Trend Micro CTF was this weekend. This is the first one of these Trend Micro CTF I've done and I was expecting it to be really well run and fun.
I was pretty surprised to see the real situation though. I felt the difficulty scaling was all over the place and just too many guessing games. Also a lack of communication with no official IRC channel and only a couple of tweets from Trend throughout the day.
Anyway, I still am determined to document at least one solution per CTF so here's the one I decided because I liked the idea.
This is in the Analysis-Defensive category, which is essentialy the same as any other CTF's Reverse Engineering category. We are given a ZIP file containing a single file called "vonn":
Which is a 64 bit ELF binary that is not stripped. Neat.
When we execute it we just get the string
(Oh the program deletes itself also, just a tip, make a backup of it first)
Which doesn't say a lot but is a good clue. Trend Micro being a company related to AV has probably dealt with VM aware threats quite a lot. So perhaps this program uses a trick to determine if it's on a VM and behaves a certain way because of it.
Let's look in IDA Pro:
Yep sure enough, if you are not on a VM then just print a message, but if you ARE on a VM then run the ldex() function passing a pointer to argv, the command line arguments.
The ldex() function seems to be where all the magic happens:
All this is doing is opening a new file in the /tmp/ path called "...,,,...,,", decrypting a payload into that file, executing it, then cleaning up by deleting itself.
First thing we need to do is grab the payload. Since there's no file in /tmp/ after we execute this from the command line, I assume that the payload is also deleting itself.
Instead, we run "vonn" inside a debugger and set a breakpoint on the execv() call...
Great. I make a copy of the payload and let's analyse this in IDA Pro:
Ok this is looking familiar no? This is the same main function as the dropper ("vonn") except there are no printf() messages and the non-VM function looks to be doing the work this time.
So the solution becomes clear at this point. The challenge is a two part binary. A dropper and an encrypted payload. When run on a VM the dropper will decrypt the payload, however the payload will only perform it's duties on a non-VM system.
To get the flag we only need to run the payload on a bare metal system.
Unfortunately I don't have that ready to hand, so I resort to patching the payload. In the graph view I identify an easy "JZ" instruction I can flip to a "JMP" instruction to take our desired execution path:
This JZ lives at address 0x400a33 in memory so let's use pwntools to patch that to a JMP and execute the patched version:
Which we combine with GDB to get us the flag like so:
Not too bad. A good 100 point challenge IMHO.