See for our method of capturing data using Wireshark, a fake mail server, and Outlook Express.
DllMain
, which starts by checking for DLL_PROCESS_ATTACH
, as with the previous lab. It appears that this malware runs only during DLL_PROCESS_ATTACH
; otherwise, DllMain
returns without doing anything else.strncat
at ❸. The malware attempts to open the INI file for reading at ❹. If the file cannot be opened, DllMain
returns.If the malware successfully opens the INI file, it reads the file into a global buffer, as shown in at ❶.
byte_100034A0
, which we rename email_address
in IDA Pro to aid future analysis.We have one last function to analyze inside DllMain
: sub_100014B6
. Because this function will install an inline hook, we’ll rename it hook_installer
. The hook_installer
function is complicated, so before diving into it, we provide a high-level overview of what this inline hook looks like after installation in .
send
function in ws2_32.dll looks like. The right side of the figure shows how hook_installer
installs an inline hook of the send
function. The start of the send
function is replaced with a jump to malicious code, which calls a trampoline (shown in the figure’s lower-right box). The trampoline simply executes the start of the send
function (which was overwritten with the first jump) and then jumps back to the original send
function, so that the send
function can operate as it did before the hook was installed. contains code from the first of these functions, sub_10001075
.
GetCurrentProcessId
and then sub_100012FE
, which we rename to suspend_threads
. The suspend_threads
function calls GetCurrentThreadId
, which returns a thread identifier (TID) of the current thread of execution. Next, suspend_threads
calls CreateToolhelp32Snapshot
and uses the result to loop through all of the TIDs for the current process. If a TID is not the current thread, then SuspendThread
is called using the TID. We can conclude that the function called at ❶ suspends all executing threads in the current process.Conversely, the function called at ❸ does the exact opposite: It resumes all of the threads using calls to ResumeThread
. We conclude that the code in is surrounded by two functions that suspend and then resume execution. This behavior is common when malware is making a change that could impact current execution, such as changing memory or installing an inline hook.
Next, we examine the code in the call at ❷. The function sub_100012A3
takes four arguments, as shown by the series of pushes in . Since this function is called only from this location, we can rename all of the arguments to match what is passed to the function, as shown in beginning at ❶.
GetModuleHandleA
at ❷. That handle is passed to GetProcAddress
to resolve the send
function at ❸. The malware ends up passing the address of the send
function and the two other parameters (sub_1000113D
and dword_10003484
) to sub_10001203
, which we renamed place_hook
.Now, we examine place_hook
and rename the arguments accordingly in order to aid our analysis. shows the start of place_hook
.
send
function and the start of sub_1000113D
. This difference has an additional 5 bytes subtracted from it before being moved into var_4
at ❶. var_4
is used later in the code and prepended with 0xE9
(the opcode for jmp
), making this a 5-byte instruction to jump to sub_1000113D
.Let’s see how the malware installs this code as a hook later in place_hook
. The start of the send
function is modified by the instructions shown in .
var_4
contains the destination of the jump, sub_1000113D
. The code in places a jmp
instruction at the beginning of the send
function that jumps to the function in our DLL at sub_1000113D
, which we’ll now rename hook_function
.Before we examine hook_function
, let’s wrap up our analysis of the inline hook installation. shows place_hook
manipulating memory.
place_hook
calls VirtualProtect
at ❶ on the start of the send
function code. This action changes the memory protection to execute, read, and write access, thereby allowing the malware to modify the instructions of the send
function. Another call to VirtualProtect
at the end of the shows the creation of the trampoline’s code.memcpy
at ❶ copies the first 5 bytes of the send
function into the trampoline. Since the malware overwrites the first 5 bytes of the send
instruction (), it needs to make sure that the original instructions are saved. The malware assumes that the send
function’s first several instructions align exactly on 5 bytes, which might not always be the case.Next, the malware adds a jmp
instruction to the trampoline code at ❷ and ❸. At ❷, the 0xE9
opcode is added. At ❸, the location to jump is added. The jump location is calculated by subtracting the location of the trampoline from the location of the send
function (meaning it will jump back to the send
function).
Finally, place_hook
ends by setting the global variable dword_10003484
to the trampoline location. We rename dword_10003484
to trampoline_function
to aid analysis.
Next, we analyze hook_function
(sub_1000113D
), which will have the same arguments as the send
function since it is installed as a hook. We begin our analysis by right-clicking the function name, selecting Set Function Type, and entering the following:
RCPT TO: <
at ❶, followed by email_address
at ❷, and ends with >\r\n
at ❸. The email_address
value in this case is (extracted from Lab11-02.ini, as explained earlier when we looked at the contents of that file). This code adds a recipient to all outgoing email messages.The program calls the send
function.
The first instruction of the send
function transfers execution to sub_1000113D
.
sub_1000113D
manipulates the outgoing buffer only if it contains a RCPT TO
string.
sub_1000113D
calls the trampoline code located on the heap and pointed to by dword_10003484
.
The trampoline code executes the first three original instructions of the send
function (which it overwrote to install the hook).
The trampoline code jumps back to the send
function 5 bytes in, so that send
can function normally.
send
function with the jmp
hook to sub_1000113D
. (If you like, you can set a breakpoint at this jump and analyze the code during runtime.)installer
, which installs the malware persistently using AppInit_DLLs
, causing the malware to be loaded into most processes. The malware checks to see if it is loaded into a mail client by using a preset list of process names to target. If the malware determines that it is running inside one of these processes, it will act as a user-mode rootkit by installing an inline hook for the send
function. The hook takes the form of a jmp
instruction placed at the beginning of the send
function. The hook executes a function that scans every data buffer passed to the send
function and searches for RCPT TO
. If the malware finds the RCPT TO
string, it inserts an additional RCPT TO
containing an email address retrieved by decoding Lab11-02.ini, essentially copying the malware author on every email sent from the targeted email programs.