Lab 5-1 | Practical Malware Analysis

1. What is the address of DllMain?

As we can see from the functions window, the DLLMain is at 0x1000D02E, in the .text section.

2. Use the Imports window to browse to gethostbyname. Where is the import located?

If we search for gethostsbyname in the Imports window and then double click it, we can later see it’s in the .idata section at address 0x100163CC

3. How many functions call gethostbyname?

So if we search for this function in the disassembly window, then press X while highlighting it and then look all the xrefs, we’ll see that it appears to be called 18 times.
That differs from the author’s answer, which was 9 times. That’s because, as it’s also explained, IDA will reference the same function twice: once for the calling and once for the read.
So in total, those 9 calls while become 18.
The right answer is, of course, 9.

4. Focusing on the call to gethostbyname located at 0x10001757, can you figure out which DNS request will be made?

mov      eax, off_10019040
add      eax, 0Dh
push     eax             ; name
call     ds:gethostbyname

First we can see that whatever is at offset 0x10019040 will be moved into EAX register, then it’s adding 0XD into whatever it is in this EAX register.
0XD in decimal is 13, so that means it will be advancing 13 positions in the string it’s taking us to.
We can see that at position 0x10019040 we have the string [This is RDO]pics.praticalmalwareanalys, and what do we have left when we subtract the 13 letters? Pics.praticalmalwareanalys, that’s right.

Then we’ll push EAX to the top of the stack and then immediately call the method gethostbyname.
When the struct is called,
gethostbyname(const char *name), the pointer to the constant character will be pics.praticalmalwareanalys.

5. How many local variables has IDA Pro recognized for the subroutine at 0x10001656?


All of those ( the negative ones ).

6. How many parameters has IDA Pro recognized for the subroutine at 0x10001656?

The one labeled lpThreadParameter is the one parameter which IDA has recognized.

7. Use the Strings window to locate the string \cmd.exe /c in the disassembly. Where is it located?

At 0x10095B34, after we searched for it in the strings window and double clicked it.

8. What is happening in the area of code that references \cmd.exe /c?

We can see a few text strings right after the cmd.exe:

db 'WelCome Back...Are You Enjoying Today?',0Dh,0Ah
db 0Dh,0Ah
db 'Machine UpTime  [%-.2d Days %-.2d Hours %-.2d Minutes %-.2d Secon'
db 'ds]',0Dh,0Ah
db 'Machine IdleTime [%-.2d Days %-.2d Hours %-.2d Minutes %-.2d Seco'
db 'nds]',0Dh,0Ah
db 0Dh,0Ah
db 'Encrypt Magic Number For This Remote Shell Session [0x%02x]',0Dh,0Ah
db 0Dh,0Ah,0

It displays a couple of machine information strings of text and, from the last sentence, we can guess it starts a remote shell session.

9. In the same area, at 0x100101C8, it looks like dword_1008E5C4 is a global variable that helps decide which path to take. How does the malware set dword_1008E5C4? (Hint: Use dword_1008E5C4’s cross-references.)

From the author, we can see that ( pressing X to get a listing of all the cross references dword_1008E5C4 ), will show us 2 times this function is read but once written, and considering it’s asking us how the malware is setting something, we’ll deduce it’s refering to where it’s being written.

There, we see this:

call    sub_10003695
mov      dword_1008E5C4, eax

So whatever we called in sub_10003695 will get loaded into EAX, and moved from there into
dword_1008E5C4.

If we double click on the first one, it will take us to a function which is named _OSVERSIONINFOA, and holds the method GetVersionExA.

We’ll say this will give the OS information to the malware.

10. A few hundred lines into the subroutine at 0x1000FF58, a series of comparisons use memcmp to compare strings. What happens if the string comparison to robotwork is successful (when memcmp returns 0)?

After test eax, eax, if the result is not zero, we’ll just continue until the call to sub_100052A2, from where, after following it, we can see that it’s pushing the key regsitry  HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WorkTime unto the stack.



11. What does the export PSLIST do?

Didn’t know/understand, I’ll try to come back here when I know a bit more.

12. Use the graph mode to graph the cross-references from sub_10004E79. Which API functions could be called by entering this function? Based on the API functions alone, what could you rename this function?


Considering it’s getting the language from the system, we could call it GetLanguage.

13. How many Windows API functions does DllMain call directly? How many at a depth of 2?

To set the recursion depth here, I went to View > User xrefs chart and set the maximum recursion to 1, with the ending and starting point the same ( 0x1000D02E ).


And with a depth of 2:


Well that’s big.

14. At 0x10001358, there is a call to Sleep (an API function that takes one parameter containing the number of milliseconds to sleep). Looking backward through the code, how long will the program sleep if this code executes?

mov      eax, off_10019020
add      eax, 0Dh
push     eax             ; Str
call     ds:atoi
imul     eax, 3E8h
pop      ecx
push     eax             ; dwMilliseconds
call     ds:Sleep

We can see that here they are moving the contents of off_10019020 into EAX, that offset holds the value [This is NTI]30, and then it’s adding 0D ( 13 in decimal ) to it. As we’ve seen in previous cases, that means that the first 13 letters will be out, and we’ll be left with the number 30.
The number 30 is then pushed onto the stack. Afterwards we call atoi, and I’m not sure what that does.
Then 3E8 ( 1000 in decimal ) is multiplied by whatever there is in EAX, that it’s 30. That results in 30000 milliseconds, which results in 30 seconds.
The program will sleep for 30 seconds.

15. At 0x10001701 is a call to socket. What are the three parameters?

As we can see from a bit above, the three parameters are the protocol ( number 6 ), type ( number 1 ) and af ( number 2 ).

16. Using the MSDN page for socket and the named symbolic constants functionality in IDA Pro, can you make the parameters more meaningful? What are the parameters after you apply changes?

From the author explanations, we can guide ourselves with the help of the MSDN webpage which talks about symbolic constants.
So if the see the number 6 assigned to the protocol, that means we’ll have to go to the protocol table and look for the one value which is assigned as number 6. In this case, it’s IPPROTO_TCP for protocol, SOCK_STREAM for type and AF_INET for number 2.

17. Search for usage of the in instruction (opcode 0xED). This instruction is used with a magic string VMXh to perform VMware detection. Is that in use in this malware? Using the cross-references to the function that executes the in instruction, is there further evidence of VMware detection?

At first I found the string ‘Found Virtual Machine’ in the disassembly view, but after reading the author’s explanations, I stumbled across this part:

mov     eax, 'VMXh'
mov     ebx, 0
mov     ecx, 0Ah
mov     edx, 5658h
in       eax, dx

I right clicked on the VMXh and selected it as ASCII, but it first looked like 564D5868h.

18. Jump your cursor to 0x1001D988. What do you find?

Looks like a bunch of characters without apparent meaning.

19. If you have the IDA Python plug-in installed (included with the commercial version of IDA Pro), run Lab05-01.py, an IDA Pro Python script provided with the malware for this book. (Make sure the cursor is at 0x1001D988.) What happens after you run the script?

Oh?! Now the weird characters have a meaning.

20. With the cursor in the same location, how do you turn this data into a single ASCII string?

a1UUUbackdoorSt db '-1::',27h,'u<&u!=<&ubackdoor, string decoded for Practical Malwar'
.data:1001D988          db 'e Analysis Lab :)1234UUUUUUUUUUUUUU',0

Ah, fun! I pressed A and then right clicked on the first address.

21. Open the script with a text editor. How does it work?

sea = ScreenEA()

for i in range(0x00,0x50):
       b = Byte(sea+i)
       decoded_byte = b ^ 0x55
       PatchByte(sea+i,decoded_byte)

From this website we see that the ScreenEA() will get the segment’s starting address, but the author says that it grabs the location of the cursor, so maybe that explains is better.
From 0 to 80 range, we’ll assign the value of b to whatever character is the at sea + i calling the Byte function ( which grabs the byte as the name specifies ).
Then we decode the byte so that we are able to interpret it.
Finally it calls PatchByte, which will modify what we see, but not modify the file.

Comments

Popular Posts