187 words
1 minute
DreamHack - [web-HTTP-CLI challenge writeup]

The program receives a URL and the server sends request to the URL.

Since the URL is sent by the server, it could lead to Server-Side Request Forgery (SSRF) or Local File Inclusion (LFI).

Don’t bind the URL with http always, there are many more schemes. In this problem, flag is located at /app/flag.txt, and we have a URI scheme file:// to read file.

So now we just need to bypass the url checking condition.

def get_host_port(url):
return url.split('://')[1].split('/')[0].lower().split(':')
(host, port) = get_host_port(url)
if 'localhost' == host:
cs.sendall('cant use localhost\n'.encode())
continue
if 'dreamhack.io' != host:
if '.' in host:
cs.sendall('cant use .\n'.encode())
continue

The get_host_port() gets the host and port of the URL by taking the second element after splitting ://, then takes the first element after splitting /, and finally splits by :.

After reading on wikipedia about valid URL scheme, wikipedia, it indicates this.

A valid file URI must therefore begin with either file:/path (no hostname), file:///path (empty hostname), or file://hostname/path.

Choosing the “no hostname” way to go is fine. Since it still splits by : at the end, we can just add an arbitrary port.

The payload is.

file://:1/app/flag.txt
Terminal window
> file://:1/app/flag.txt
result: DH{5e2c73de0f2b273731665914bfaff022}

🚩 FLAG: DH{5e2c73de0f2b273731665914bfaff022}

DreamHack - [web-HTTP-CLI challenge writeup]
https://minhi1.github.io/minhi1-blogs/posts/dreamhack/level-4/web-http-cli/
Author
Minhi1
Published at
2025-12-25
License
CC BY-NC-SA 4.0