Fireeye has published the full write-up from the authors of the challenges, and at the time I wrote this, there is already one complete write-up (this) and I think many more will come. So instead of doing another full write-up, I will just write down things that I did differently and/or different tools that I used to solve the challenges.
You can also use command line
tr to use alternate base64 characters
echo x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q| tr ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/ ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/|base64 -d
Same as most people: I just patched the executable to let it do the decryption
Same as others: copy the memory after it is decrypted and do a bruteforce on it.
I wrote a python script to find the longest call chain and call in that order.
I didn’t know that the decryption result supposed to be an executable that calls the
beep() (“The decrypted data is a simple executable that makes a series of calls to the Beep API. “) . What I did find was just the string
usetheforceluke!, and I searched the web for star wars theme song. And this one fits perfectly. I guess I was just very lucky.
Instead of creating a disassembler, I reimplemented the emulator (if it had been a Linux binary, I would have tried WCC), and Identify the comparison points.
Initially I just manually try to find the requested values, but then I got bored and I just brute force every character and see if it would reach the next comparison point.
I did it like everyone else.
This is the first time I reversed a Go binary. I learned a lot by looking at the source code of gofrontend (especially the libgo part).
I realized immediately that this is a DOS Code (from the name: Chiemera). I used Dosbox with heavy debugger (this forum post helps a lot).
The first two levels can easily be solved using NoFuserEx and any .NET decompiler (I used ilspy).
I was not able to fix the third level with NoFuserEx, so I used reflection to load the third layer, then disassemble the instructions (using
method.GetInstructions()). The pattern of the problem is the same as the first two layers, so I just need to find a reference to a field in StringUtils and find the reverse of the MD5.
For the first part of the flash, I used JPEX open source flash decompiler. There a button to deobfuscate an SWF and that helped a lot.
Throughout the flash challenge, I didn’t use any native debugger , so I didn’t use both solution in “Searching Memory” in the official writeup page 26. Instead I used RABCDasm to disassemble and reassemble the ABC (actionscript byte code).
I created a new class to post data to a local URL, compiled the class, extract the byte code and copy it to the target.
amxmlc url.as abcexport url.swf rm -rf url-0 rabcdasm url-0.abc cp url-0/*asm target-0
On top of the
#include "url.script.asasm"getlex QName(PackageNamespace(""), "url") pushbyte 1 callpropvoid QName(PackageNamespace(""), "testSendNumber"),1
Another example to send a byte array:
dup #duplicate stack getlex QName(PackageNamespace(""), "url") swap #swap stack to correct the order callpropvoid QName(PackageNamespace(""), "testSendBA"),1
On the last part, after we get the last .SWF, JPEXS is too slow to decompile the method. To solve this, I used RABCDasm again and use a simple python script to remove junk codes from the bytecode, rebuild the SWF then decompiled it with JPEXS.
I was a bit disappointed on this last challenge because I think it requires a bit guessing on the Imgur URL. I found the URL immediately, but I didn’t realize that it was important (I thought it was just an easter egg) until I saw the *size* of the image.
This year’s challenge was much harder than last year, I had much fun and I learned a lot from solving the challenges.