UMDCTF 2020: Evil Santa's Mysterious Box of Treats
Patching and Instruction counting towards first blood.
Here we are given a 64bit ELF executable and we're tasked with finding the flag.
Running the binary:
Running the binary reveals that it is looking for input on STDIN. When you pass in an invalid flag it responds with "You are getting coal for the next five years!"
Running strings
on the binary reveals the first clue: with this much symbol data available it's possible that the binary is statically linked and will make debugging and static analysis difficult.
We can confirm this suspicion by parsing the binary and reading symbols through running readelf -s EvilSantasBox.back
. Without symbols this makes instrumenting this binary through and LD_PRELOAD tricks impossible. So our next step is opening it up in ghidra.
Ghidra reveals a massive listing of functions in the it's function table further confirming static compilation.
Following the entry function I discovered that main
was the function defined at 0x004005c0
. Scrolling down through the decompilation reveals a couple additional pieces:
* Function at 0x411360 prints to screen * Function at 0x410680 collects user input * The user input is likely 0x28 (40) characters long * The success string of the binary is printing "You received a present from santa this year!"
The next step is setting up a debugger and then stepping through the binary after collecting some random input, however the challenge posses some anti-debugging logic as seen below:
To identify where the syscall is made I used some QEMU usermode emulation through qemu-x86_64
to provide tracing information on the syscall. Using the command qemu-x86_64 -d in_asm ./EvilSantasBox.back 2>&1 | grep syscall
Qemu will output all the instructions it executes with the addresses associated with those instructions as seen below.
The function above will return the status code of the ptrace call, so looking at the function xrefs we can identify where this call is being made. The function at 0x4012a0
will call this function and return either a 0 or a 1 and print out the previous error message we saw before. By patching out the check and always returning a 0 we can avoid being detected!
Instruction stomp starting creating some weird looking input, so I immediately thought that there might be some non-deterministic instructions being executed. Looking back through the strace
reveals that there is a syscall made to get the current time. Using the same qemu-x86_64 -d in_asm
trick from earlier I was able to find where this syscall was made and patch it out.
Firing Instruction Stomp off again reveals the flag after a minute or two. The flag appears to be base64 encoded, so base64 decoding reveals the final flag. By using instruction counting instead of dumping each value out of a debugger I was able to quickly snatch a first blood with this problem.
Last updated
Was this helpful?