c485dd9c6d810f36618315d661ecb801f4ef8d44ef9946876a4649ed8c23c15eletsdiskusscom: c485dd9c — fifteenth confirmed poem-stego sibling, Update.js
Executive Summary
Update.js is the fifteenth confirmed sibling in the letsdiskusscom Node.js dropper cluster. It encodes four PE payloads and a persistence BAT inside a 256-word English poem via numbered-suffix steganography, stages them to %ProgramData%\Microsoft Edge Updates Helper WG4n5KCoqYf0, and silently executes a signed Revo Uninstaller component. No C2 — self-contained local payload delivery with registry Run persistence. ^[strings.txt:1]
What It Is
| Field | Value |
|---|---|
| SHA-256 | c485dd9c6d810f36618315d661ecb801f4ef8d44ef9946876a4649ed8c23c15e |
| Filename | Update.js |
| Size | 8,150,621 bytes (7.8 MB) |
| File type | JavaScript source, ASCII text, very long lines (63,365), CRLF terminators ^[file.txt:1] |
| Family | letsdiskusscom (high-confidence cluster sibling) |
| Source | OpenCTI / MalwareBazaar (js label) |
The sample is a Node.js script using fs, path, and child_process modules to drop and execute embedded Windows PE payloads. All payloads are encoded inside the script via custom poem-word-list steganography. ^[strings.txt:1]
How It Works
1. Poem-word-list steganography
The script defines a 256-word lookup table (wlist) — the same English poem fragment observed in siblings 3465e6ee through 26155786 — and five payload strings (exe, dll1, dll2, dll3, bat). Each payload word is looked up in wlist by index; the index value (masked to 0xFF) is written to disk as a byte. ^[strings.txt:6]
Builder variant: numbered suffixes on repeated vocabulary (gentle1, hush2, that3 ... fail164). This poisons frequency analysis without changing lookup semantics. Same template as siblings 3465e6ee, ae2e9acd, 70862e4d, ff3ae2e7, 1fbaf8ab, and 26155786. ^[strings.txt:6] ^[techniques/poem-word-list-steganography.md]
2. Payload decode and staging
const folder = path.join(process.env.PROGRAMDATA, `Microsoft Edge Updates Helper WG4n5KCoqYf0`);
const exePath = path.join(folder, "Microsoft Edge Updates Helper.exe");
const autorunPath = path.join(folder, "WG4n5KCoqYf0.bat");
// ... plus three VC++ runtime DLLs
The script creates the staging directory recursively with mode 0o755, decodes all five payloads via writePositionsToFile, then spawns the BAT (adds registry persistence) followed by the EXE. ^[strings.txt:12]
3. Registry Run persistence via BAT
The decoded BAT adds an HKCU\Software\Microsoft\Windows\CurrentVersion\Run entry named "Microsoft Edge Updates Helper" pointing to the staged EXE. ^[manual decode of bat.bin]
4. Payloads decoded
| Payload | SHA-256 | Size | Description |
|---|---|---|---|
| EXE | 8b94af60...7fc55f |
52,400 B | RevoSrp.exe — VS Revo Group, MSVC 14.44, Authenticode signed (DigiCert). Same hash as all 14 prior siblings. ^[exiftool.json: exe] |
| DLL1 | 832c1425...0d8ca |
969,728 B | msvcp140.dll, Microsoft, MSVC 14.27.29016.0. Fifteenth distinct msvcp140 morph in cluster. Unsigned. ^[exiftool.json: dll1] |
| DLL2 | ff43e813...4c833 |
101,672 B | vcruntime140.dll, Microsoft, MSVC 14.27. Signed. Same hash as all 14 prior siblings. ^[exiftool.json: dll2] |
| DLL3 | 7b8f70dd...6dfc7 |
44,328 B | vcruntime140_1.dll, Microsoft, MSVC 14.27. Signed. Same hash as all 14 prior siblings. ^[exiftool.json: dll3] |
| BAT | dff20059...06919 |
440 B | Registry Run persistence script. Same hash as all 14 prior siblings. ^[manual decode] |
Decoded Script Behavior
Entry point is the top-level block at the bottom of the script:
- Directory creation —
safeMakeDir(folder)withrecursive: trueand mode0o755. ^[strings.txt:27] - Payload reconstruction — Five calls to
writePositionsToFile(wlist, payload, destPath)decode the poem strings back to raw PE/BAT bytes. ^[strings.txt:18] - Execution —
launchExecutablespawns"autorunPath"withshell: trueand passesexePathas an argument, then spawnsexePathdirectly. The BAT adds the registry key and exits; the EXE runs regardless. ^[strings.txt:29] - Error handling — Wrapped in a bare
try/catchthat logs"Installation failed"to stderr and exits with code 1. ^[strings.txt:42]
C2 Infrastructure
None. Self-contained local installer. No network requests, no hardcoded URLs, no DNS, no C2 callbacks. The malicious act is silent staging and execution of a masqueraded signed binary with persistence.
Interesting Tidbits
- Fifteenth distinct msvcp140.dll: The cluster now shows 15 unique msvcp140 morphs. The builder rotates VC++ runtime redistributables between builds while keeping the Revo EXE and vcruntime DLLs constant, likely to evade hash-based detection on the DLL alone. ^[exiftool.json: dll1]
- Filename lacks build counter: Unlike prior siblings (
Update_3.js,Update_13.js,Update_16.js,Update_22.js,Update_25.js), this sample is simplyUpdate.js. This may represent a fresh campaign wave, a different distribution channel, or a builder configuration toggle. ^[metadata.json:5] - MSVC 14.27 timestamp on DLL1:
2020-06-16 03:11:14— same vintage runtime as siblings5126076d,2274d74f,ae2e9acd,70862e4d,ff3ae2e7,1fbaf8ab, and26155786. The builder draws from a pool of older redistributables. ^[exiftool.json: dll1] - RevoSrp.exe PDB path:
D:\\Work_REVO\\VSRevo\\Windows\\Projects\\Registry Cleaner\\revo-registry-cleaner\\Revo Registry Cleaner\\x64\\Release\\RevoSrp.pdb— same as sibling26155786, confirming a Registry Cleaner product-line origin rather than Uninstaller Pro. ^[strings.txt: exe_strings.txt] - BAT argument passing: The BAT accepts
"%~1"(the EXE path) as an argument, but the registry key hardcodes the EXE path inside the BAT's own string — the argument is redundant and likely builder template residue. ^[manual decode of bat.bin] - No
javascript-obfuscator: The obfuscation is purely the poem steganography. No self-defend IIFE, no string-array rotator, no dead-code injection. ^[strings.txt:1]
How To Mess With It (Homelab Replication)
See poem-word-list-steganography for the full replication recipe. The numbered-suffix variant used here is identical to sibling 26155786; add suffixes only on repeated words to poison frequency analysis without changing decode semantics.
Deployable Signatures
YARA rule — letsdiskusscom poem-stego Node.js dropper
rule letsdiskusscom_poem_stego_js
{
meta:
description = "Node.js dropper using 256-word poem steganography to encode PE payloads"
author = "PacketPursuit"
reference = "/intel/analyses/c485dd9c6d810f36618315d661ecb801f4ef8d44ef9946876a4649ed8c23c15e.html"
date = "2026-08-22"
strings:
$require_fs = "const fs = require('fs');"
$require_path = "const path = require('path');"
$require_spawn = "const { spawn } = require('child_process');"
$wlist = "const wlist = \"gentle hush"
$exe = "const exe = \"unwearied"
$dll1 = "const dll1 = \"unwearied"
$func = "function writePositionsToFile(listA, listB, outPath)"
$progdata = "Microsoft Edge Updates Helper"
condition:
filesize > 1MB and filesize < 15MB
and all of ($require_*)
and $func
and $progdata
and any of ($wlist, $exe, $dll1)
}
Sigma rule — Node.js spawning signed EXE from fake Edge Updates Helper directory
title: Node.js spawning signed EXE from fake Edge Updates Helper directory
logsource:
product: windows
category: process_creation
detection:
selection_parent:
ParentImage|endswith: '\\node.exe'
selection_child:
CommandLine|contains:
- 'Microsoft Edge Updates Helper'
- 'WG4n5KCoqYf0'
selection_registry:
CommandLine|contains:
- 'reg add'
- 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run'
condition: selection_parent and (selection_child or selection_registry)
falsepositives:
- Unknown
level: high
IOC list
| Indicator | Value | Type |
|---|---|---|
| SHA-256 (carrier) | c485dd9c6d810f36618315d661ecb801f4ef8d44ef9946876a4649ed8c23c15e |
Hash |
| SHA-256 (embedded EXE) | 8b94af60bb58bc1629edb3b4f6a86ccff5769bb9b96d8826f06686af2d7fc55f |
Hash |
| SHA-256 (embedded DLL1) | 832c14257068501f4edbdd18e0ab7eac5b615dbd2e63da20a47ec7475f00d8ca |
Hash |
| SHA-256 (embedded DLL2) | ff43e813785ee948a937b642b03050bb4b1c6a5e23049646b891a66f65d4c833 |
Hash |
| SHA-256 (embedded DLL3) | 7b8f70dd3bdae110e61823d1ca6fd8955a5617119f5405cdd6b14cad3656dfc7 |
Hash |
| SHA-256 (embedded BAT) | dff20059f161090c76f9f45ac2269f2965bdc96023c78c1072f8d1aa66b06919 |
Hash |
| Staging directory | %ProgramData%\Microsoft Edge Updates Helper WG4n5KCoqYf0 |
Path |
| Registry key | HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Microsoft Edge Updates Helper |
Registry |
| Process tree | node.exe → cmd.exe /c "WG4n5KCoqYf0.bat" → Microsoft Edge Updates Helper.exe |
Behavior |
Behavioral fingerprint
This Node.js script drops five files to a fake %ProgramData%\Microsoft Edge Updates Helper <random_suffix> directory: one 52 KB signed x64 EXE (RevoSrp.exe), three Microsoft VC++ runtime DLLs (msvcp140.dll, vcruntime140.dll, vcruntime140_1.dll), and one 440-byte BAT script. The BAT adds an HKCU\Run persistence entry, then the EXE is launched via child_process.spawn with shell: true. No network activity. The script body contains extremely long lines (tens of thousands of characters) composed of English poem words with optional numeric suffixes.
Detection Signatures
- capa: N/A — JavaScript source file, not a supported binary class. ^[capa.txt:1]
- MITRE ATT&CK:
- T1059.007 (Command and Scripting Interpreter: JavaScript)
- T1027.002 (Obfuscated Files or Information: Software Packing) — poem-word-list encoding
- T1036.005 (Masquerading: Match Legitimate Name or Location)
- T1547.001 (Boot or Logon Autostart Execution: Registry Run Keys)
- T1543.003 (Create or Modify System Process: Windows Service) — via
child_process.spawn
References
- letsdiskusscom — cluster entity page
- poem-word-list-steganography — technique page
- natural-language-payload-encoding — concept page
- registry-run-persistence — procedure page
- OpenCTI label:
letsdiskuss-com - MalwareBazaar:
c485dd9c6d810f36618315d661ecb801f4ef8d44ef9946876a4649ed8c23c15e
Provenance
- Source file:
wiki/wiki/raw/analyses/c485dd9c6d810f36618315d661ecb801f4ef8d44ef9946876a4649ed8c23c15e/ - Decoded payloads written to
/tmp/c485_decode/via manual Python script - File type:
file 5.44 - Metadata:
exiftool 12.76 - capa: skipped (JavaScript source, unsupported file class) ^[capa.txt:1]
- CAPE: skipped (JavaScript source, no Windows guest) ^[dynamic-analysis.md:1]
- No radare2 or Ghidra analysis required — behavior is fully recoverable from plaintext JavaScript decode.