Tags
ESET ChallengeME 2013, ESET CrackMe 2013 Challenge, Malware Analysis, Malware Reverse Engineering
my continuing adventures in reversing the eset 2013 crackme challenge…
In my last post, we found all the Easter eggs and set off looking for the solution to unlock this puzzle. This is a challenge from an anti-malware company, so there should a “malicious-like” component to this puzzle and started examining other threads that were spawned before the WinMain function that displays the textboxes began. We did find an interesting path, a path that led us to the process injection of Window’s userinit.exe. That was our “malicious-like” behavior and when we traced the code to the CreateRemoteThread call:
And stepped over that call (F8), we could observe our CrackMe code launching the newly injected userinit process:
Unfortunately, the process goes immediately into a suspended state, which prevents OllyDbg from attaching to it. After several failed attempts of trying to find a solution, I posed the question to the community for some help. My thanks to the many members Reverse Engineering and Malware Group on LinkedIn for their suggestions. The solution that worked was submitted by Mr. Mahmoudnia — he found another person’s solution to this ESET challenge. The solution is rather clever. Before we hit the second call to WriteProcessMemory:
Which is going to write the code at location 0x403E70 into userinit’s process space at 0xA0000. We want to go to 0x403E70 and change the function prologue from “PUSH EBP” and “MOV EBP, ESP” to the opcode “EB FE”:
In Olly, right-click on the “PUSH EBP” instruction, select binary, then edit and uncheck the “keep size” box; now you can change the opcode to the value “EB FE”:
The opcode “EB FE” creates an infinite jump to the start of this function, i.e. to address 0x403E70. Now we can step over the “WriteProcessMemoryCall” and proceed to step to the “CreateRemoteThread” call. Now hit F8 to step over CreateRemoteThread and stay at location 0x4063B6:
Next, open a second OllyDbg instance, go to File -> Attach and scroll down the list of process until you find userinit.exe and click the “Attach” button:
Once attached and in the CPU window hit CTL-G and go to address 0xA0000 and change the “EB FE” back to the “PUSH EBP” and “MOV EBP, ESP” function prologue and set a break point. This may take several attempts. What consistently worked for me was to go to the theads window (the blue T button) and check to see if my thread was suspended. If it was, I right clicked on the thread and selected “Resume”, then I hit F9 (Run). If the RE gods are smiling upon us, we will hit the BP:
To see what the above routine does, I am going to single-step through this code line-by-line:
A little ways down, there is a call to a function at 0xA02F0. I stepped inside that function and determined that this was some kind of key generation function. Observe that ESI was set to the ASCII string “472631FB”. Continuing on:
In the above chunk of code, we are making a call to a function in wininet.dll, I used DLL Export Viewer to resolve the symbol name. This is setting up a http network connection to localhost on port (highlighted as 0x1F90 in the stack window) 8080. In my last post, we observed a wget POST call posting an index.php. Continuing on, we can observe that this section of code is setting up all the parameters for an HttpOpenRequest call:
Again, I fired up FakeNet and stepped over the call:
The wget POST with index.php is supposed to receive data but as you can clearly see, we don’t because EAX is set to 0. The next instruction will test EAX and since it is 0, we will jump all the way down to 0xA0296. At that location, there is code to terminate our thread. I don’t want to end just yet. There is an awful lot of code real estate that we are skipping and I want to see what it does. So, I changed EAX from 0 to 1 so that the JE instruction is NOT taken in order to see what happens next:
In the above screen shot, we can see that what ever we were supposed to receive from our first wget POST is supposed to decrypt to the value of “Jules” — one of the main character’s (played by Samuel L. Jackson) in the movie “Pulp Fiction”. So our Pulp Fiction theme continues. Since we did not receive any data, the zero flag is not set and we make that long jump to 0xA0296 again. So I set the ZF to 1 so the JNZ instruction is not taken. Continuing on:
The code continues to set up a second HttpOpenRequest call. This time instead of passing just index.php as one of the parameters, I thought I would change it to “index.php?key=280877F8” This was the key that was generated in our first wget POST call. I don’t know why I thought to try this, I was just curious and assumed that since we were getting a key, that there would be a second decryption routine. Maybe I could coax the code to decrypted what ever is going to happen next…
So we make the second wget POST call and and continue on to what I believe to be is a decryption routine…
Interesting! We did get a message: “That’s all. Congratulations!” We must be getting close to solving this thing. So if we continue to single-step our way through this routine, eventually we wend our way to a USER32.MessageBox call:
Let’s step over that call and see what message we get…
W00t w00t — we did it!
This was a very fun RE challenge. My thanks to ESET for creating such a fun puzzle and a special thanks to Mr. Mahmoudnia and others in the Reverse Engineering and Malware Research group on LinkedIn for their help and suggestions during the times I got stuck. I learned some new tricks like that “EB FE” trick to attach to a suspended process. I’ll have to remember that one if I ever encounter such a sneaky maneuver by malware in the future.