Problem
Because reversing an obfuscated jit’ed virtual machine for 3 points is fun!
(re 3, solved by 38)
Solution
I downloaded it immediately when it was released and solved it really fast, but it turned out they uploaded the wrong binary. After a while they uploaded the proper binary and the fun could begin.
The binary takes the flag as argv[1]: ./c3803116bd70e802483d3bc4c4b564d2 BKPCTF{flag...}
.
We’re provided with a binary with a strange loop and a call to a function pointer. Looks too weird to understand, so I gave up static analysis quickly.
The way I solved the easy binary was to just put a breakpoint in write
because it prints Nope.
when you enter the wrong flag. When the breakpoint hits, I scanned the memory for strings and could quickly find the BKPCTF flag because of the format.
But the new binary wasn’t that easy. They encrypted the flag.
I put a breakpoint in write
again, but this time I made a core dump at this point by invoking generate-core-file
from GDB.
Then I loaded the core dump in a proper reverse engineering tool and could start analyzing it.
From GDB I already knew the address of the code that invoked write, but it turns out that this was coming from the libc flush. The backtrace wasn’t interesting. I want to know who generated the text. After setting a couple of hardware write breakpoints using watch
I tracked down the code that actually generates the output. I then continued the core dump analysis in this location.
After scanning though the assembly, I could see where the encrypted flag is put into the stack.
Encrypted flag: [FMTEPB}U3`_YEl0jj_hYcpp0emuYcv_Yu4Y355<w]
I then tracked down where argv[1] is accessed and could find the comparing algorithm. It is basically doing the following:
for i in len(userflag):
if (chr(userflag[i]) ^ 0x05) - 1 != flag[i]:
return 2
return 1
So I wrote a python one-liner that decrypts the flag:
s = "FMTEPB}U3`_YEl0jj_hYcpp0emuYcv_Yu4Y355<w"
''.join([chr((ord(c) + 1) ^ 0x5) for c in s])
This in turn reveals the flag: BKPCTF{S1de_Ch4nnel_att4cks_are_s0_1338}.
The flag of the easy binary was BKPCTF{S1de_Ch4nnel_att4cks_are_3asier_than_st4tic_analySis}
for the record.