if
statement that checks for an active Internet connection.printf
is the subroutine located at 0x40117F.
The second function called from main
is located at 0x401040. It downloads the web page located at: and parses an HTML comment from the beginning of the page.
This subroutine uses a character array filled with data from the call to InternetReadFile
. This array is compared one byte at a time to parse an HTML comment.
There are two network-based indicators. The program uses the HTTP User-Agent Internet Explorer 7.5/pma
and downloads the web page located at: .
First, the program checks for an active Internet connection. If none is found, the program terminates. Otherwise, the program attempts to download a web page using a unique User-Agent. This web page contains an embedded HTML comment starting with <!--
. The next character is parsed from this comment and printed to the screen in the format “Success: Parsed command is X,” where X is the character parsed from the HTML comment. If successful, the program will sleep for 1 minute and then terminate.
Error 2.3: Fail to get command Error 2.2: Fail to ReadFile Error 2.1: Fail to OpenUrl http://www.practicalmalwareanalysis.com/cc.htm Internet Explorer 7.5/pma Success: Parsed command is %c
. This domain can be used immediately as a network-based indicator.
These imports contain several new Windows API functions used for networking, as shown in .
InternetReadFile InternetCloseHandle InternetOpenUrlA InternetOpenA
All of these functions are part of WinINet, a simple API for using HTTP over a network. They work as follows:
InternetOpenA
is used to initialize the use of the WinINet library, and it sets the User-Agent used for HTTP communication.
InternetOpenUrlA
is used to open a handle to a location specified by a complete FTP or HTTP URL. (Programs use handles to access something that has been opened. We discuss handles in .)
InternetReadFile
is used to read data from the handle opened by InternetOpenUrlA
.
InternetCloseHandle
is used to close the handles opened by these files.
Next, we perform dynamic analysis. We choose to listen on port 80 because WinINet often uses HTTP and we saw a URL in the strings. If we set up Netcat to listen on port 80 and redirect the DNS accordingly, we will see a DNS query for , after which the program requests a web page from the URL, as shown in . This tells us that this web page has some significance to the malware, but we won’t know what that is until we analyze the disassembly.
401040
and 40117F
) in the main
method were not in . shows the InternetOpenUrlA
and the InternetReadFile
calls.
Buf
fer
goes up by 1 before it is moved into a register, and then compared.Buffer
and define an array 1 byte wide and 512 bytes large. The right side of the figure shows what the corrected stack should look like.Manually adjusting the stack like this will cause the instruction numbered ❼ in to be displayed as [ebp+Buffer+4]
. Therefore, if the first four characters (Buffer[0]-Buffer[3]
) match <!--
, the fifth character will be moved into AL and returned from this function.
Returning to the main
method, let’s analyze what happens after the 0x401040 function returns. If this function returns a nonzero value, the main
method will print as “Success: Parsed command is X,” where X is the character parsed from the HTML comment, followed by a call to the Sleep
function at 0x401173. Using MSDN, we learn that the Sleep
function takes a single parameter containing the number of milliseconds to sleep. It pushes 0xEA60
on the stack, which corresponds to sleeping for one minute (60,000 milliseconds).
To summarize, this program checks for an active Internet connection, and then downloads a web page containing the string <!--
, the start of a comment in HTML. An HTML comment will not be displayed in a web browser, but you can view it by looking at the HTML page source. This technique of hiding commands in HTML comments is used frequently by attackers to send commands to malware while having the malware appear as if it were going to a normal web page.