CSAW Quals 2016 – “mfw” challenge write-up (Web)

I attended the online ctf CSAW with my university team PolyHack. The challenge’s portal did not give a lot of informations, most importantly that it was a Web challenge.

Let’s dig in. We are presented a standard website with a few pages.

Seeing the URL and the GET parameter “page”, I tested for LFI. For this classic payload, we were provided with an error message displaying Hacking Detected.

http://web.chal.csaw.io:8000/?page=../../../etc/passwd

All right, so there is some sort of validation on this parameter and we could try to bypass it, but before that I wanted to look at other possible exploitation points.

Inspecting the HTTP requests and responses with a Web proxy such as Burp suite, I was able to see a HTML commentary about the page for the flag.

Let’s go see that page. I cannot believe that this challenge would have been this easy.

And it was not. There were no commentary or hidden field relevant for us. We have to go down another road. I scanned the website with Tachyon, a Web discovery scanner. It found pretty interesting artefacts, which was a git repository. We could have gotten there directly from the first step since the homepage tells us the website uses git.

In the always useful library of tools called GitTools, I used gitdumper which downloads the remote git repository.

We now have access to the repository and we can dig through it. I was able to see the messages of the previous commit, get information about the uses of PHP, and revert the content of the repository to this commit.

Great, we now have the source code the website at a certain previous time. I looked into templates/flag.php.

Of course! But it would have been a pretty easy challenge since we have not done any web exploitation to this point. I looked the other files and index.php was the only one containing interesting informations. By looking at the content of the file, we see that the flag is written as a commentary PHP, which does not render on the client side. Viewing flag.php without interpreting the PHP should be the challenge.

Essentially, there are two filters, one to prevent LFI by preventing “..” and another one checking if the file exists. We have found the vulnerability. In PHP, the “assert()” function interprets its parameter as PHP code, before validating the assertion. We have an unfiltered parameter in this function so we can play with it. If we can make execute the PHP function “system()” with the instructions to display the inside of flag.php.

After a few trial and error, we found a working payload for the page parameter:

about.php', 'bogus') === false and system('cat templates/flag.php') and strpos('templates/flag
Inserted in the second assert, this line should be interpreted:
assert("strpos('about.php', 'bogus') === false and system('cat templates/flag.php') and strpos('templates/flag', '..'") === false") or die("Detected hacking attempt");

By URL encoding the payload, the payload does not make crash the application and it gives us the flag.

 

Posted in

Comments are closed, but trackbacks and pingbacks are open.