I was recently talking to a friend, who wanted to find out what types of malware target his country of living, japan. We read the Japan Threat Report by Check Point cyberint, which contained a part about APT10 which was intriguing to me. To cite the quick rundown on APT10:
"[...] Operating since 2006, APT10 is a cyberespionage group affiliated with the Chinese government, potentially
linked to the Chinese Ministry of State Security (MSS). In 2018, the group gained notoriety for infiltrating and
pilfering trade secrets and technologies from at least 12 countries. Various security agencies refer to APT10
using different monikers such as MenuPass (FireEye), Stone Panda (CrowdStrike), APT10 (Mandiant), and
POTASSIUM (Microsoft) [...]"
"Loaders like HUI Loader, Ecipekac, FYAnti, and trojans like Impacket.AI and ChChes are also part of their arsenal."
I like looking at "APT" malware, so I quickly analyzed two HUI loader samples (see IOCs below). The first sample turned out to be a bit disappointing since it was so simple, but it uses techniques, which are still used today and are still effective, although the sample is from 2021 (if you trust the compiler timestamp).
First Sample
The compiler timestamp of the first sample (Sha256 `2317...`) shows Fri Dec 24 08:08:56 2021, so if that is not spoofed, it is a rather old piece of malware & it also does not appear to be packed. Examining the exports, it looks like a DLL sideloading payload for libvlc.dll
:

Looking at the exports in IDA, libvlc_new
seems to hold the main logic. It starts by calling into the following function, which resolves the payload from a config file vlc.cnf
. This is a common technique: decoupling the payload from the malware makes analysis harder, defeats sandboxes that only run the main binary and reduces entropy:

The malware immediately establishes persistence via a service called MapServer
, masquerading as an Xbox Live related service:

The service main spawns a new thread:

This thread contains the main injection logic. It starts by decrypting the config file:

It then spawns svchost.exe
in suspended state and writes the decrypted payload into it, to then start a remote thread on the payload, which is likely shellcode:

The remote thread is, depending on the OS version, created via CreateRemoteThread
or NtCreateThreadEx
:

Besides that, the malware contains a lot of garbage code, which is likely a simple means of obfuscation, and also helps to combat machine learning models, by adding benign code:

Essentially, this HUI Loader sample is a classic remote injection DLL sideloading payload. Interestingly, the sample did not show any anti-analysis capabilities, obfuscation or anti-debug.
I then found this .csv file by JPCERTCC, which lists services, dll names and payload file names, among other characteristics, for different samples of HUI loader - some dating back up to 2015. One of these samples also patches AMSI and ETW, which I had a look at next:
Second Sample
The second sample is much more sophisticated, but similar in nature. It shows a compiler timestamp of just 5 hours later (Fri Dec 24 13:28:27 2021) masquerades as glib
instead of libvnc
and uses vmware.ini
as the payload file. Additionally, it does not employ any sort of persistence mechanism.
This time, some basic anti-debugging is included, by checking the BeingDebugged
and NtGlobal
Flag of the PEB
. NtGlobalFlag
is set, if the process was created under a debugger:

The sample also does unhooking of every DLL that is loaded, by first loading it reflectively and then copying over the sections. I am not exactly sure why they do not just copy over the .text
section but do all this reflective loading shenanigans... maybe to evade hooks other than .text
section based hooks (e.g. .idata
).

The reflective loader:

The unhooking unhooks all sections, except .text
of clr.dll
:

clr.dll
is excluded in both the unhooking and reflective loading part, although it is not loaded anyway - this indicated that the code is copy-paste from another project or loader that might have the CLR loaded (and in the case of unhooking, is a safety check):

Additionally, this sample patches AMSI and ETW, by replacing the first byte of both AmsiScanBuffer
and EtwEventWrite
with a ret
(0xC3
) opcode:

Finally, the shellcode is invoked in the same process using a function pointer cast. This is a technique that avoids thread creation, and as such also bypasses thread creation kernel callbacks - a technique effective against EDRs that rely on those callbacks.

To summarize, while both samples share similarities, the first sample is much simpler. This second sample employs more modern evasion techniques such as anti-debugging, AMSI and ETW bytepatches, unhooking and direct pointer execution. To be honest, it looks a lot different from most loaders, since it employs almost zero obfuscation, making it look more like basic red team malware. However, both payloads would likely still perform not too bad against many modern EDRs and reversing them was a fun exercise.
IOCs
SHA256 first sample: 2317d3e14ab214f06ae38a729524646971e21b398eda15cc9deb8b00b231abc3
SHA256 second sample: 9d898173dbdbb4886d9b73e16635a85ffed53b3c83860dad028c5e0dcabb06c5
mapserver (Service Name)