|< Day Day Up >|
Before beginning your practical journey, there is one final issue to note. Similar to software debugging, reverse engineering by definition goes in reverse . In other words, you must be able to think backward. Zen meditation skills will serve you better than many years of formal programming education. If you are good at solving verbal brain-teaser riddles on long trips with friends , you will probably be good at RCE. In fact, master reversers like +Fravia recommend cracking while intoxicated with a mixture of strong alcoholic beverages. While for health reasons we cannot recommend this method, you may find that a relaxing cup of hot tea unwinds your mind and allows you to think in reverse. The following segments walk you through live examples of Windows reverse engineering.
2.3.1 Example 1: A Sample Crackme
Example 1 is Muad'Dib's Crackme #1.
This is a simple program, with a twist. The program's only function is to keep you from closing it. For example, when you run the program you will see an Exit button. However, pressing the Exit button does not work (on purpose). Instead, it presents you with a nag screen that says, "Your job is to make me work as an exit button" (Figure 2-12).
Figure 2-12. Solving Muad'Dib's crackme
Thus, the crackme emulates shareware or software that has features removed or restricted to the user (i.e., crippleware ). Your job is to enable the program in order to make it fully functional. Fortunately, the program itself gives you a great clue. By searching the disassembled program for the following string:
"Your job is to make me work as an exit button"
you will probably be able to trace back to find the jump in the program that leads to functionality ”i.e., a working Exit button.
Once you have installed IDA Pro, open your target (in our case, Muad'Dib's Crackme #1) and wait for it to disassemble. You will be looking at the bare, naked ASM. Go straight for the protection by searching the convenient list of strings that IDA Pro has extracted (Figure 2-13).
Figure 2-13. String disassembly in IDA Pro
Double-clicking on our target string takes us directly to the target code in the disassembly (Figure 2-14).
Figure 2-14. Using strings to find target code in the disassembly
We arrive at this code:
* Reference To: KERNEL32.ExitProcess, Ord:0075h :00401024 E843000000 Call 0040106C ;( ThisCalls ExitProcess when we click on theWindows Exit Cross) :00401029 55 push ebp :0040102A 8BEC mov ebp, esp :0040102C 817D0C11010000 cmp dword ptr [ebp+0C], 00000111 :00401033 751F jne 00401054 :00401035 8B4510 mov eax, dword ptr [ebp+10] :00401038 6683F864 cmp ax, 0064 :0040103C 752A jne 00401068 :0040103E 6A00 push 00000000 * Possible StringData Ref from Data Obj ->"GOAL:" :00401040 682F304000 push 0040302F ; This references the text in the MessageBox * Possible StringData Ref from Data Obj ->"Your job is to make me work as an exit button!" :00401045 6800304000 push 00403000 :0040104A FF7508 push [ebp+08] ;These lines push the Caption and Handle of the MessageBox * Reference To: USER32.MessageBoxA, Ord:01BBh :0040104D E832000000 Call 00401080 :00401053 EB2A jmp 00401068
This is the call to the annoying message box that we want to bypass! We need to patch this address to jump to the Exit Process API. This is the heart of the protection.
Looking back at line 401024, we see it calls the exit process 0040106C, as follows :
* Referenced by a CALL at Address: :00401024 ;This made the call to 0040106C * Reference To: KERNEL32.ExitProcess, Ord:0075h This is the Exit Process API call that we need. :0040106C FF2504204000 jmp dword ptr 
Thus, we will patch with this jump instead. We replace the bytes at offsets 40104D and 401053 with those at offset 40106C, and when we click on the Exit button, the program will exit and the nagging message box will not appear.
The best way to patch it is to replace these lines:
:0040104D E832000000 Call 00401080 :00401053 EB2A jmp 00401068 with the following: :0040104D FF2504204000 jmp dword ptr  :00401053 90 nop
Thus, 0040104D now jumps to the ExitProcess address. The program exits appropriately when we click on either the X or the Exit button. 00401053 is extraneous, so we can just NOP it; this involves changing the JMP to a NOP (no operation).
In order to do the actual opcode patching, you need to open the program in a hex editor. After you have installed the hex editor, simply right-click the binary program in Windows and select "open with Ultra Edit." You will see the raw hex code (Figure 2-15) ready to be patched.
Figure 2-15. Hex dump of our binary
How do we find the bytes that we need to patch? Search the hex dump for a unique string of hex bytes that represents the target code. For example, to find:
:0040104D E832000000 Call 00401080 :00401053 EB2A jmp 00401068
we search for its unique hex string (Figure 2-16):
Figure 2-16. Searching for our hex code to patch
The key is to search for a hex string that is long enough that it will be unique in the application.
Once you have found the target bytes, carefully replace them to bypass the jump. Then, simply save the binary application again and run it. In our example, the program exits properly when you click the Exit button.
2.3.2 Example 2: Reversing Malicious Code
One of the most important functions of RCE is to reverse engineer malicious code such as computer viruses or Trojans. In this example, we will be reversing the notorious SubSeven Trojan by MobMan. By reverse engineering a Trojan, you can find its unique hex byte signature, its registry entries, etc., for the purposes of antivirus programs or manual extraction. However, in this case we will be reversing SubSeven in order to demonstrate its hidden secret. Interestingly, we will demonstrate why these days you can't even trust an honest Trojan writer!
At the time of this writing, you can obtain the Trojan from http://www.subseven.ws or, when that site goes down (which it undoubtedly will), by a simple web search. Credit for this discovery goes to the Defiler, and portions are reprinted with permission from +Tsehp. For this exercise, you need SoftICE installed and running.
You may choose from several versions of SubSeven, each of which will give you slightly different results. After installing the software, you configure the server portion using the accompanying EditServer program (Figure 2-17). In this exercise, we will use the localhost address for the server and configure it with port 666 and password "Peikari."
Figure 2-17. Configuring SubSeven with the EditServer program
Make sure to use an uninstall manager when installing any malware so that you will be able to manually remove it later. For this exercise, you must turn off your virus scanners , or you will be unable to work with the malware. Once the server is configured, launch the client. The disclaimer that appears (Figure 2-18) is quite ironic, as we will soon see.
Figure 2-18. The SubSeven disclaimer is filled with irony, as we will soon uncover
We point the client to localhost (127.0.0.1), as shown in Figure 2-19. Note that we will change the port from the default of 27374 to read "666" (which is how we configured our server).
Figure 2-19. Use the SubSeven client to connect to localhost
Next, open SoftICE's symbol loader to import winsock exports ( wsock32.dll ), depending on your operating system. After you load the SubSeven server in SoftICE's symbol loader, the Trojan will run. Once you click "connect" to reach localhost, the password dialog pops up. In this case, enter a dummy password that is different from the real password (Peikari) that we chose previously.
The server uses the WSOCK32!recv function to retrieve data sent from a socket:
int recv ( SOCKET s, char FAR* buf, int len, int flags );
The second parameter ( char FAR* buf ) is the important one, as the data will be stored within it. Before you continue to enter the password, hit Ctrl-D to break into SoftICE. Now set a breakpoint on the recv function, as follows:
bpx recv do "d esp->8"
Enter Ctrl-D again, then click OK to send the password to the client. SoftICE will break on the bpx. Press F11, and you will see your dummy password in SoftICE's data window, along with its current address in memory.
Now set a bpr on the password's address (e.g., bpr 405000 405010 RW). Run the program again, and this time SoftICE will break at location 004040dd. You will see the following code:
0167:004040dd 8b0e mov ecx,[esi] ; our password 0167:004040df 8b1f mov ebx,[edi] 0167:004040e1 39d9 cmp ecx,ebx 0167:004040e3 755 jnz 0040413d 0167:004040e5 4a dec edx 0167:004040e6 7415 jz 004040fd 0167:004040e8 8b4e04 v ecx,[esi+04] ; move 1 st 4 chars into ecx 0167:004040eb 8b5f04 mov ebx,[edi+04] ; move another 4 chars into ebx 0167:004040ee 39d9 cmp ecx,ebx ; compare the two values
The program breaks at line 4040dd after we set a bpr on our dummy password. Thus, the password must be located inside the buffer to which esi points. The first four characters are moved into ecx , and another four characters are moved into ebx . They will then be compared.
We have now found the cmp that compares our dummy password with the real one, right? Wrong! We have stumbled on to the fact that the author of SubSeven has put a backdoor in his backdoor ! Type d edi to see the data contents of the edi register in SoftICE, and you will see the following:
016F:012A3DD4 31 34 34 33 38 31 33 36-37 38 32 37 31 35 31 30 1443813678271510 016F:012A3DE4 31 39 38 30 00 69 6F 00-28 00 00 00 22 00 00 00 1980.io.(..."... 016F:012A3DF4 01 00 00 00 13 00 00 00-53 75 62 73 65 76 65 6E ........Subseven 016F:012A3E04 5F 5F 5F 3C 20 70 69 63-6B 20 3E 00 10 3E 2A 01 __ _< pick >..>*. 016F:012A3E14 10 3E 2A 01 38 00 00 00-53 75 62 73 65 76 65 6E .>*.8...Subseven
This number (14438136782715101980) is not the password we set. We now disable all of the breakpoints ( bd * ) and run the program, this time entering the password 14438136782715101980. SubSeven responds with "connected."
This exercise reveals that SubSeven's author has secretly included a hardcoded master password for all of his Trojans! The Trojan itself has been Trojaned. You just can't trust anyone these days.
|< Day Day Up >|