Back to reports
highPhishing

Formbook's Five-Layer Matryoshka: A JavaScript Dropper With GUID-Encoded Process Hollowing, Rotational XOR, and a Bulletproof Hosting Problem

PublishedMarch 12, 2026
phishingsocial-engineeringcredential-theftc2supply-chainexploitaptspearphishing

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.

AttributeValue
SHA-256bade048fe2950223aa3d8d6ba376433e8e8040384a831c04345e657c70f30190
MD5bd0f15e17d87804815e6eb1848bb63a0
SHA-181a0b550da746aed49d55af40c82df95018239f0
Size2,003,574 bytes
TypeJavaScript (ASCII, single-line)
SSDEEP24576: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:

  1. $securecontainer -- 22,449 lines of Base64-encoded encrypted data (1,077,357 bytes when decoded)
  2. $encryptionrotational -- The 32-byte XOR key, itself Base64-encoded: XFqu2LVScYa9scI/uHY/mkqmpgPORYmzcZc8iM4mqUM=
  3. $xorrotational -- The decryption function
  4. $masterdecoder -- Orchestration: decode Base64, then apply the XOR
  5. $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:

  1. Invoke-Expression (standard)
  2. Scriptblock invocation (alternative)
  3. [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.

AttributeValue
SHA-25664f72b92ba056fec73ba30912a0a92d03d223d8cce9de56149cbd10f80ed80e4
MD50156574aac3f1b138634f78fd2472cf6
SHA-1799048e37ae217b6e3d2dbcb064c6f867c5de4f0
Size47,104 bytes
TypePE32 DLL (.NET Framework 4.5.1)
PDBDEV.pdb
Copyright2026
Compile Timestamp2093-10-06T15:05:52Z (spoofed -- 67 years in the future)
Campaign IDnfkc2gcmGd
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:

GUIDResolved APIPurpose
{11111-22222-10009-11112}CreateProcessACreate the target process in suspended state
{11111-22222-20001-00001}VirtualAllocExAllocate memory in target process
{11111-22222-20001-00002}WriteProcessMemoryWrite payload bytes into allocated memory
{11111-22222-30001-00001}GetThreadContextRetrieve thread state for redirection
{11111-22222-30001-00002}SetThreadContextRedirect execution to injected payload
{11111-22222-40001-00001}NtUnmapViewOfSectionHollow out the original image
{11111-22222-40001-00002}ResumeThreadResume execution of the hollowed process
{11111-22222-50001-00000}GetDelegateForFunctionPointerDynamic API marshalling
{11111-22222-50001-00001}VirtualProtectExChange memory protections
{11111-22222-50001-00002}ReadProcessMemoryRead 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:

  1. CreateProcessA launches Aspnet_compiler.exe in CREATE_SUSPENDED state
  2. NtUnmapViewOfSection unmaps the original executable image from the process
  3. VirtualAllocEx allocates new memory at the preferred base address
  4. WriteProcessMemory copies the Formbook payload into the allocated space
  5. SetThreadContext modifies the thread's instruction pointer to the payload entry point
  6. ResumeThread lets 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.

AttributeValue
SHA-2560d7e7746b07d934dc222aab6af170e9c8f69f09eea2159d5f7c7d371ebcbdb43
MD527ba27853c240b277490d9db3f9b3ad7
SHA-17107aabb716118c3ff4ff47100334e9e225df52d
Size285,696 bytes
Sections1 (.text only)
Compile Timestamp2017-04-20T06:23:00Z (forged)
Rich Header XOR Key0xa57d119d

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.

ArtifactValue
Report260310-l4nkjsat4k
Score10/10 (Formbook confirmed)
Dropped PS1 (run 1)C:\Temp\ps_Pwk1cco2psK8_1773137130942.ps1
Dropped PS1 (run 2)C:\Temp\ps_isi2EfbMOj2A_1773137126129.ps1
Startup LNKSystemUpdate_<id>_<timestamp>.lnk
Registry Run (HKCU)HKCU\...\CurrentVersion\Run\SystemUpdate_<id>_<timestamp>
Registry Run (HKLM)HKLM\...\CurrentVersion\Run\SystemUpdate_<id>_<timestamp>
Injection targetAspnet_compiler.exe (confirmed)
Network C2Not 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:

SampleSHA-256File NameSizeReporterFirst Seen
Primarybade048f...Purchase Order.js2.0MBlowmal32026-03-10 10:04
Variant172d478c...Technical Parameter.js3.9MBlowmal32026-03-10 07:47
Relateda4e993...AWB_2026031000.zip1.1MBpr0xylife2026-03-10 09:47
Relatedfdfac8...2026-os arajanlatkeres.bat--smica832026-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)

DomainIPASN / ProviderStatus
www[.]yakutianguide[.]ru176.57.66.176AS57724 / Tilda Publishing (RU)LIVE
www[.]xfqjrms[.]bond104.233.223.161PEG TECH INC (US)LIVE
www[.]wzsw5[.]shop198.200.45.122PEG TECH INC (US)LIVE
www[.]thkifry[.]bond104.233.223.165PEG TECH INC (US)LIVE
www[.]studyvibez[.]site198.54.117.242Unknown (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 80
  • 198.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:

DomainContext
www[.]xeoc[.]shopFormbook C2 (ThreatFox)
www[.]xtmmm[.]topFormbook C2 (ThreatFox)
www[.]spjpantp[.]topFormbook 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-256 64f72b92... -- 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:

VendorDetectionNotes
KasperskyTrojan-Spy.Win32.Noon.sb, Trojan-Dropper.Win32.Injector.sb, HEUR:Trojan-Downloader.Script.Generic12 detections across layers
ReversingLabsScript-JS.Backdoor.FormBook8/36 scanners
Hatching TriageFormbook10/10 score
Spamhaus HBLSuspiciousHash-based
FileScan.IOLIKELY_MALICIOUSConfidence 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

TacticTechniqueIDImplementation
Initial AccessSpearphishing AttachmentT1566.001"Purchase Order.js" email lure
ExecutionJavaScriptT1059.007WScript/WSH executes obfuscated JS dropper
ExecutionPowerShellT1059.001Hidden PowerShell with -ExecutionPolicy Bypass
PersistenceRegistry Run Keys / Startup FolderT1547.001HKCU + HKLM Run keys + Startup LNK
Defense EvasionObfuscated Files or InformationT1027957-entry string table, hex-indexed lookups
Defense EvasionDeobfuscate/Decode FilesT1140Base64 --> Rotational XOR --> .NET reflective load
Defense EvasionProcess HollowingT1055.012DEV.dll hollows Aspnet_compiler.exe via GUID APIs
Defense EvasionMasqueradingT1036.005Uses legitimate .NET Framework binary
DiscoveryProcess DiscoveryT1057WMI: SELECT * FROM Win32_Process
DiscoverySystem Information DiscoveryT1082Physical storage device enumeration
DiscoverySystem Location DiscoveryT1614.001System language detection
CollectionKeyloggingT1056.001Formbook keylogger capability
CollectionScreen CaptureT1113Formbook screenshot module
Credential AccessCredentials from Password StoresT1555Formbook credential theft
ExfiltrationExfiltration Over C2 ChannelT1041HTTP 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

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 nfkc2gcmGd mutex and SystemUpdate_ Run key entries across the endpoint estate
  • Search for C:\Temp\ps_*.ps1 files -- this directory and naming pattern are highly specific
  • Alert on Aspnet_compiler.exe running with powershell.exe as 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 .js attachments 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


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

Share