# PlugX: Bad guy disguises as an msi file
## I. Overview

## II. Analysis
### 1. Locate suspicious files
Use msitool to extract `msidump -s -t mal.msi`. In `File.idt`, we can see that there are 3 embed file.

These files are extracted to `%LOCALAPPDATA\kjnBsLsJo\`
```
2024Contact.exe
security.dll
contactDB.dat
```
Upon running, the program opens an pdf file called `Meeting Invitation.pdf`

### 2. DLL Side-loading technique
`security.dll` export 3 functions

`2024Contact.exe` load `security.dll` which trigger the call to `NimMain` in Dll dispatcher. Then, the executable calls `InitSecurityInterfaceW` after resolving its address.

The `NimMain` function's role is to resolve global variables's value. Most of them are api's address and config. Below is one of the functions called in `NimMain`

For `InitSecurityInterfaceW`, it registers a Window class object and a message dispatcher.

The call to `RegisterClassW` at line 50 requires a `WNDCLASSW` object. According to this [docs](https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-wndclassa), the object's structure is below

The second entry `WNDPROC` is `A pointer to the window procedure`. The function pointed to by that entry is going to be registered for this window class.


The window proc opens `contactDB.dat` file, reads it to an allocated memory, decrypt and use it as a callback in `EnumSystemGeoID`

The data after decrypted is an PE file.

The interesting thing is the header can be converted to executable code to be able to pass into `EnumSystemGeoID`. It will eventually jump into `Initialize` function.

### 3. Depression: Navigating through the control-flow obfuscation
`Initialize` function implemented a control flow obfuscation method.

Checking the functions calls, there are only a few `call` instructions in this function. The obfuscation method set up the call manually and place the called address to eax.

By placing breakpoints in all these calls, we can monitor the api used by this function as below:
```
kernel32_VirtualAlloc
kernel32_LoadLibraryA (kernel32.dll)
kernel32_GetProcAddress
GetProcAddress
LoadLibraryA
GetLastError
WriteConsoleW
CloseHandle
CreateFileW
QueryPerformanceCounter
GetCurrentProcessId
GetCurrentThreadId
GetSystemTimeAsFileTime
...
kernel32_LoadLibraryA (User32.dll)
kernel32_GetProcAddress
kernel32_VirtualProtect
kernel32_VirtualProtect
kernel32_VirtualProtect
kernel32_VirtualProtect
ntdll_NtFlushInstructionCache
DllEntryPoint
DllEntryPoint
```
It just initialize api and memory, the 2 importance calls are to `DllEntryPoint` function with args `fdwReason` equal to 1 and 4

For `fdwReason` equal to 4, it calls this function, which contains some suspicious activity of decrypting strings

The decryped string is used to resolve api, here at line 66 it resolves `SetUnhandledExceptionFilter` and call it imediately.

Then the program changes a few byte from the start of `SetUnhandledExceptionFilter`



A new thread is created to call `sub_5B313F3`

The thread first applies an anti debug check using 2 api `kernel32_GetCurrentProcess` and `kernel32_CheckRemoteDebuggerPresent`

To bypass this, we just have to change the return value of `eax` from `1` to `0`
### 4. The config
Tracing for a while, the program hit this function which decrypt a block of data

The algorithm used is `RC4` with key `10C6F`. After being decrypted, the data block contains many interesting strings.
```
ZwNlqMnRE
529
Meeting Invitation.pdf
buyinginfo[.]org
```
### 5. Victim's info gathering
This sample collects multiple information about the victim to for identification. That information is exfiltrate through `http`.

Here is the list of infos that this malware collects:
```
Window's version
Computer name
Username
File in %appdata%/Render
Machine's IP
Architecture
```
### 6. Suspicious pdf file opening
The malware first create `%temp%/tmp.dat` file by copying `contactDB.dat`. Read the content and then decrypt it.

Then, payload of the pdf is written to `%temp%/Meeting Invitation.pdf`

Finally, it call `ShellExecuteW` to open the pdf as we see at first. `%temp%/tmp.dat` then is deleted.
### 7. Anti-debug, mutex, and other shenanigans...
#### Mutex
Mutex `ZwNlqMnRE` is created to ensure that one instance of malware runs concurrently. The mutex name is taken from the config data.

#### Anti-debug
This sample actively checks for debugger by running a thread just to call `CheckRemoteDebuggerPresent` every 1 second with a call to `Sleep`

#### Registry activities
This sample creates/queries many registry keys for multiple purposes, like info collection or defense bypass.
```
SOFTWARE\Microsoft\Windows\CurrentVersion\InternetSetting - ProxyEnable
SOFTWARE\Microsoft\Internet Explorer\Version Vector - IE
SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\50\User Agent\Post Platform - *
SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\User Agent\Post Platform - *
Software\CLASSES\ms-pu - CLSID
```
To disable the proxy, it set the value of `ProxyEnable` to 0

It also copies modules to `%programdata%\VirtualFile\` and creates a value of the key `CurrentVersion\Run` to achieve persistence.

The copy destination folder like`%programdata%\VirtualFile\` is randomly set, which variant between these:
```
%userprofile%\Intelnet
%allusersprofile%\VirtualFile
%public%\SamsungDriver
%appdata%\SecurityScan
%localappdata%\DellSetupFiles
```
### 8. How it communicate under the hood

This sample interacts with `buyinginfo[.]org` at port `443`, it first receives a key from malicious server then uses it to encrypt traffic afterward.
The first request to the server includes randomly generated data

Another piece of data included is the `CLSID` value of registry key `Software\CLASSES\ms-pu`
Note that these data is located in the header section of the http request as it is added using `winhttp_WinHttpAddRequestHeaders`

After sending those data, it read 32 bytes from the response of the server.

For the second round, it collects the host's info (which was mentioned in section 5 before), encrypts it using `RC4` algorithm using those 32 bytes of data as a key and sends the encrypted data to the server. Then, if there is a response from the server, it decrypt the data and uses the dword value at offset 4 as command and control option. For example, here it checks if the option value is equal to `0x7002`.

### 9. Command and Control
#### 0x1005: Bro gonna leave
This option deletes `%programdata%\VirtualFile\`, notice the server and then kill the process.
1. Search for module `2024 Contact.exe`
It uses APIs below to iterate through processes running on the machine and stop when `2023 Contact.exe` is found.
```
kernel32_CreateToolhelp32Snapshot
kernel32_Process32FirstW
kernel32_OpenProcess
kernelbase_EnumProcessModules
kernelbase_GetModuleFileNameExW
kernel32_Process32NextW
```
2. Create `%temp%\del_Contact Update.bat` using `kernel32_CreateFileW` and `kernel32_WriteFile`.

The written content:

3. Execute the `.bat` file using `kernel32_CreateProcessW`

4. Exit the process

#### 0x1007: Bro leaves violently

First it call `kernel32_SetUnhandledExceptionFilter`, which was previously modified from the begining. This fuction now leads us to a piece of 2 line instruction which only returns 0.

Then it call `kernel32_UnhandledExceptionFilter` to detect debugger and invoke the pre-registered handler.
Finally, `GetCurrentProcess` and `TerminateProcess` is called to exit.
However, if there is no debugger, it executes the exception handler. The handler then call `FatalAppExitW` with this message.

#### 0x3004: Drop / modify a file
1. Create new thread execute `sub_541312A`

2. Query `SOFTWARE\Microsoft\Internet Explorer\Version Vector` value `IE`

3. Enumerate through all the values in `SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\50\User Agent\Post Platform`

4. Send data to the server, then receive the file name and file data
5. Open file then write the content.

#### 0x7002: spawn cmd shell
To establish a connection between cmd shell and a malicious server, it uses a named pipe to send and receive data from the shell. By using 2 threads for reading and writing, it can interact with cmd simultaneity.
Here is the function that creates 2 named pipes and stores those handles to global variables.

It then cratf a `STARTUPINFO` structure and stores our handle to `hStdInput` and `hStdOutput`. By doing so, it can read data and write commands to the shell through the named pipe.

Finally, it creates a process `cmd.exe` using a crafted struct.

## III. IOC
|Type|Value|
|-|-|
|Mutex|ZwNlqMnRE|
|URL|buyinginfo[.]org|
|Filename|Meeting Invitation.pdf|
|Filename|del_Contact Update.bat|
|Filehash|7486cefa12be05d7c027c6d85b024835346e2450|
|Filehash|3e67011bbb2867de4ba17c0d2bb64db324d3b0c9|
|Filehash|2705079351efebe935ccbc395cbc16a523f69125|
|Filehash|dc62cb7c24c14d6dbb16412e6553c4f10c34051d|
|Registry key|HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run - Contact Update|
|Folder|%userprofile%\Intelnet|
|Folder|%allusersprofile%\VirtualFile|
|Folder|%public%\SamsungDriver|
|Folder|%appdata%\SecurityScan|
|Folder|%localappdata%\DellSetupFiles|
## IV. Att&ck technique used
