The most interesting strings are ftp.practicalmalwareanalysis.com and Home ftp client,
which indicate that this program may be FTP client software.
The imports FindFirstFile and FindNextFile indicate that the program probably searches through the victim’s
filesystem. The imports InternetOpen, InternetConnect, FtpSetCurrentDirectory, and FtpPutFile tell us that this malware may upload files from the victim
machine to a remote FTP server.
The object created at 0x004011D9 represents a .doc file. It has one virtual function at offset 0x00401440, which uploads the file to a remote FTP server.
The virtual function call at 0x00401349 will call one of the virtual functions at 0x00401380, 0x00401440, or 0x00401370.
This malware connects to a remote FTP server using high-level API functions. We could download and set up a local FTP server, and redirect DNS requests to that server in order to fully exercise this malware.
This program searches the victim’s hard drive and uploads all the files with a .doc or .pdf extension to a remote FTP server.
The purpose of implementing a virtual function call is to allow the code to execute different upload functions for different file types.
First, we look at the program’s strings. The two most interesting strings are Home ftp client and ftp.practicalmalwareanalysis.com. Looking at the imports, we also see FtpPutFile and FtpSetCurrentDirectory.
Taken as a whole, the strings and imports strongly suggest that this program is going to connect to
an FTP server.
Next, we run this program to perform dynamic analysis. Because of the FTP-related strings, we should set up an FTP server on our malware analysis machine and use ApateDNS to redirect DNS requests to the local machine.
When we run the malware, we see in procmon that the malware is opening files in directories
starting with c:\, and then searching each directory and subdirectory. Looking
at the procmon output, we see that the program is mostly opening directories, not individual files,
and that it is opening files with .doc and .pdf
extensions. Where the code opens .doc and .pdf files, we
also see calls to TCPSend and TCPRecv, which show connections to the local FTP server. If the FTP server you are
running has logs, you should be able to see the connections being made, but you won’t see any
files that have been successfully uploaded, so let’s load the program into IDA Pro to see what
is going on. The program’s main method is relatively short,
as shown in Example C-211.
Example C-211. The main method for Lab 20-2 Solutions
00401500 push ebp 00401501 mov ebp, esp 00401503 sub esp, 198h 00401509 mov [ebp+wVersionRequested], 202h 00401512 lea eax, [ebp+WSAData] 00401518 push eax ; lpWSAData 00401519 mov cx, [ebp+wVersionRequested] 00401520 push ecx ; wVersionRequested 00401521 ❶call WSAStartup 00401526 mov [ebp+var_4], eax 00401529 push 100h ; namelen 0040152E ❸push offset name ; name 00401533 ❷call gethostname 00401538 push 0 ; int 0040153A push offset FileName ; "C:\\*" 0040153F ❹call sub_401000 00401544 add esp, 8 00401547 xor eax, eax 00401549 mov esp, ebp 0040154B pop ebp 0040154C retn 10h
The code starts by calling WSAStartup at ❶ to initialize the Win32 network functions. Next, it calls
gethostname at ❷ to
retrieve the hostname of the victim. The hostname is stored in a global variable, which IDA Pro has
labeled name at ❸. We
rename this variable to local_hostname so that we can recognize
it when it’s used later in the code. The code then calls sub_401000 at ❹, which will execute the rest
of this malware. Examining sub_401000, we see that it calls
FindFirstFile, and it runs in a loop that calls FindNextFile and also calls itself recursively. You should recognize this
pattern as a program searching through the filesystem. In the middle of the loop, we see a lot of
string-manipulation functions (strcat, strlen, strncmp, and so on), which will find what the
program is searching for. A strncmp compares the manipulated
string to the characters .doc. If the filename ends in
.doc, the code in Example C-212 is
executed.
Example C-212. Object creation code if a file ending in .doc is found.
004011D9 push 8 004011DB call ??2@YAPAXI@Z ; operator new(uint) 004011E0 add esp, 4 004011E3 ❶mov [ebp+var_15C], eax 004011E9 cmp [ebp+var_15C], 0 004011F0 jz short loc_401218 004011F2 mov edx, [ebp+var_15C] 004011F8 ❷mov dword ptr [edx], offset off_4060E0 004011FE mov eax, [ebp+var_15C] 00401204 ❸mov dword ptr [eax], offset off_4060DC 0040120A mov ecx, [ebp+var_15C] 00401210 mov [ebp+var_170], ecx 00401216 jmp short loc_401222
This code creates a new object that represents the file ending in .doc
that has been found. The code first calls the new operator to
create an object, and then it starts to initialize the object. The object is stored in var_15C at ❶. Two
instructions, at ❷ and ❸, write the virtual function table to the object’s first offset. The first
instruction at ❷ is useless to us because it is
overwritten by the second mov instruction at ❸.
We know that off_4060DC is a virtual function table because
it is being written to an object immediately after creation with the new operator, and if we look at off_4060DC, we see
that it stores a pointer to a function at sub_401440. We’ll
label this function docObject_Func1 and analyze it later if we
see it called.
If a filename does not end in .doc, the code checks to see if the filename ends in .pdf. If so, it creates a different type of object, with a different virtual function table, at offset 0x4060D8. Once the pdf object is created, the code jumps to 0x4012B1, and then to 0x40132F, the same location that is executed after a doc object is created. If the filename does not end in .pdf or .doc, then it creates another type of object for all other file types.
Following the jump where all code paths converge, we see code that moves our object pointer
into var_148, and then we see the code in Example C-213.
Example C-213. A virtual function call
0040132F mov ecx, [ebp+var_148] 00401335 mov edx, [ebp+var_4] 00401338 mov [ecx+4], edx 0040133B mov eax, [ebp+var_148] 00401341 mov edx, [eax] 00401343 mov ecx, [ebp+var_148] 00401349 call dword ptr [edx]
This code references the object stored in var_148,
and then calls the first pointer in the virtual function pointer table. This code is the same
whether a .pdf or .doc object is created, but the function
called differs for different types of objects.
We saw earlier that the code could create one of three different objects:
An object for .pdf files, which we’ll call pdfObject. The first function for this object in the virtual function table is at
0x4060D8.
An object for .doc files, which we’ll call docObject. The first function in the virtual function table for this object is at
0x4060DC.
An object for all other files, which we’ll call otherObject. The first function in the virtual function table for this object is at
0x4060E0.
We’ll first check the function to be called for a pdf object. We navigate to the virtual
function table at 0x4060D8 and find that the function being called starts at 0x401380. We see that
it calls InternetOpen to initialize an Internet connection, and
then calls InternetConnect to establish an FTP connection to
ftp.practicalmalwareanalysis.com. Then we see it changes the current directory
to pdfs and uploads the current file to the remote server. We can now rename
the function pdfObject_UploadFile. We also look at the function
for docObject and see that it executes nearly the same steps,
except that it changes the directory to the docs directory.
Finally, we look at the virtual function table for the otherObject to find the upload function for otherObject at 0x401370. This function does very little, and we can conclude that only
.doc and .pdf files are uploaded by this malware.
The malware author implemented virtual functions to allow this code to be easily modified or extended in order to add support for different file types simply by implementing a new object and changing the part of the code where the object is created.
To test this code, we can add directories named docs and pdfs to our FTP server, and allow anonymous write access to them. When we rerun our malicious code, we see that it uploads every .pdf and .doc file from the victim’s computer to these directories, naming each file with the victim’s hostname and an ID number.