On or around June 27, 2018, personal particulars of almost 1.5 million people was exfiltrated from a SingHealth database in Singapore where information on patients was stored. Multiple pieces and types of malware was used in this attack which took place over almost a year .
On 6th March, Symantec released a blog article  linking several pieces of malware and a threat group which we will be tracking as SectorM04 to Singapore’s SingHealth breach last year. One such artifact we found an exact match on was the DLL Shellcode Loader which was referred to as Trojan.Vcrodat that is one of the files dropped as something which has characteristics of the PlugX RAT. The PlugX RAT is a RAT which has been used by multiple threat groups, including one which was reported to have interests in the healthcare sector .
The dropper for that file was in the form of a decoy executable/document and named as “PositionRequirement-SeniorCivilEngineer.doc.exe”. Opening this results in the Word document below being opened, and everything will seem normal to the victim.
However, this is actually a trick because the malware uses a “.docx.exe” extension. The actual executable drops other files in the same folder – a legitimate signed executable, a malicious DLL file which abuses the DLL search order  from the executable, a compressed shellcode file, a simple batch script (a.bat) to clear its tracks, and a normal Word document. The executable then executes the normal Word document, the batch script, and drops the remaining three files and executes the legitimate signed executable.
If this was the RAT used for the initial infection, then it seems to reinforce the theory that one likely initial infection vector was via spear phishing using a link or an archived file . This is because using an exploit to automatically run this dropper would not make sense as the malware also automatically opens a benign Word document which would arouse suspicion if it opened by itself.
Those remaining three files are actually the three files in what other researchers have dubbed the PlugX Trinity  – a legitimate signed executable, a loader DLL, and a shellcode file.
In this example, while the legitimate signed executable was a file named adobe.exe it was actually an application from ESET. However, the attacker uses DLL side loading, and this “adobe.exe” file tries to load MSVCR110.dll which is a legitimate system DLL. But because of the way the DLL search order works, the system tries to find MSVCR110.dll from the directory from which the application loaded first, thus loading the attacker’s version of MSVCR110.dll.
MSVCR110.dll is a tiny dll made up of exported functions which the real MSVCR110.dll should have. These external functions simply jump to the MSVCR90.dll when called, except for the “__crtGetShowWindowMode” function which calls the malicious function. The malicious function will proceed to read the MSVCR110.dat shellcode file into memory and decompress the buffer using RtlDecompressBuffer under the COMPRESSION_FORMAT_LZNT1 scheme, a method seen since early days of the PlugX RAT , and further unpack the shellcode. Throughout the unpacking process, it makes use of its Process Environment Block (PEB) to parse the PEB_LDR_DATA structure for getting addresses of functions and libraries it wants to use.
When starting, this malware uses the Global mutex named “eeclnt”. It will run another copy of itself with the arguments “258”, and this copy will run %windir%\system32\msiexec.exe as it disables WOW64 redirection.
The created msiexec.exe will be started with the flags 0x434 which among other things starts the process in a suspended mode and command line arguments “259”, then performs process injection so that the malware is running as msiexec.exe.
In order to persist on a system, the malware makes use of %APPDATA%\Windows folder, setting the folder attributes to HIDDEN | SYSTEM and moving MSVCR110.dll, MSVCR110.dat, and eeclnt.exe (renamed from adobe.exe) there. It stores this new location of the shellcode file (MSVCR110.dat) in an environment variable “%UI00%” and the location of the DLL file (MSVCR110.dll) in an environment variable “%UI01%”.
There are two persistence mechanisms it makes use of:
- Service with service name and display name set to “WanServer”, which starts %APPDATA%\Windows\eeclnt.exe with the command line arguments “260”. The service description used is “Network for this computer. If this service is stopped, these functions will be unavailable.”, which is a generic sounding but unique description for this malicious service.
- If the service failed to be created, most likely due to insufficient privileges, then the malware would make use of the standard run registry key located at HKCU\Software\Microsoft\Windows\CurrentVersion\Run with key “eeclnt” and value %APPDATA%\Windows\eeclnt.exe with the command line arguments “260”.
|NULL||Re-run with arguments “258” and continue|
|“258” / “260”||Run %windir%\system32\msiexec.exe with arguments “259” or “261” respectively in suspended mode and inject itself into it|
|“259”||Create persistence via service / run registry key and run itself as “eeclnt.exe” with arguments “260”|
|“261”||Run normally, including C2 communications.|
The malware beacons using a legitimate HTTPS POST on port 443 to “/login.asp?id=%d” where %d is the victim identifier using the user-agent “User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.0)” via WinINet.dll’s HttpSendRequestA. If the configuration uses a different port, then the request is done via HTTP.
The malware manually sets inline hooks on SspiCli.dll’s AcquireCredentialsHandleA function if running on Windows 10. AcquireCredentialsHandleA is actually a function normally called from secur32.dll, which then forwards the API call to SspiCli.dll. Before performing the actual function, the inline hook will use the process token from explorer.exe and perform ImpersonateLoggedOnUser() with that token, which is a trick we are seeing for the first time and seems to be for UAC bypass.
The malware also manually sets inline hooks on WSs2_32.dll’s closesocket and shutdown functions. Before performing the closesocket function, the inline hook will perform “setsockopt(socket, SOL_SOCKET, SO_DONTLINGER, 0, 4)” and on shutdown, the inline hook will simply return from the function instead.
The malware mainly collects the following information from the system automatically:
- Major, minor, and build OS versions
- NetBIOS Name
- MAC Address
- Logged on user name
Other PlugX Capabilities
Similar to previous PlugX variants , this version zeroes out its entire PE header (without that false “XV” header), together with other certain other PE sections we presume the attacker did not want others to see.
Finally, besides this technical analysis, it is important to remember that PlugX in general has reverse shell capabilities and typically has additional modules which might be either decrypted or downloaded as shellcode .
While we cannot be sure of the SectorM04’s motives, healthcare data is information that has a lot of potential for intelligence gathering with the most obvious being used for blackmail. They have shown their willingness, ability, and patience to compromise their targets, of which Singapore appears to be one of the bigger ones. As is the case for many nation state threat actor groups, it is important to remember that cyber is only one part of an intelligence operation.
Indicators of Compromise
PlugX Trinity Hashes (SHA-256)
PlugX RAT Full Dropper
PlugX Trinity – Legitimate signed executables
PlugX Trinity – Malicious DLLs which are used to abuse search order
PlugX Trinity – Shellcode files
Other Hashes (SHA-256)
Another RAT Used