[CTF Write-up] nn8ed HackGym challenge write-up.
This weekend, Navaja Negra 8 CTF started, organized by ka0labs.org. This pwn challenge has the following statement:
Say the magic word to get the flag!
http://hackgym.ka0labs.org
The provided website is a phpinfo() output from the server, but with a string at the beginning.
As you can see, ka0labs team is formed by dick-painter teenagers. Ok let’s see what’s in the PHP Information. Scrolling down a bit, we can see an extension HackGym
is loaded.
At this point, a hint is released: Look at the HTML source code. And there it is, there’s a comment at the bottom of the HTML leaking a backup path for the loaded extension.
Well, let’s download the shared object and open it using IDA and see what funcions we have:
If you have some PHP extensions background, you can easily identify what this functions are. For those newbies on PHP internals, there are a few functions PHP use when loading extensions, you can read more about this, from an offensive perspective in: https://www.tarlogic.com/en/blog/backdoors-php-extensions/
TL;DR: PHP_FUNCTION macro is where extension functions are defined.
So let’s analyze the PHP_FUNCION function, which really should be a PHP_FUNCTION
macro, but for readability reasons, it’s badly written on purpose.
Ok lot of stuff, the interesting part is here
This function is taking the X-Forwarded-For HTTP header, and passing it to kaboom
function, so let’s see what this function does:
In the first basic block, this function is taking our input, which is 256 bytes long, and writing it to a variable, there’s is another 256 bytes buffer containing the 8=====> ! JE! Target! 3%
string. The next basic block, overwrites our buffer with this dick string.
On the third basic block, _ap_php_snprintf
, a wrapper in PHP for snprintf
function is called passing our overwritten buffer as argument. There’s more, the string of the placeholder will be nn8ed{...}
. But wait, what placeholder string?
snprintf
function works like this, you specify a string which is kind of a template string, and inside this template, you can specify placeholders which are going to be replaced based on what you indicate. For example:
char destination[256];
char * name = "Gonzalo";
snprintf(destination,256,"Hi my name is %s", name);
Will write the destination
variable with "Hi my name is Gonzalo"
string. Ok, do you remember that the replace string ended with a %
? Din din din! We need to force the final string to end up in “s”, so the template string passed to snprintf
will be 8=====> ! JE! Target! 3%s
and the flag is going to be replaced as %s
so the placeholder is replaced as seen in the example.
Let’s test:
GET / HTTP/1.0
Host: hackgym.ka0labs.org
X-Forwarded-For: XXXXXXXXXXXXXXXXXXXXXXXs
200 OK
8===D ! JE! Target! 3nn8ed{Th3_r1ght_f0rm4t_Off_by_1}
Win! The flag is returned at the beginning of the HTML as expected.
This challenge was easy for those people who know about format string bugs and PHP extensions, for those not so used to work with exploiting challenges or PHP extensions, is a great challenge to know some basics about it.
Congratz to ka0labs.org team and Navaja Negra.
See you!