Hack.lu CTF - Secure Safehouse and Safehouse
Hack.lu CTF Secure Safehouse and Safehouse challenges
For these challenges an ssh login was provided. On the server we could find the +s binaries "safehouse" and "secure-safehouse" and a "FLAG" file, respectively. Both challengesalmost worked the same way. Interpreting the command line arguments as unsigned long integers, they copied the resulting code to a RWE-memory region in memory. However, every third byte would be replaced with "c3", which in itself is "retn". Then the binary would jump to these regions. "Safehouse" will jump to every of the at max. 5 provided long ints, while "Secure Safehouse" would just jump once, to the first. After that, both would execute a shell - which just had not enough privileges. The goal was to call the kernel to set the uid of the process to the uid of a privileged user, which could read the flag. For "Safehouse" this is easier, since we got up to 15 bytes of shellcode, but only up to 3 byte opcodes. Still it can be done by adjusting first ebx to 1006 (the uid of the user safehouse) and al to 23, the syscall number for setuid, followed by a kernel call. ebx was initially set to 4096, so in two opcodes (shr ebx, 2 and sub ebx, 18) we are done. mov al, 0x17, finished by an int 0x80 wins the challenge. We do not need the last 3 bytes, thefore setting them to nops.
1 2 3 4 5
./safehouse 2416110529 2417159043 2425362352 2425389261 2425393296 $ whoami safehouse $ cat FLAG FUNNY_C3_LOOP_MAKES_ZOMBIES_BUTTHURT
"Secure Safehouse" was way more challenging. As already mentioned, it would just jump to our first 3 bytes and when it returns execute a challenge. This only happens, when rax contains the number of command line arguments. This makes things more difficult, because we need the register for syscalls.
First we needed code, which uses "c3", so we have more bytes to play with. After a painfully long time fiddling, we found xchg eax, ebx to be exactly what we needed.
Another thing to mention is, that the value of rdx is the same as the last command line argument, which is an easy way to provide, say the user id of secure-safehouse,
which is 1005. This would of course leave us with only 16 bytes, where every third byte is "c3". Long story short, the solution is to:
1 2 3 4 5 6 7 8 9
xchg rax, rdx xchg eax, ebx xchg rax, rcx test bl, al mov al, 0x17 test bl, al int 0x80 xchg eax, edx retn
1 2 3 4 5
./secure-safehouse 3280441928 3280245064 3280213936 3281158349 1005 $ whoami secure_safehouse $ cat FLAG JOO_ARE_NOW_SUPER_LEET_C3_HECKER