Writeup: Secuinside CTF 2013 - Secure Web
binary: http://war.secuinside.com/files/mod_dontwebhack.so
http://59.9.131.155:8181/
Bad, we’ve got hacked and destroyed by the evil.
So, the government distributes a web-hacking-defense module to people.
You can check it out if there is any problem inside. Please!
This challenge could have been quite interesting but I think organizer must have miss something.
They completely ignored that .pth/.phtml
files may be interpretated as PHP script too.
This challenge could have been resolved simply uploading a file like the one publicated in this Tweet by FluxFingers.
Not every .pht/.phtml
file could work for this challenge.
The module attached to the challenge must apply some filters.
Let’s examine why FluxFingers’ one worked:
1 | <script type="text/javascript" language="pHp"></script> |
First thing to do is run strings on the module:
1 | $ strings mod_dontwebhack.so |
This command reveal an interesting keyword blacklist:passthru, fpassthru, system, execl, open, popen, escapeshellcmd, eval, proc_open, get_contents
.
As you can see print and assert doesn’t appear in the list, this explain why FluxFingers’ choose them and let us getting closer in understanding how their exploit work.
Another key shrewdness is the uppercase H
in language attribute on script tag.
Further exploration in module (explained later in this post) revealed a filter on the lowercase php
string, that letter is needed to bypass the
check.
Here we are, FluxFinger’ exploit behaviour should be now clear.
To get it work we need to pass php shell-code as c argument in GET request.
But where can I find my uploaded file? The upload script source code was public and upload dir was:
1 | "/var/www/uploads/" . md5($_SERVER['REMOTE_ADDR']) . "/" |
We need to calculate md5sum of 59.9.131.155:8181
so:
1 | $ echo -n "59.9.131.155:8181" | md5sum |
So we need to go to:
http://59.9.131.155:8181/uploads/c8270a1a28591f621d4874acf133227a/ourUploadedFile.php
The flag was in /home/dwh/flags
Well, I started this post arguing this challenge could have been quite interesting so let’s assume .pht/.phtml
files are not applicable in this
case and analyse together how to get a .php
file interpreted on the server.
To do this we need to go deeper and give a closer look to the module, it’s IDA time!
Opening module with IDA we can see two very interesting functions, called check_php_bad_string
and dontwehack_input_filter
:
Lets see what this functions contain (with HexRay Decompiler FTW!):
dontwebhack_input_filter
:check_bad_php_string
:
I spent some time looking at check_php_bad_string()
to find some vulnerability with no success, so I looked then in dontwebhack_input_filter
.
Here I found the check for lowercase php
string, and after that we find the vulnerability we need to upload our scripts.
Module search for filename
attribute in POST data, and only if it find it run the check_bad_php_string
, we simply need to change its case to avoid check_bad_php_string
!
Moreover the check for php
only sets a flag instead of interrupt immediately the execution to return the error so, changing filename
case, we bypass that check too!
Understood this we only need to craft our request the way we prefer.
One way to do this is intercept Firefox’s request with TamperData plugin.
Just select your php shell to upload and before click the submit button open TamperData (Tools->Edit with TamperData
) and then click Start capture
.
After the click a pop-up should appear to notify the capture of the request and to make you chose if you want to edit the request, just press Tamper
.
A window should now appear, on the right column you will see POST data and you should be able to manually edit it.
Change filename to FILENAME and execute the request.
You will now see the Success page
and should be able to run your script.