5ebd96a1eb9cf6179dc7ea68b5b221c7aab22c460567071a930a11a24cd03f8bletsdiskusscom: 5ebd96a1 — Twenty-third confirmed sibling, Update_9.js poem-stego dropper
Executive Summary
A 9.2 MB Node.js self-extracting dropper (Update_9.js) masquerading as a Microsoft Edge update helper. Uses numbered-suffix poem-word-list steganography (gentle1, hush2, etc.) to encode a signed RevoSrp.exe payload plus three VC++ runtime DLLs and a BAT-based HKCU Run persistence script. Twenty-third confirmed sibling in the letsdiskusscom cluster. No C2 — fully self-contained. Static-only (CAPE skipped — JS source not a supported binary class). ^[strings.txt:1]
What It Is
| Field | Value |
|---|---|
| SHA-256 | 5ebd96a1eb9cf6179dc7ea68b5b221c7aab22c460567071a930a11a24cd03f8b |
| Filename | Update_9.js |
| File type | JavaScript source, ASCII text, CRLF line terminators ^[file.txt] |
| Size | 9,227,899 bytes (9.2 MB) |
| ssdeep | 6144:/ubnYpscp3SqA5mPYsTvQw1z8jBZlLtH+Bp89S5mfsw9wpNQVwS0msFJvXiESUWq:DPBqO ^[ssdeep.txt] |
| tlsh | 4896DFAB6DEC361D3000B1C2F48521F5E6621336DBDE12D9B8F924337AFA49AC46D746 ^[tlsh.txt] |
Preliminary family: letsdiskusscom (OpenCTI label letsdiskuss-com). High confidence — exact same Microsoft Edge Updates Helper masquerade, same poem-word-list encoding technique, same signed Revo payload and vcruntime DLLs, same BAT persistence pattern. ^[entities/letsdiskusscom.md]
How It Works
Payload Encoding
The carrier defines a 256-word English poem lookup table with numbered suffixes (gentle1, hush2, ... fail164). Five embedded binaries are encoded as space-delimited word sequences. At runtime writePositionsToFile splits the lookup table, maps each encoded word back to its index, and writes index & 0xFF to disk. This produces the original PE byte-for-byte. ^[strings.txt:6] ^[strings.txt:18]
Staged Files
| Staged file | Size | SHA-256 | Notes |
|---|---|---|---|
Microsoft Edge Updates Helper.exe |
52,400 B | 8b94af60bb58bc1629edb3b4f6a86ccff5769bb9b96d8826f06686af2d7fc55f |
RevoSrp.exe (Registry Cleaner), signed by VS REVO GROUP OOD via DigiCert Trusted G4 Code Signing CA ^[raw/analyses/5ebd96a1eb9cf6179dc7ea68b5b221c7aab22c460567071a930a11a24cd03f8b/exe.bin] |
msvcp140.dll |
1,119,232 B | 72e5b6aaa61f9dcadee52fd680080e0b51389016190533f94a88b0cbc2797684 |
MSVC 14.27.29016.0, compiled 2020-06-16 (timestamp 0x5EE83852). PE32+ x64. Twenty-third distinct morph in cluster. ^[raw/analyses/5ebd96a1eb9cf6179dc7ea68b5b221c7aab22c460567071a930a11a24cd03f8b/dll1.bin] |
vcruntime140.dll |
101,672 B | ff43e813785ee948a937b642b03050bb4b1c6a5e23049646b891a66f65d4c833 |
Same as all 22 prior siblings |
vcruntime140_1.dll |
44,328 B | 7b8f70dd3bdae110e61823d1ca6fd8955a5617119f5405cdd6b14cad3656dfc7 |
Same as all 22 prior siblings |
CLTNCl7Ekb2U.bat |
440 B | dff20059f161090c76f9f45ac2269f2965bdc96023c78c1072f8d1aa66b06919 |
HKCU Run persistence — adds "Microsoft Edge Updates Helper" pointing to EXE path |
Execution Chain
- Creates
%ProgramData%\Microsoft Edge Updates Helper CLTNCl7Ekb2Uwithmode 0o755. ^[strings.txt:27] - Decodes all five payloads from poem-word indices to disk via
writePositionsToFile. ^[strings.txt:18] - Launches the BAT file with the EXE path as argument — BAT adds
HKCU\Software\Microsoft\Windows\CurrentVersion\Runentry. ^[strings.txt:30] - Launches the EXE directly via
spawn(..., { shell: true, stdio: 'inherit' }). ^[strings.txt:29]
Note: dll4Path is declared but never written — a template artifact. ^[strings.txt:17]
Decompiled Behavior
Not applicable. The artifact is a raw Node.js script (not a PE binary). No compiled machine code is present; threat logic is plaintext JavaScript with lexical obfuscation. Ghidra / radare2 do not apply. ^[file.txt]
C2 Infrastructure
None. The dropper is fully self-contained — no network requests, no C2 URLs, no callback. The malicious act is the deceptive delivery of a signed third-party executable under a false identity, with registry persistence. ^[strings.txt]
Interesting Tidbits
- Build counter continuity: Filename
Update_9.jsslots between existing siblingsUpdate_5.js(b53d6a32),Update_12.js(2c86df65),Update_13.js(70862e4d),Update_14.js(a27bda89),Update_15.js(4c57911f),Update_16.js(26155786),Update_17.js(c075aeba),Update_18.js(7d47ca60),Update_19.js(b23bb560),Update_22.js(ff3ae2e7),Update_25.js(1fbaf8ab), andUpdate_1.js(bf5c69a5). The internal counter suggests at least 25 builds in this template. ^[triage.json] - Template artifact —
dll4Path: A fourth DLL path is computed (CLTNCl7Ekb2U.bat) but never passed towritePositionsToFile. The BAT path is already handled by thebatvariable. This suggests a builder template that optionally emits four DLLs, and this build left the fourth slot empty. ^[strings.txt:17] module.exportsdead code: The script ends withmodule.exports = writePositionsToFile;, which has no effect in a standalone.jsfile executed directly. Builder template leakage from a Node.js module context. ^[strings.txt:26]- Double EXE launch: The BAT adds the registry entry but does not launch the EXE. The subsequent
launchExecutable(exePath)directly spawns the payload, meaning the EXE runs once immediately and will run again at next logon via the Run key. ^[strings.txt:30] - MSVC 14.27.29016.0 msvcp140.dll: The twenty-third distinct morph uses the same compiler version as most siblings (14.27.29016.0, 2020-06-16), confirming a fixed pool of legitimate runtime DLLs being rotated rather than custom-compiled payloads. ^[raw/analyses/5ebd96a1eb9cf6179dc7ea68b5b221c7aab22c460567071a930a11a24cd03f8b/dll1.bin]
How To Mess With It (Homelab Replication)
- Create a 256-word lookup table with numbered suffixes after the first cycle:
gentle1 hush2 that3 wraps4 ... fail164 - Encode a file:
words = lookup.split() with open('payload.exe','rb') as f: data = f.read() encoded = ' '.join(words[b] for b in data) - Carrier script: Wrap in a Node.js file using the
writePositionsToFilepattern withfs.writeFileSyncandchild_process.spawn. - Verify: Decode the poem string back to the original payload; compare SHA-256.
- What you learn: How natural-language steganography defeats static string extraction and why child-process +
%ProgramData%write monitoring is a better detection than content scanning.
Deployable Signatures
YARA Rule
rule Letsdiskusscom_PoemStego_JS
{
meta:
description = "Node.js poem-word-list steganography dropper (letsdiskusscom cluster)"
author = "triage"
family = "letsdiskusscom"
reference = "/intel/analyses/5ebd96a1eb9cf6179dc7ea68b5b221c7aab22c460567071a930a11a24cd03f8b.html"
strings:
$a1 = "Microsoft Edge Updates Helper"
$a2 = "writePositionsToFile"
$a3 = "Buffer.from(positions.map(p => p & 0xFF))"
$b1 = "gentle1 hush2 that3 wraps4"
$b2 = "const fs = require('fs');"
$b3 = "const { spawn } = require('child_process');"
condition:
filesize > 1MB and filesize < 20MB
and #b2 == 1 and #b3 == 1
and 2 of ($a*)
and 1 of ($b*)
}
Behavioral Hunt Query (Sigma)
title: Node.js Letsdiskusscom Poem-Stego Dropper Execution
logsource:
category: process_creation
product: windows
detection:
selection:
- Image|endswith: 'node.exe'
- CommandLine|contains:
- 'Microsoft Edge Updates Helper'
- 'CLTNCl7Ekb2U'
- 'writePositionsToFile'
selection2:
- ParentImage|endswith: 'node.exe'
- Image|endswith:
- 'reg.exe'
- 'cmd.exe'
- CommandLine|contains:
- 'Microsoft Edge Updates Helper'
- 'CLTNCl7Ekb2U'
condition: selection or selection2
falsepositives:
- Unknown
level: high
IOC List
| Indicator | Type | Value |
|---|---|---|
| SHA-256 | Hash | 5ebd96a1eb9cf6179dc7ea68b5b221c7aab22c460567071a930a11a24cd03f8b |
| Filename | String | Update_9.js |
| Staging directory | Path | %ProgramData%\Microsoft Edge Updates Helper CLTNCl7Ekb2U |
| Registry key | Registry | HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Microsoft Edge Updates Helper |
| Revo payload | Hash | 8b94af60bb58bc1629edb3b4f6a86ccff5769bb9b96d8826f06686af2d7fc55f |
| msvcp140.dll (this build) | Hash | 72e5b6aaa61f9dcadee52fd680080e0b51389016190533f94a88b0cbc2797684 |
| vcruntime140.dll | Hash | ff43e813785ee948a937b642b03050bb4b1c6a5e23049646b891a66f65d4c833 |
| vcruntime140_1.dll | Hash | 7b8f70dd3bdae110e61823d1ca6fd8955a5617119f5405cdd6b14cad3656dfc7 |
| BAT persistence | Hash | dff20059f161090c76f9f45ac2269f2965bdc96023c78c1072f8d1aa66b06919 |
Behavioral Fingerprint
This artifact is a Node.js script that drops four PE files and one BAT to a %ProgramData% subdirectory named after a legitimate browser product. It uses a 256-word English poem with numbered suffixes as a byte-to-word lookup table, decoding payloads by word-index position. It then spawns a BAT that adds an HKCU Run registry key pointing to the dropped EXE, followed by direct execution of the EXE via child_process.spawn with shell: true. No network activity is generated by the carrier. The EXE payload is a signed copy of RevoSrp.exe (Registry Cleaner) with a rotating msvcp140.dll runtime.
Detection Signatures
| Source | Mapping | Note |
|---|---|---|
| capa | N/A | capa errored — JS source is not a supported binary class ^[capa.txt] |
References
- letsdiskusscom — cluster entity page (twenty-three confirmed siblings)
- poem-word-list-steganography — technique page for the 256-word poem encoding
- natural-language-payload-encoding — concept page for prose-based payload hiding
- registry-run-persistence — procedure page for the BAT-based Run key technique
- MalwareBazaar:
5ebd96a1eb9cf6179dc7ea68b5b221c7aab22c460567071a930a11a24cd03f8b(Update_9.js)
Provenance
Analysis derived from file.txt, strings.txt, ssdeep.txt, tlsh.txt, triage.json, exiftool.json, and manual JavaScript deobfuscation via Python regex extraction. Python 3.12 used for payload decoding and SHA-256 verification. capa v8.0.1 and floss v3.1.0 errored on JS source; expected behavior. CAPE skipped — JavaScript source is not a supported binary class for detonation. No dynamic analysis performed. Report generated 2026-08-23.