Writeup by r2uwu2
I wrote my own HTTP server. I have to admit: the code is a bit cursed, but it works! So no problem, right?
Looking at the first request to the server,
It's bash 💀.
There is url http://chal-kalmarc.tf:8080/assets/26c3f25922f71af3372ac65a75cd3b11/iceberg.jpg on the page to request an image, let us try an LFI.
We can lfi now. Let us try to get the application source code.
Some more info is revealed on error:
We know that the application has an /app
folder and a /static/assets
in it.
I was trying to read /proc/self/status
but would receive an empty string. To look into this further, I tried sending a raw HTTP request with nc
.
The above command returned me the /proc/meminfo
yay.
With this truly arbitrary read, I decided to try leaking the cmdline
and environ
of some of the initial PID
. I found that PID=1
was socat
and from the cmdline
, I found that the path to the server is /app/badass_server.sh
.
From here, I was fairly stumped. I had to figure out a way to get the flag. However, I don't even know where the flag is, so I might need RCE.
Looking through the source code for badass_server.sh
, it's fairly hard to see anything wrong with the code.
I can't sneak in a command injection anywhere to get RCE as everything is properly quoted. Or is it?
Looking at line 62, we have [ $protocol != 'HTTP/1.0' ] && [ $protocol != 'HTTP/1.1' ]
. Since $protocol
is not quoted and [
is simply an executable /usr/bin/[
, $protocol
will expand as a glob. We can use this to perform nefarious deeds.
Playing around with various globs, I found that when the glob matches two files, it causes a space in the expansion which bypasses the protocol check (try using *
as the protocol). When I was trying to build up a prefix using a glob to find the flag file path, I found that the following glob bypasses the protocol check:
(echo 'GET /assets/26c3f25922f71af3372ac65a75cd3b11/../../../../etc/passwd [bs][at][ad][at][is]*[ch]'; echo; echo; sleep 1) | nc chal-kalmarc.tf 8080; echo
It may seem very weird that each character only has two possible characters. Looking at it closer, it indicates that there exists a badass.sh
and a static
in the same directory as the glob is an interleaving of the two. We can use this to leak file paths as long as we know a file path in the directory.
I first thought that the flag was in /
, but after a lot of trial and error, I was not able to find anything. I then looked at the inspect element for the website.
There seem to be multiple folders in assets/
, perhaps there is a folder with our flag.
With a manual test, I confirmed that there was a folder starting with 9
in assets/
. I then decided to write a script to do this (I was doing this all by hand previously).
It slowly built up to the full hex:
I then tried visiting flag.txt
in the folder and found the flag: