PMA - CH 11-2

Analysis of Lab11-02.dll and Lab11-02.ini

We are given two files for this analysis Lab11-02.dll and Lab11-02.ini

First inspecting the ini file we can see what appears to be some random data. Most likely encoded.

Looking at the DLL we can see it has one export called 'installer' which I can only assume it will be installing the malware...

Let's analyze the export first. Opening the DLL in Ghidra we can see a pretty simple function that doesn't appear to call anything else

This function is opening a registry with RegOpenKeyExA, it is opening HKLM\SOFTWARE\Microsoft\Windows_NT\CurrentVersion\Windows. It then gets the string length of some data. Looking at the data we can see it is: spoolvxx32.dll

It then calls RegSetValueExA, passing in AppInit_DLLs as the value name, and passes spoolvxx32.dll as the data to be stored in the registry.

Next, it gets the system directory by calling GetSystemDirectory() and concatenates the system path with spoolvxx32.dll. This gives us this: "C:\Windows\System32\spoolvxx32.dll"

It then copies itself to spoolvxx32.dll

I was curious about why it was creating a registry name so I looked into AppInit_DLLs. Per MSDN AppInit_DLLs is a mechanism that allows an arbitrary list of DLLs to be loaded into each user mode process on the system. However, the next statement states that in Windows 7 a code-signing requirement for DLLs to use AppInitDLLs. This makes sense as to why during my dynamic analysis the AppInitDLL wasn't populated with spoolvxx32.dll. If on Windows XP and earlier you could use AppInitDLLs to create persistence on the machine since every process would load the specified DLL into memory.

Now shifting our focus to the rest of the DLL. There were a few interesting functions.

The first one is IniFile (sub_10001610). This function made a call to GetSystemDirectory() again and this time concatenated the path with Lab11-02.ini giving us a path of "C:\Windows\System32\Lab11-02.ini".

It then calls CreateFile() with the specific path above. For the creation disposition argument, it was passed a 3 which indicates it is looking for an existing file on the system. This means for this DLL to work properly the Lab11-02.ini file should be located within your system directory.

From there the sample will then call DecryptWrapper (sub_100010b3). Which as the name suggests is going to be used to decrypt our random data held within the Lab11-02.ini file. In this blog post, I'm not going to over the decryption routine but it uses a while loop to loop through each character in the file and XOR's it. Once fully decrypted we can see the string generated is:

"billy@malwareanalysisbook.com"

We are now back in our IniFile function. The last call that is made is to StringComparisonWrapper (sub100014b6). This function calls GetModuleFileNameA() to get the path of the executable. It passes the path to another function StringManipulation (sub_10001104). This calls strrchr, which looks for the last occurrence of a character specified. In this example, it is looking for the last occurrence of 0x5c which in ASCII is a "\\". This will return the executable's name and not the full path.

Moving back now to our StringComparisonWrapper function. It will call another function, which converts the executable's name to upper case. It then goes into a nested IF statement which is comparing the process name to three different hardcoded processes.

THEBAT.EXE | OUTLOOK.EXE | MSIMN.EXE

If the process's name does not match one of these three it will exit.

If the process name matches one of the values we jump down to the bottom of the code. It will call LoadModule (sub_100012a). Looking at this function we can see the sample loading wsocks32.dll and then getting the address of the export send

Which passes this information to Hook_ws32 (sub_10001203). Looking at this function we can see the sample hooking the send function within wsocks32.dll. This requires some prior knowledge of hooking. If you are interested check out this blog. But the goal of hooking is when a certain function is called you want to redirect the code to your function which can check the variables passed or you can manipulate the variables. Hooking has been used for a long time and is implemented both on the defender's side as well as the offensive side.

The pseudo-code for this function is quite messy...

The last thing we need to look at is the trampoline function SendHooked (sub_1000113d). Looking at it we can see it is modifying the recipients by adding an entry "RCPT TO:" and our decoded value from the ini file which was "billy@malwareanalysisbook.com". And then the function finally calls the real send function passing in the same arguments that were passed to it originally.

Now things are starting to come together. Let's recap everything that happened.

  1. The DLL must be installed using the export which will use the APPInit_DLLs to load itself into every process.

  2. It looks for three processes which are all mail clients. (THEBAT.EXE | OUTLOOK.EXE | MSIMN.EXE)

  3. If found the sample will then hook the function "send" within wsocks32.dll

  4. Now every time the send function is called from that process it will add another recipient to the message (in this case it will add the email address billy@malwareanalysisbook.com)

Last updated