Formbook's Five-Layer Matryoshka: A JavaScript Dropper With GUID-Encoded Process Hollowing, Rotational XOR, and a Bulletproof Hosting Problem
TL;DR: A 2MB JavaScript file named "Purchase Order.js" arrived via email targeting organizations in Germany on March 10, 2026. Beneath the filename is a five-stage payload chain that nests like a Russian matryoshka doll: an obfuscated JavaScript dropper with a 957-entry string table decodes a Base64 blob into a PowerShell script, which decrypts itself via rotational XOR with a 32-byte key, which reflectively loads a .NET assembly (DEV.dll) into memory, which process-hollows Aspnet_compiler.exe to inject a fully packed Formbook infostealer. Static analysis alone -- no sandbox, no dynamic execution -- was sufficient to crack the first four layers, yielding two previously unreported binaries: the .NET loader (campaign ID nfkc2gcmGd) and the final Formbook PE. A second variant ("Technical Parameter.js", 3.9MB) dropped the same day from the same reporter confirms an active distribution campaign. The Formbook C2 infrastructure clusters heavily on PEG TECH INC, a US-registered hosting provider whose netblocks keep appearing in Formbook operations with suspicious regularity.
Why Another Formbook Post Matters
Formbook is old. First sold on HackForums in 2016 for $29/week, it has been one of the most persistent commodity infostealers in the threat landscape for a decade. Most security teams have seen thousands of Formbook alerts. Many have stopped looking closely.
That complacency is exactly what this campaign exploits.
The delivery mechanism here is not a recycled macro document or a repackaged executable. It is a custom five-stage obfuscation chain with a novel encryption scheme, a .NET loader that resolves Windows API calls through a GUID lookup table, and a monitoring loop that re-injects the payload every five seconds if the hollowed process dies. The final payload -- a 285KB single-section PE with near-perfect entropy -- is not in MalwareBazaar. Neither is the .NET loader. These are fresh binaries attached to a campaign that was actively distributing multiple variants on the same day this investigation began.
Commodity malware does not mean commodity delivery. The operator behind this campaign invested meaningful effort in evasion engineering while relying on Formbook's proven post-compromise capabilities. Understanding how these layers fit together matters for anyone writing detection rules, triaging email alerts, or hunting for process hollowing in their environment.
The Kill Chain: Five Layers Deep
Before diving into the technical details of each stage, here is the full attack chain as reconstructed through static analysis:
[EMAIL ATTACHMENT]
|
v
[Purchase Order.js] (2MB obfuscated JavaScript, WScript/WSH execution)
| 957-entry string table with hex-indexed lookups (Q(0xNNN) - base 0x1CC)
| ActiveXObject: Scripting.FileSystemObject, WScript.Shell, ADODB.Stream
|
v
[Base64 Decode] (1.95MB Base64 blob --> 1.46MB PowerShell)
|
v
[Stage 1: Rotational XOR Decryption]
| Key: 5c5aaed8b5527186bdb1c23fb8763f9a4aa6a603ce4589b371973c88ce26a943
| Algorithm: XOR with position-dependent rotation (mod 7)
| Output: 1.08MB decrypted PowerShell script
|
v
[Stage 2: .NET Reflective Loading]
| [System.Reflection.Assembly]::Load() of embedded DEV.dll (47KB)
| Entry: DEV.DOWN.SHOOT(Aspnet_compiler_path, Formbook_payload)
| Monitoring loop: re-injects every 5 seconds if target process absent
|
v
[Stage 3: Process Hollowing via GUID-Encoded APIs]
| Target: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Aspnet_compiler.exe
| CreateProcess(SUSPENDED) --> VirtualAllocEx --> WriteProcessMemory
| --> NtUnmapViewOfSection --> SetThreadContext --> ResumeThread
|
v
[Stage 4: Formbook Infostealer] (285KB packed PE, single .text section)
| Credential theft, keylogging, screenshot capture, form grabbing
| HTTP POST to rotating C2 domain infrastructure
|
v
[PERSISTENCE]
+-- Registry: HKCU\...\Run\SystemUpdate_<random>
+-- Registry: HKLM\...\Run\SystemUpdate_<random>
+-- LNK: Startup folder (SystemUpdate_<random>_<timestamp>.lnk)
+-- All execute: powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden
Five layers. Each one designed to defeat a different class of security control. The JavaScript defeats email attachment scanning that keys on PE headers. The Base64 encoding defeats string-matching rules. The rotational XOR defeats automated decryption. The reflective loading defeats disk-based AV scanning. The process hollowing defeats process-based behavioral detection. It is defense-in-depth, but for the attacker.
Layer 1: The JavaScript -- 957 Strings and a Lookup Table
The initial dropper is a single-line JavaScript file weighing in at just over 2MB. No line terminators. No whitespace formatting. Just a continuous stream of obfuscated code.
| Attribute | Value |
|---|---|
| SHA-256 | bade048fe2950223aa3d8d6ba376433e8e8040384a831c04345e657c70f30190 |
| MD5 | bd0f15e17d87804815e6eb1848bb63a0 |
| SHA-1 | 81a0b550da746aed49d55af40c82df95018239f0 |
| Size | 2,003,574 bytes |
| Type | JavaScript (ASCII, single-line) |
| SSDEEP | 24576:aLLuAC/7qkdGYNTMdX7O4tHASPHz9fa+iRHuL3M6puuO92NpcnKLX4h+/k2jA+mR:YLuAkZkOod/zNp1XpkhDZv |
The obfuscation technique is control-flow flattening built on a string table. A function called q() contains a 957-element array of string fragments -- API names, COM object identifiers, command-line arguments, and the payload itself, all chopped into 8-character chunks and scattered across the array. A decoder function Q(offset) resolves strings at runtime by subtracting a base offset of 0x1CC (460 decimal) from the requested index.
Multiple alias functions (ZO, Zg, Zk, T0-T5, B0-B9) all reference the same decoder, creating a tangled web of indirection that makes manual analysis tedious and automated pattern matching unreliable. This is not sophisticated cryptography -- it is the code equivalent of shredding a document and numbering the strips.
When the string table is resolved, the reconstructed operations reveal the full scope of what this JavaScript is doing:
// Reconstructed operations from string table resolution
Scripting.FileSystemObject // File system operations
WScript.Shell // Command execution
ADODB.Stream // Data encoding/handling
MSXML2.DOMDocument // XML processing
// Execution
powershell.exe -ExecutionPolicy Bypass -NoProfile -WindowStyle Hidden -File
pwsh.exe // Alternative PowerShell Core path
// Persistence
RegWrite -> HKCU\Software\Microsoft\Windows\CurrentVersion\Run\
CreateTextFile -> C:\Temp\ // PS1 staging directory
.lnk creation -> Startup // LNK persistence
// Monitoring
winmgmts / SELECT * FROM Win32_Process WHERE Name=
The dropper writes a PowerShell script to C:\Temp\ with a randomized filename (ps_<random>_<timestamp>.ps1), registers persistence through both the Registry Run key and a Startup folder LNK shortcut, then executes the PowerShell with -WindowStyle Hidden to suppress any visible window. The WMI process monitoring query is used later by the .NET loader to check whether the hollowed process is still running.
Two things stand out. First, the dropper writes to C:\Temp\ rather than %TEMP% -- a directory that does not exist by default on Windows. This suggests the PowerShell script that gets executed first creates the directory, or the dropper itself creates it via the FileSystemObject. Second, the dual persistence (Registry + Startup LNK) is redundant by design. If an EDR product cleans one, the other survives.
Layer 2: The Rotational XOR -- Custom Crypto That Resists Frequency Analysis
Buried at index 266 in the string table is the real payload: a 1,949,248-character Base64 blob that decodes to a 1,461,935-byte PowerShell script. The script identifies itself internally as a "Multi-Stage Rotational XOR Decryption Framework" and contains five components:
$securecontainer-- 22,449 lines of Base64-encoded encrypted data (1,077,357 bytes when decoded)$encryptionrotational-- The 32-byte XOR key, itself Base64-encoded:XFqu2LVScYa9scI/uHY/mkqmpgPORYmzcZc8iM4mqUM=$xorrotational-- The decryption function$masterdecoder-- Orchestration: decode Base64, then apply the XOR$executionhandler-- Execution with three fallback methods
The XOR key in hex: 5c5aaed8b5527186bdb1c23fb8763f9a4aa6a603ce4589b371973c88ce26a943
The encryption is the same scheme we documented in the SnakeKeylogger investigation published today -- a rotational XOR cipher with a non-linear key schedule:
for each byte at position i:
key_position = (i + rotation_tracker) % key_length
plaintext[i] = ciphertext[i] XOR key[key_position]
rotation_tracker = (rotation_tracker + key[key_position]) % 7
The rotation_tracker variable creates a feedback loop: after each byte is decrypted, the tracker advances by the value of the key byte at the current position, modulo 7. This means the effective key offset at position N depends on every key byte used before it. Standard XOR frequency analysis -- which assumes a repeating key -- fails because the key never actually repeats in the same pattern.
This is the second time we have seen this exact scheme in a single day of investigation. The SnakeKeylogger PS1 dropper analyzed this morning uses an identical algorithm with a different key. Both use DEV.dll as the .NET loader name. Both use DEV.DOWN.SHOOT as the entry point. Both target Aspnet_compiler.exe for process hollowing. The shared tooling strongly suggests a common builder or shared infrastructure in the dropper supply chain -- likely a crypter-as-a-service that multiple operators purchase access to.
The execution handler is worth noting for its resilience. It tries three different methods to run the decrypted payload:
Invoke-Expression(standard)- Scriptblock invocation (alternative)
[ScriptBlock]::Create().Invoke()(fallback)
If the first method is blocked by a constrained PowerShell environment or a security product hooking Invoke-Expression, the script automatically falls through to the next method. This is not sophisticated, but it is thorough.
Layer 3: DEV.dll -- Process Hollowing Through a GUID Phone Book
The decrypted PowerShell payload contains two embedded binaries as byte arrays. The first is a 47KB .NET DLL that gets loaded reflectively via [System.Reflection.Assembly]::Load(). The second is the Formbook payload that the DLL will inject.
| Attribute | Value |
|---|---|
| SHA-256 | 64f72b92ba056fec73ba30912a0a92d03d223d8cce9de56149cbd10f80ed80e4 |
| MD5 | 0156574aac3f1b138634f78fd2472cf6 |
| SHA-1 | 799048e37ae217b6e3d2dbcb064c6f867c5de4f0 |
| Size | 47,104 bytes |
| Type | PE32 DLL (.NET Framework 4.5.1) |
| PDB | DEV.pdb |
| Copyright | 2026 |
| Compile Timestamp | 2093-10-06T15:05:52Z (spoofed -- 67 years in the future) |
| Campaign ID | nfkc2gcmGd |
| Module GUID | {68D09C70-25FA-4299-AF81-22A8F8CB699B} |
The compile timestamp of 2093 is a common anti-analysis technique: timestomping the PE header to a future date breaks automated tooling that uses compilation timestamps for clustering or timeline analysis. More useful for tracking is the campaign identifier nfkc2gcmGd embedded in the assembly, which can serve as a pivot point for correlating other samples from the same distribution campaign.
The most technically interesting feature of DEV.dll is how it resolves the Windows API calls needed for process hollowing. Instead of importing them directly (which would be trivially detectable in an import table scan) or using standard GetProcAddress dynamic resolution (which every EDR product hooks), the loader maps API functions through a GUID lookup table:
| GUID | Resolved API | Purpose |
|---|---|---|
{11111-22222-10009-11112} | CreateProcessA | Create the target process in suspended state |
{11111-22222-20001-00001} | VirtualAllocEx | Allocate memory in target process |
{11111-22222-20001-00002} | WriteProcessMemory | Write payload bytes into allocated memory |
{11111-22222-30001-00001} | GetThreadContext | Retrieve thread state for redirection |
{11111-22222-30001-00002} | SetThreadContext | Redirect execution to injected payload |
{11111-22222-40001-00001} | NtUnmapViewOfSection | Hollow out the original image |
{11111-22222-40001-00002} | ResumeThread | Resume execution of the hollowed process |
{11111-22222-50001-00000} | GetDelegateForFunctionPointer | Dynamic API marshalling |
{11111-22222-50001-00001} | VirtualProtectEx | Change memory protections |
{11111-22222-50001-00002} | ReadProcessMemory | Read from target process memory |
The GUID format follows a consistent pattern -- the first two segments are always 11111-22222, with the remaining segments encoding which API function to resolve. This is not standard Windows GUID usage. It is a custom dispatch table that maps arbitrary identifiers to API function pointers at runtime using GetDelegateForFunctionPointer. The effect is that the binary's string table and import table contain no references to the actual API names being called. A static analysis tool looking for CreateProcessA or WriteProcessMemory in the binary's strings will find nothing.
The injection sequence follows the classic process hollowing pattern:
CreateProcessAlaunchesAspnet_compiler.exeinCREATE_SUSPENDEDstateNtUnmapViewOfSectionunmaps the original executable image from the processVirtualAllocExallocates new memory at the preferred base addressWriteProcessMemorycopies the Formbook payload into the allocated spaceSetThreadContextmodifies the thread's instruction pointer to the payload entry pointResumeThreadlets the process run -- now executing Formbook instead of Aspnet_compiler
The target process -- C:\Windows\Microsoft.NET\Framework\v4.0.30319\Aspnet_compiler.exe -- is a legitimate Microsoft binary used for precompiling ASP.NET applications. To a process listing, it looks like a normal .NET Framework tool. To an EDR product that trusts processes running from the Framework directory, it looks benign. The choice is deliberate: Aspnet_compiler rarely runs on workstations, so its presence is unusual but not alarming enough to trigger automated responses in most environments.
The monitoring loop adds a persistence layer beyond the Registry and Startup folder mechanisms. The PowerShell script checks every 5 seconds (via Start-Sleep) whether the hollowed Aspnet_compiler.exe process is still running. If it has been killed -- by an EDR product, by a user, by a crash -- the script re-injects the payload. This creates a resilient execution loop: you cannot just terminate the hollowed process and walk away. You have to kill both the hollowed process and the monitoring PowerShell to actually stop the malware.
The DLL also imports cryptographic capabilities: AesCryptoServiceProvider, RSACryptoServiceProvider, MD5CryptoServiceProvider, and RijndaelManaged. These are used for decrypting configuration data from an embedded resource (aR3nbf8dQp2feLmk31.lSfgApatkdxsVcGcrktoFd.resources). The obfuscated namespace (iEOwMbVOWMg6jFXihv.3eSDovBwXZZ5f2tEBw) contains the actual injection logic.
Layer 4: The Formbook Payload -- A Black Box With a Known Fingerprint
The final payload is a 285KB PE32 executable packed into a single .text section with near-100% byte entropy.
| Attribute | Value |
|---|---|
| SHA-256 | 0d7e7746b07d934dc222aab6af170e9c8f69f09eea2159d5f7c7d371ebcbdb43 |
| MD5 | 27ba27853c240b277490d9db3f9b3ad7 |
| SHA-1 | 7107aabb716118c3ff4ff47100334e9e225df52d |
| Size | 285,696 bytes |
| Sections | 1 (.text only) |
| Compile Timestamp | 2017-04-20T06:23:00Z (forged) |
| Rich Header XOR Key | 0xa57d119d |
The compile timestamp of April 20, 2017 is a known Formbook fingerprint. It appears across hundreds of Formbook samples spanning years of campaigns -- a hardcoded value in the builder rather than an actual compilation date. The Rich Header XOR key provides another pivot for sample clustering.
This is where static analysis hits a wall. Formbook v4.x uses multiple runtime encryption layers to protect its C2 configuration, exfiltration paths, and encryption keys. The .text section is entirely packed ciphertext that only resolves in memory during execution. The C2 domains, the campaign configuration, the credential theft targets -- none of these are extractable without running the binary in a sandbox or manually unpacking it in a debugger.
What we can say from the packing characteristics: single-section PE with maximum entropy is Formbook's calling card. The binary is not in MalwareBazaar as of investigation time, meaning this is a previously unreported payload hash. The dropper chain was generating fresh payloads for this campaign.
Sandbox Confirmation: Hatching Triage Agrees
Dynamic analysis via Hatching Triage confirms the static analysis findings with a perfect 10/10 maliciousness score.
| Artifact | Value |
|---|---|
| Report | 260310-l4nkjsat4k |
| Score | 10/10 (Formbook confirmed) |
| Dropped PS1 (run 1) | C:\Temp\ps_Pwk1cco2psK8_1773137130942.ps1 |
| Dropped PS1 (run 2) | C:\Temp\ps_isi2EfbMOj2A_1773137126129.ps1 |
| Startup LNK | SystemUpdate_<id>_<timestamp>.lnk |
| Registry Run (HKCU) | HKCU\...\CurrentVersion\Run\SystemUpdate_<id>_<timestamp> |
| Registry Run (HKLM) | HKLM\...\CurrentVersion\Run\SystemUpdate_<id>_<timestamp> |
| Injection target | Aspnet_compiler.exe (confirmed) |
| Network C2 | Not captured |
The absence of C2 network traffic is notable. Formbook is known for implementing geo-fencing and sandbox detection that can suppress C2 communication in analysis environments. The payload likely fingerprinted the Triage sandbox and refused to phone home -- a behavior that paradoxically makes the sandbox confirmation more reliable, since sandbox-aware behavior is itself a strong maliciousness signal.
The two sandbox runs produced different PS1 filenames but identical behavior, confirming the randomization built into the dropper. Each execution generates a unique filename incorporating a random string and a Unix timestamp.
Same Day, Same Campaign: The Second Variant
This sample did not arrive alone. A second JavaScript dropper from the same MalwareBazaar reporter (lowmal3) was uploaded the same day, just two hours earlier:
| Sample | SHA-256 | File Name | Size | Reporter | First Seen |
|---|---|---|---|---|---|
| Primary | bade048f... | Purchase Order.js | 2.0MB | lowmal3 | 2026-03-10 10:04 |
| Variant | 172d478c... | Technical Parameter.js | 3.9MB | lowmal3 | 2026-03-10 07:47 |
| Related | a4e993... | AWB_2026031000.zip | 1.1MB | pr0xylife | 2026-03-10 09:47 |
| Related | fdfac8... | 2026-os arajanlatkeres.bat | -- | smica83 | 2026-03-10 08:00 |
All four samples are Formbook, all delivered via email attachment on March 10, 2026. The filenames tell a story about the targeting strategy:
- "Purchase Order.js" -- standard business email compromise lure
- "Technical Parameter.js" -- engineering/procurement context
- "AWB_2026031000.zip" -- airway bill (shipping/logistics targeting)
- "2026-os arajanlatkeres.bat" -- Hungarian language ("price request"), Central European targeting
The second JS variant at 3.9MB is nearly double the size of the primary sample, suggesting either additional payload layers or more aggressive padding to evade size-based email scanning rules. The diversity of file formats (JS, ZIP, BAT) and languages (English, Hungarian) across the four samples indicates a campaign with multiple distribution channels targeting different geographies and industry verticals simultaneously.
C2 Infrastructure: PEG TECH INC and the Bulletproof Hosting Question
The Formbook C2 infrastructure mapped through ThreatFox reveals a pattern that goes beyond this single campaign.
Active C2 Domains (Resolving at Investigation Time)
| Domain | IP | ASN / Provider | Status |
|---|---|---|---|
| www[.]yakutianguide[.]ru | 176.57.66.176 | AS57724 / Tilda Publishing (RU) | LIVE |
| www[.]xfqjrms[.]bond | 104.233.223.161 | PEG TECH INC (US) | LIVE |
| www[.]wzsw5[.]shop | 198.200.45.122 | PEG TECH INC (US) | LIVE |
| www[.]thkifry[.]bond | 104.233.223.165 | PEG TECH INC (US) | LIVE |
| www[.]studyvibez[.]site | 198.54.117.242 | Unknown (US) | LIVE |
Three of five live C2 domains resolve to PEG TECH INC IP space. That is not coincidence.
PEG TECH INC (ARIN handles: PT-82-5, PT-82-6) operates at least two netblocks that consistently appear in Formbook C2 infrastructure:
104.233.128.0/17-- nginx on port 80198.200.32.0/19-- nginx on ports 80 and 888
These are /17 and /19 allocations -- 32,768 and 8,192 IPs respectively. The nginx configuration across the blocks, combined with the repeated appearance of these ranges in Formbook C2 mapping, raises serious questions. Either PEG TECH INC has a significant abuse problem that it is failing to address, or its infrastructure is being deliberately provisioned for malware operations. In the threat intelligence community, that pattern has a name: bulletproof hosting.
The outlier in the infrastructure is www[.]yakutianguide[.]ru, hosted on Tilda Publishing (AS57724) in Russia. Tilda is a legitimate website builder platform -- think Squarespace for the Russian market. The domain name ("Yakutian guide") suggests this was once a legitimate tourism or regional information website that has been compromised and repurposed as a C2 front. Compromised legitimate websites are a standard Formbook infrastructure technique: they provide trusted domain reputation, valid TLS certificates, and hosting that will not be taken down by an abuse report because the underlying account belongs to an unaware legitimate customer.
Three additional C2 domains were identified but were not resolving at investigation time:
| Domain | Context |
|---|---|
| www[.]xeoc[.]shop | Formbook C2 (ThreatFox) |
| www[.]xtmmm[.]top | Formbook C2 (ThreatFox) |
| www[.]spjpantp[.]top | Formbook C2 (ThreatFox) |
The use of .bond, .shop, and .top TLDs across the C2 domains is characteristic of Formbook operations. These TLDs offer cheap registration (often under $1), minimal verification, and high volumes of legitimate traffic that make blanket blocking impractical. The short, random-looking domain names (xfqjrms, wzsw5, thkifry) are generated rather than manually chosen -- consistent with an automated domain registration workflow.
What Was Found vs. What Was Known
The investigation yielded three artifacts at different stages of public knowledge:
Previously Unreported:
DEV.dll(.NET loader) -- SHA-25664f72b92...-- not in MalwareBazaar, VirusTotal, or any public malware repository at investigation time- Formbook packed payload -- SHA-256
0d7e7746...-- not in MalwareBazaar - Campaign identifier
nfkc2gcmGd-- not previously associated with any public Formbook campaign tracking - GUID-encoded API resolution table -- this specific technique variant has not been publicly documented for Formbook delivery chains
Known but Newly Correlated:
- The JavaScript dropper (
bade048f...) was in MalwareBazaar but had not been fully deobfuscated or linked to specific extracted payloads - The rotational XOR scheme matches the SnakeKeylogger dropper analyzed the same day, suggesting a shared crypter service
- PEG TECH INC netblocks are known to the abuse community but remain active, indicating insufficient takedown pressure
Shared Tooling Signal:
The DEV.dll loader with DEV.DOWN.SHOOT entry point, the rotational XOR with mod-7 feedback, and the Aspnet_compiler.exe hollowing target all appeared in today's SnakeKeylogger investigation as well. This strongly suggests a shared builder or crypter-as-a-service that is being used by multiple operators delivering different final payloads. The crypter developer appears more skilled than the malware operators purchasing access -- a common dynamic in the cybercrime ecosystem where tooling developers occupy a higher tier than the campaign operators who use their products.
Detection Engineering
Vendor Coverage (as of 2026-03-10)
Detection coverage at the time of discovery was thin:
| Vendor | Detection | Notes |
|---|---|---|
| Kaspersky | Trojan-Spy.Win32.Noon.sb, Trojan-Dropper.Win32.Injector.sb, HEUR:Trojan-Downloader.Script.Generic | 12 detections across layers |
| ReversingLabs | Script-JS.Backdoor.FormBook | 8/36 scanners |
| Hatching Triage | Formbook | 10/10 score |
| Spamhaus HBL | Suspicious | Hash-based |
| FileScan.IO | LIKELY_MALICIOUS | Confidence 1.0 |
8 out of 36 scanners on ReversingLabs means roughly 78% of antivirus products would have missed this dropper at the time of submission. The five-stage obfuscation chain is doing its job.
Behavioral Detection Opportunities
The strongest detection signals are behavioral, not signature-based:
Process Ancestry Anomalies:
wscript.exe --> powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden
--> Aspnet_compiler.exe (with no ASP.NET compilation context)
Aspnet_compiler.exe should almost never run on a standard workstation. When it does, it should be invoked by Visual Studio, MSBuild, or an IIS deployment pipeline -- not by PowerShell running with -WindowStyle Hidden. Any EDR product that tracks process parent-child relationships can flag this with high confidence.
File System Artifacts:
C:\Temp\ps_*_*.ps1 # Randomized PS1 staging
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\SystemUpdate_*.lnk # Startup persistence
Registry Indicators:
HKCU\Software\Microsoft\Windows\CurrentVersion\Run\SystemUpdate_*
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\SystemUpdate_*
The SystemUpdate_ prefix in both the registry keys and the LNK files is a consistent fingerprint across sandbox runs. It is specific enough to detect with low false positives -- legitimate Windows Update does not create SystemUpdate_ prefixed Run keys.
PowerShell Script Block Logging:
If Script Block Logging is enabled (and it should be), the rotational XOR decryption framework will appear in the logs with its characteristic variable names: $securecontainer, $encryptionrotational, $xorrotational, $masterdecoder, $executionhandler. These are distinctive enough for reliable detection rules.
Network-Level Detection
Block the following at the network perimeter (firewall, proxy, DNS sinkhole):
PEG TECH INC ranges (aggressive but justified):
104.233.128.0/17
198.200.32.0/19
Blocking entire /17 and /19 ranges is aggressive. But if your organization has no legitimate business reason to communicate with PEG TECH INC infrastructure, the false positive risk is low and the coverage against current and future Formbook C2 rotation within these blocks is high. Evaluate against your own traffic baseline before implementing.
MITRE ATT&CK Mapping
| Tactic | Technique | ID | Implementation |
|---|---|---|---|
| Initial Access | Spearphishing Attachment | T1566.001 | "Purchase Order.js" email lure |
| Execution | JavaScript | T1059.007 | WScript/WSH executes obfuscated JS dropper |
| Execution | PowerShell | T1059.001 | Hidden PowerShell with -ExecutionPolicy Bypass |
| Persistence | Registry Run Keys / Startup Folder | T1547.001 | HKCU + HKLM Run keys + Startup LNK |
| Defense Evasion | Obfuscated Files or Information | T1027 | 957-entry string table, hex-indexed lookups |
| Defense Evasion | Deobfuscate/Decode Files | T1140 | Base64 --> Rotational XOR --> .NET reflective load |
| Defense Evasion | Process Hollowing | T1055.012 | DEV.dll hollows Aspnet_compiler.exe via GUID APIs |
| Defense Evasion | Masquerading | T1036.005 | Uses legitimate .NET Framework binary |
| Discovery | Process Discovery | T1057 | WMI: SELECT * FROM Win32_Process |
| Discovery | System Information Discovery | T1082 | Physical storage device enumeration |
| Discovery | System Location Discovery | T1614.001 | System language detection |
| Collection | Keylogging | T1056.001 | Formbook keylogger capability |
| Collection | Screen Capture | T1113 | Formbook screenshot module |
| Credential Access | Credentials from Password Stores | T1555 | Formbook credential theft |
| Exfiltration | Exfiltration Over C2 Channel | T1041 | HTTP POST to rotating C2 domains |
Indicators of Compromise
File Indicators
# JavaScript Dropper (Primary)
SHA256: bade048fe2950223aa3d8d6ba376433e8e8040384a831c04345e657c70f30190
MD5: bd0f15e17d87804815e6eb1848bb63a0
SHA1: 81a0b550da746aed49d55af40c82df95018239f0
# JavaScript Dropper (Variant)
SHA256: 172d478c04c29843e4f5372957380e4d1ff043bbc4e0058c885fd8ea5b45466f
# DEV.dll (.NET Loader) -- PREVIOUSLY UNREPORTED
SHA256: 64f72b92ba056fec73ba30912a0a92d03d223d8cce9de56149cbd10f80ed80e4
MD5: 0156574aac3f1b138634f78fd2472cf6
SHA1: 799048e37ae217b6e3d2dbcb064c6f867c5de4f0
# Formbook Packed Payload -- PREVIOUSLY UNREPORTED
SHA256: 0d7e7746b07d934dc222aab6af170e9c8f69f09eea2159d5f7c7d371ebcbdb43
MD5: 27ba27853c240b277490d9db3f9b3ad7
SHA1: 7107aabb716118c3ff4ff47100334e9e225df52d
Network Indicators (Defanged)
# Formbook C2 Domains
www[.]yakutianguide[.]ru # Tilda Publishing (RU) -- likely compromised
www[.]xfqjrms[.]bond # PEG TECH INC (US)
www[.]wzsw5[.]shop # PEG TECH INC (US)
www[.]thkifry[.]bond # PEG TECH INC (US)
www[.]studyvibez[.]site # US hosting
www[.]xeoc[.]shop # Formbook C2
www[.]xtmmm[.]top # Formbook C2
www[.]spjpantp[.]top # Formbook C2
# C2 IP Addresses
104[.]233[.]223[.]161 # PEG TECH INC
198[.]200[.]45[.]122 # PEG TECH INC
104[.]233[.]223[.]165 # PEG TECH INC
176[.]57[.]66[.]176 # Tilda Publishing (RU)
198[.]54[.]117[.]242 # US hosting
# Hosting Netblocks (PEG TECH INC)
104.233.128.0/17
198.200.32.0/19
Behavioral Indicators
# Campaign identifier
nfkc2gcmGd # DEV.dll campaign ID / mutex
# File system artifacts
C:\Temp\ps_<random>_<timestamp>.ps1 # Staged PowerShell dropper
# Registry persistence
HKCU\Software\Microsoft\Windows\CurrentVersion\Run\SystemUpdate_<random>
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\SystemUpdate_<random>
# Startup persistence
SystemUpdate_<random>_<timestamp>.lnk
# Process hollowing target
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Aspnet_compiler.exe
# PowerShell execution arguments
-ExecutionPolicy Bypass -WindowStyle Hidden -File
# Encryption artifacts
XOR Key: 5c5aaed8b5527186bdb1c23fb8763f9a4aa6a603ce4589b371973c88ce26a943
.NET Module GUID: {68D09C70-25FA-4299-AF81-22A8F8CB699B}
.NET PDB GUID: 29529e96-eec4-46f1-9872-5e147db2e821
Obfuscated class: iEOwMbVOWMg6jFXihv.3eSDovBwXZZ5f2tEBw
Recommended Actions
Immediate (24-48 hours)
- Block all file hashes listed above at the endpoint level (EDR/AV hash blocklists)
- Block all C2 domains and IPs at the network perimeter (firewall, proxy, DNS sinkhole)
- Hunt for the
nfkc2gcmGdmutex andSystemUpdate_Run key entries across the endpoint estate - Search for
C:\Temp\ps_*.ps1files -- this directory and naming pattern are highly specific - Alert on
Aspnet_compiler.exerunning withpowershell.exeas a parent process
Short-term (1-2 weeks)
- Deploy YARA rules targeting the DEV.dll module GUID and the obfuscated class namespace
- Block PEG TECH INC ranges (
104.233.128.0/17,198.200.32.0/19) if no legitimate business traffic exists - Monitor email gateway logs for
.jsattachments exceeding 500KB with purchase-order or invoice social engineering themes - Review email logs specifically for delivery of "Purchase Order.js" or "Technical Parameter.js"
Medium-term (1-3 months)
- Implement application whitelisting to prevent WScript/cscript execution of untrusted JavaScript files
- Enable PowerShell Constrained Language Mode and Script Block Logging across all endpoints
- Monitor .NET Framework tool execution (
Aspnet_compiler.exe,MSBuild.exe,InstallUtil.exe,RegAsm.exe) for anomalous parent processes - Deploy Suricata/Snort rules for Formbook HTTP POST exfiltration patterns
References
- MalwareBazaar: bade048f...
- Hatching Triage: 260310-l4nkjsat4k
- Malpedia: Formbook
- ThreatFox: Formbook IOCs
Published by Breakglass Intelligence. Investigation conducted 2026-03-10. 5 layers deobfuscated. 2 unreported binaries extracted. 1 campaign ID recovered. 3 PEG TECH INC IPs mapped. Zero sandbox required for 80% of the analysis. Classification: TLP:CLEAR