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()) continueif 'dreamhack.io' != host: if '.' in host: cs.sendall('cant use .\n'.encode()) continueThe 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), orfile://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> file://:1/app/flag.txtresult: DH{5e2c73de0f2b273731665914bfaff022}🚩 FLAG: DH{5e2c73de0f2b273731665914bfaff022}