UPDATE 20160114: The links to the ESET ChallengeMe 2013 sample are now outdated. I have attached the samples to this post and you can get them here: Crackmes. Password: eset. Enjoy!
I was introduced to ESET’s ChallengeMe 2013 by Yashar Mahmoudnia, a member of the Reverse Engineering Malware Research group on LinkedIn. You can download the challenge here. Before reading the solution, I wanted to try my hand at the challenge and brush up on my skills. Then I can compare my results to see how I did. I am half-way through the challenge and here is what I have learned so far.
Step one: Triage analysis
When you first run the program you get:
When you hit enter it quits. Next, I ran the sample through a strings program:
Not very many human readable strings. Looks like a bunch of garbage. This is an indication of packing or encryption. I used a tool called PEiD to try to identify the packer. At first under normal scan, PEiD said it found nothing. So I tried the deepscan:
Packed with UPX.
step two: unpacking
We could try the program upx -d to unpack, however, I am going to unpack it by hand. I am going to use OllyDbg to load the program, step (F7) past the PUSHAD (you may want to make sure you have the anti-debug plugins installed to hide the debugger in case the sample uses anti-debugging techniques) instruction and then set a hardware breakpoint on the ESP register on access. Then run the program (F9) and when the breakpoint is hit, you should be close to the POPAD instruction. Close by should be the programs Original Entry Point (OEP):
We just paused after the POPAD and a few lines down we see a really far, unconditional jump from our present location at 0x4122E6 to 0x40463C. That is our OEP. Set the cursor to that JMP instruction and hit F4 to run to position. Then hit F7 to make the jump to the OEP and voila — this looks like source code:
Leave the program paused here for now. This won’t run as is. We have to first rebuild the imports with ImportRec. We will need the Relative Virtual Address (RVA): in our OEP address of 0x40463C that is the 463C part. Next, we need the RVA of the import table. In Olly, scroll down until you see something that looks like:
The table starts at address 0x40C074 and if you keep scrolling down to the end of the table, you will find that it ends at 0x40C150. The RVA of the table is C074 and if we subtract that from the C150 we get the size of the table: 0xDC (220 bytes). This is all the information we will need to use ImportRec.
Attach to the running process with ImportRec, the right click the big middle, white box and go to “Advanced Commands”, then “Select Code Sections”, and accept the defaults. Now press the full dump button to dump the process from memory. Click “Ok” to close the dialog boxes.
In ImportRec’s “IAT Infos needed” section type the 463C in the OEP box, C074 in the RVA box, and DC in the size box. Click on the “IAT Autosearch” button. If we did this right, it should find something:
Click OK, then click Get Imports. The big middle white box should have no errors. Next click on the Fix Dump button and click on the dump file that ImportRec created for us earlier. ImportRec will create a esetcrackme2013_dump_.exe file. You should be able to run that file and it should work just like the original packed sample, displaying the same start up message, and exiting when you hit the enter key.
Now we should be able to examine the binary’s strings to get a first impression of what this program might do:
I see some Windows Registry key strings HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run, and HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess. This sample may set these keys to persist between power cycles. There are strings to URLMON.DLL functions that check an Internet connection and to download a file. I see an URL to http://www.eicar.org, so this thing may be trying to download an eicar.com file. Also note the long string sequence highlighted in the string snapshot above. That looks like the string sequence used to leverage an old OllyDbg vulnerability. I see other possible anti-debugging strings such as GetTickCount, and IsDeguggerPresent.
Upon first impression, it looks like this program might be some sort of downloader or dropper, but the only way to know for sure is to attempt to debug it. See if we can coax the thing to continue even after we hit the enter key in order to observe what its true intent is. I will write up those results and post them in a few days.
EDIT TO ADD 20140109: Yashar posted his teammate’s write up of the solution.
EDIT TO CORRECT 20140109: Corrected the spelling of Yashar’s name.