Practical Malware Analysis - Lab 5

Discovering IDA Pro

Lab 5

This lab use the file Lab05-01.dll. It has to be analyze only on IDA Pro. This is my first experience with this tool.

What is the address of DllMain ?

The address of DllMain can be find in the Functions Windows by default on the left side of your screen. It starts at 0x1000D02E.

start_address

Also, you can visualize it on the Graph View by turning on Line Prefixes in the settings. For me it was already checked.

start_address2

Use the Imports window to browse to gethostbyname.

Where is the Import located ?

If the Import Windows isn’t enable by default. You can show it by clicking on:
View -> Opensubviews -> Imports

The imports address of that function is 0x100163CC.

imports

How many functions call gethostbyname ?

In order to see where the gethostbyname functions is call we use Cross-reference. To open the all the cross-reference of this function, you have to use the shortcut CTRL + X once the name is highlighted.

It should open this windows and list all the references.

xrefs

There are 18 calls of this function made by 5 differents subroutines.

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

We jump to the address mentionned in the question with the jump to address setting.

jump_dns

Here we are.

dns

Before the execution of the function we can see that a strings is moved in the EAX register. The strings is: “[This is RDO]pics.practicalmalwareanalysis.com”. The comma with the “0” is here to indicate a NULL Byte. This byte is used by the system to know when the string end.

strings

Then there is the operand ADD with the parameter 0Dh. The parameter is an hexadecimal value. We convert it in base10 and see that this number is 13. In other words, 13 bytes will be added to the EAX pointer. The new string start from: “pics.practicalmalwareanalysis.com”. This is the real address that the domain will have to resolv.

After that the EAX register is push on the stack to be used by the gethostbyname API function in order to make the call.

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

Let’s jump to 0x10001656. Here we can see 23 locals variables. There are created with a negative ptr. Otherwise,positive content mean parameter of the function.

local_variables

How many parameters has IDA Pro recognized for the subroutine at 0x1001656 ?

As we said previously, we can count only one positive value. There is only 1 parameter on this function.

parameter

Use the Strings windows to locate the string “cmd.exe” in the disassembly. Where is it located ?

View -> Opensubviews -> Strings

The strings “cmd.exe” is located at 0x10095B34.

cmd

What is happening in the area of code that references “cmd.exe” ?

We follow the cross-reference to see where the string is use.

cmd_use

The string is pushed on top of the stack to be use by a command line function. This is used to open the terminal.

If we go down a little bit we can see other strings like “quit, exit, cd”

strings2

Then let’s go back to the text view where we saw new strings. They looks like automatic “welcome” for the owner of the malware. Futhermore, we can read a “reverse shell session”. This is probably how the attacker persist on the computer of his victim.

strings3

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 ?

At 0x100101C8 the dword_1008E5C4 is compare to the content of EBX register.

dword_1008E5C4

Currently, we don’t know what is the value of this variable. We use cross-reference to see where it is initialize and what does it contain.

xref_dword_1008E5C4

The EAX register is equal to the result of the function: sub_1003695. Following this one we can see that it tries to gather facts on the operating system like:

  • major version
  • minor version
  • platform id

subroutine

The function GetVersionExA return the major version of your operating system. For example: Windows 8.1, Windows 10. It take a structure parameter call lpVersionInformation that will receive the information.

MSDN_GetVersionExA

Then there is a comparison between the content of the VersionInformation.dwPlatformId and 2. On the MSDN documentation, we can see that this function is use to Identifies the operating system, or platform supported by an assembly.

Here are the value that the function can take:

msdn_platformid

The compare value is 2. The malware tries to define if the target run a Win32NT or later operating system.

Finally, 1 is push on the top of the stack, so EAX=1 after the pop eax instruction. The retn allow us to resume the execution flow after the subroutine call.

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 successfull ?

At 0x10010438 there is a jnz instruction to 0x10010444 which is the entry of a routine containing the robotwork string.

robotwork

EAX contain the return of the memcmp function. The question say that the string comparison to robotwork is succesfull. The return of memcmp is set to EAX. The return is succesfull, it mean that EAX = 0, so ZF = 1. The jnz instruction only jump if ZF = 0. So, it will not take the jnz branch.

jump_flag

But it will jump to 0x100052A2

robotwork_2

In this area the malware open the register key: SOFTWARE\Microsoft\Windows\CurrentVersion

If the register key was sucessfully opened then it return an ERROR_SUCCESS. Otherwise, it will return nonzero value.

MSDN_GetOpenKeyExA

Then there is a jz jump instruction to 0x10005309 if ZF = 1.
To determine if ZF = 1 or 0, a test between EAX and itself is made. If the register failed to open it will contain a nonzero value. So the jz instruction will only be execute if the open work.

Here is the function starting at 0x10005309 robotwork_3

The content of the register key WorkTime will be gather. Then it will jump to 0x10005379 if the query wasn’t achieve.

MSDN_RegQueryValueExA

Here is the function starting at 0x10005379

robotwork_4

The content of the register key WorkTimes will be gather.

Finally, we can see that the information is send over the network with the s parameter corresponding to the socket created.

network_send

network_socket

What does the export PSLIST do ?

View -> Open subview -> Export

pslist_export

I find a very usefull shortcut. You can press space to switch from graph to text view and inversely.

There is two possibilities depending on the result of the routine 0x100036C3.

two_possibilities

We already focus on the beginning of this function previously. Here is what it looks like:

major_version

The major version is compare to 5 like the platform id with 2.
With MSDN documentation, we see that 5 can correspond to several operating system.

msdn_os

Then, depending on the result it will go at 0x10007046 or 0x1000704E.

a) The subroutine 10006518

It create a snapshot of a process. The EBX register is used to give the ID to be dump.

snapshot_1

b) The subroutine 100664C

It perform the same call as the previous routine. The only difference, is the snapshot that is send over the open socket.

snapshot_2

MSDN_CreateToolHelp32Snapshot

Use the graph mode to graph the cross-reference 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 ?

Let’s use the jump command by pressing g. Then we have to show the cross_reference graph. In order to achieve that you have to go in View -> Chart -> Xref from and then a chart will pop up.

xref_chart

Based on all the functions name on this graph, we can assume that this routine can be call like SystemLanguageID_Send.

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

There are 4 API Functions:

  • CreateThread
  • StrnCpy
  • StrLen
  • StrCmp

depth1

With a depth of 2 the chart is unreadable, you have to zoom a lot. I don’t count all the API functions but there are a lot.

depth2

At 0x10001358, there is a call to Sleep. Looking backward though the code, how long will the program sleep if this code executes ?

The sleep function take a milliseconds parameter that is store in EAX.

sleep

Following the offset at 0x10001341, we can see that a string is store in EAX: [This Is Cti]30.

offset

Then 0Dh (= 13) is add to the EAX pointer. In other word the pointer is move 13 bytes further. The new string is 30.

The atoi function convert the string in an integer. Finally, the number 30 is multiply by 1000. This is equal to 30 000 ms corresponding to 30 seconds.

eax content

The program will sleep 30 seconds.

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

The three parameters are push on the stack then the socket function is call. On the MSDN, we can see the meaning of these numbers.

MSDN_Socket

  • Protocol: 5 -> TCP
  • Type: 1 -> SockStream
  • AF: 2 -> AF_INET

parameters

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

The question is partially answered previously. To rename a parameter we have to right click on it, chose Symbolic constant and use standart symbolic constant. Then you can search whatever you want.

tcp

This is what it looks like when changes are done:

final

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 ?

Use the shortcut ALT + T to search for string ocurrence. For “VMXh” there aren’t any outputs.

vmxh_search

With the shortcut ALT + B you can search for bytes sequences.. We search for the in instruction which is equivalent to 0xED. There is only one result with a in instruction.

0xed_result

Following the function (0x10006196), we can see a comparison that is made. Decoding the hexadecimal value, we found the string VMHx.

vmxh_result

An anti-vm instruction is implement to cancel the installation of the malware on the target.

anti_vm_graph

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

At 0x1001D988 we can find dummies strings..

dummy_strings

If you have the IDA Python plug-in installed, run Lab05-01.py, an IDA Pro Python script provided with the malware for this book. What happens after you run the script ?

I don’t have IDA Python installed but when you open the script you can see that it XOR 0x50 (= 80 base 10) bytes with the 0x55 key. Futhermore, there are 80 encoded characters at 0x1001D988. We assume that the script decrypt those characters.

script

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

Pressing A you can concatenate the bytes

concatenate_strings

Then we can use an online tool to XOR like the script does. Here is the result:
xdoor is this backdoor, string decoded for actical malware analysis lab :)1234

result