DEV Community

Edqe14
Edqe14

Posted on

TCP1P CTF — Nuclei

Challenge Preview

In this challenge, we are presented with a rather simple web page.

Page preview

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.

dist.zip files

In the custom-template.yaml file, we can find interesting metadata, and HTTP requests..? We'll get into it further later.

custom-template.yaml

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.

Validation code snippet

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 ✨.

Command snippet

⚛ 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.

Nuclei template introduction

🛠 Crafting the server

Let's first list the things we need to do.

  1. 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)
Enter fullscreen mode Exit fullscreen mode
  1. Response

    1. In the /version endpoint, we need to respond with:

      • version that needs to be under or equal to 10.0.5 but later than 10.0.1
      • Exact words that matches "NAME":"TCP1P" and "msg":"success"

      First request matcher

    2. 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.

      Second request matcher

    3. Lastly, every request must respond with code 200.

    Status 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');
});
Enter fullscreen mode Exit fullscreen mode

Server running

🩸 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.

ngrok

Just like that, submitting the URL... and we got the flag ✨!

Flag!!

Feedback are appreciated!

Top comments (0)