o88                         ooooooo     ooooooo
 oooooooo8 oooo   oooo ooooooooo8 oo oooooo    oooooooo8 oooo  oo oooooo    ooooooo o88    888o o88    888o
888oooooo8   888   888 888oooooo8   888    888 888ooooooo  888   888   888 888     888   88888o      88888o
888           888 888  888          888                888 888   888   888 888       88o    o888 88o    o888
  88oooo888     888      88oooo888 o888o       88oooooo88 o888o o888o o888o  88ooo888  88ooo88     88ooo88

---

10/13/2024

---

Analyzing HUI Loader

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 NtGlobalFlag 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)
---

back to top

helloskiddie.club <3