In this challenge, we are presented with a rather simple web page.
Here, we can input a valid URL only as it will validate the input. Since there is not much exciting stuff on the website, let's dive into the source code provided.
⛏ Source digging
In the zip archive, we can find docker-related files, custom-template.yaml
file, and also app.py
which is a flask application.
In the custom-template.yaml
file, we can find interesting metadata, and HTTP requests..? We'll get into it further later.
On the other side, we can find the source code! app.py
. Inside, we can find the corresponding file that handles the /submit
route. We can also find the validation code for the URL input.
Following that, we can also find a command snippet that will run a process that uses our input, and by getting the desired output, we can get the flag ✨.
⚛ Nuclei
By doing a short Google search, Nuclei is:
a fast scanner used to scan modern applications, infrastructure, cloud environments, and networks to help you find and remediate vulnerabilities. (source)
Now, we also know that custom-template.yaml
is for nuclei to use. We can find the templating guide in the official nuclei templating guide documentation. From the custom template, URL input, and source code, we can safely assume that we need to craft an HTTP server that fulfills the template requirements.
🛠 Crafting the server
Let's first list the things we need to do.
-
Routes
We need to create 2 endpoints that are written in the template.yaml file:
- `/api/v1/version`
- `/api/v2/echo`
![HTTP endpoints](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s5kz0t3f7z4c9m8uokhd.png)
-
Response
-
In the
/version
endpoint, we need to respond with:-
version
that needs to be under or equal to10.0.5
but later than10.0.1
- Exact words that matches
"NAME":"TCP1P"
and"msg":"success"
-
-
As for the
/echo
endpoint, we have a more complex requirement:- the body need to match
TCP1P{[a-z]}
regex, - contains the string
<script>alert(1)</script>
, - and responds with status code 200.
- the body need to match
Lastly, every request must respond with code 200.
-
Now, we can actually make the server that will definitely give us the flag! For this example, I'll use Express and Node.
import express from 'express';
const app = express();
app.get('/api/v1/version', (req, res) => {
res
.json({
"NAME": "TCP1P",
"msg": "success",
"version": "10.0.4"
});
});
app.get('/api/v2/echo', (req, res) => {
res
.send("TCP1P{a} <script>alert(1)</script>");
});
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
🩸 Execution
To allow nuclei from the challenge to access our server, we can use a tunnel service like ngrok to give us a public URL.
Just like that, submitting the URL... and we got the flag ✨!
Feedback are appreciated!
Top comments (0)