typeanalysisfamilyletsdiskusscomconfidencehighcreated2026-08-23updated2026-08-23malware-familyloaderscriptnodejsobfuscationevasionpersistencemitre-attck
SHA-256: a27bda8928aaf0601341d9121c429a501a74260dd37c89754c2bb4288fda572a

letsdiskusscom: a27bda89 — Update_14.js, seventeenth confirmed sibling

Executive Summary

Seventeenth confirmed sibling in the letsdiskusscom Node.js poem-word-list dropper cluster. The carrier script Update_14.js (10.1 MB) uses numbered-suffix poem steganography to decode five embedded payloads — a signed Revo EXE, three Microsoft VC++ runtime DLLs, and a BAT persistence launcher — to a fake Microsoft Edge Updates Helper directory under %ProgramData%. Same EXE, vcruntime140.dll, vcruntime140_1.dll, and BAT hash as all 16 prior poem-stego siblings. The msvcp140.dll is a new morph (SHA-256 012212f9..., 1,248,256 bytes, MSVC 14.27.29016.0), bringing the cluster's distinct msvcp140 morph count to seventeen. Static-only analysis; CAPE skipped because the sample is plain JavaScript source.

What It Is

  • Filename: Update_14.js ^[metadata.json]
  • File type: JavaScript source, ASCII text, very long lines (63,365 chars), CRLF terminators ^[file.txt]
  • Size: 10,142,852 bytes (10.1 MB) ^[exiftool.json]
  • SHA-256: a27bda8928aaf0601341d9121c429a501a74260dd37c89754c2bb4288fda572a
  • Family: letsdiskusscom (high confidence, cluster sibling #17)
  • OpenCTI labels: js, malware-bazaar ^[metadata.json]

How It Works

The script is a self-contained Node.js installer with no external network dependencies. It uses the same 256-word English poem lookup-table steganography observed across all poem-stego siblings, with numbered suffixes on repeated vocabulary words (gentle1, hush2, wraps3, etc.) to defeat simple word-frequency deduplication. ^[strings.txt:6]

Execution flow:

  1. Decode payloads via writePositionsToFile(wlist, <payload>, outPath) — each payload string is a sequence of poem words; the decoder maps each word to its zero-based index in wlist, producing a byte array. ^[strings.txt:18-25]
  2. Stage to disk at %ProgramData%\Microsoft Edge Updates Helper 9yyM0KCwtOI5\:
    • Microsoft Edge Updates Helper.exe — signed Revo EXE (52,400 bytes)
    • msvcp140.dll — MSVC 14.27.29016.0 (1,248,256 bytes)
    • vcruntime140.dll — MSVC runtime (101,672 bytes)
    • vcruntime140_1.dll — MSVC runtime (44,328 bytes)
    • 9yyM0KCwtOI5.bat — registry persistence launcher (440 bytes)
  3. Launch the BAT with the EXE path as argument, then launch the EXE directly. ^[strings.txt:39-41]

A minor builder artifact is present: dll4Path is assigned to the same BAT path as autorunPath, suggesting copy-paste drift in the builder template. ^[strings.txt:17]

Decompiled Behavior

Not applicable — this is plain JavaScript source, not a compiled PE. No Ghidra or radare2 analysis required. The entire logic is readable from strings.txt (which is the source file itself, as file confirms it is ASCII text with no binary overlay). ^[file.txt]

C2 Infrastructure

None. The carrier is entirely self-contained. No network URLs, no download cradles, no hardcoded IPs or domains. The malicious act is the silent staging and execution of a signed third-party binary under a deceptive directory name. Any actual C2 would live inside the dropped EXE, which has not been independently detonated or reverse-engineered in this corpus.

Interesting Tidbits

  • Build counter continues: filename Update_14.js resumes the Update_N.js pattern after the plain Update.js wave (sibling c485dd9c). The builder appears to maintain an internal counter. ^[metadata.json]
  • Seventeenth msvcp140 morph: prior siblings cycled through sixteen distinct msvcp140.dll builds. This sample adds a seventeenth (SHA-256 012212f9..., 1,248,256 bytes, compiled 2020-06-16). All are legitimate Microsoft VC++ runtime DLLs; the morph rotation likely serves as a trivial sandbox/AV evasion tactic (rotate file hashes to avoid hash-based detection on the DLL). ^[strings.txt:14]
  • Payload hash stability: EXE, DLL2, DLL3, and BAT hashes match all 16 prior poem-stego siblings exactly. The builder reuses the signed Revo EXE and two vcruntime DLLs across every build, only swapping msvcp140.dll. ^[strings.txt:12-17]
  • Staging suffix entropy: 9yyM0KCwtOI5 — 12-character alphanumeric random suffix, consistent with the cluster's per-build unique directory naming. ^[strings.txt:5]
  • BAT content unchanged: identical HKCU Run registry persistence script as all prior siblings. ^[strings.txt:11]

How To Mess With It (Homelab Replication)

  1. Encode any binary as a poem-word sequence:
    • Build a 256-word vocabulary list (English poem prose works well).
    • For each byte b of your payload, emit vocab[b].
    • Number repeated words (word1, word2) to bloat file size and evade frequency analysis.
  2. Wrap in Node.js using the writePositionsToFile pattern from this sample.
  3. Stage and execute via fs.writeFileSync + child_process.spawn with shell: true.
  4. Verification: your output JS should be ~10 MB for ~50 KB of embedded PE payload (200× bloat factor due to word encoding). Run node yourfile.js on a Windows VM with Node.js installed.

Deployable Signatures

YARA rule — letsdiskusscom poem-stego dropper

rule letsdiskusscom_poem_stego_dropper {
    meta:
        description = "Node.js poem-word-list steganography dropper (letsdiskusscom cluster)"
        author = "PacketPursuit"
        date = "2026-08-23"
        reference = "/intel/analyses/a27bda8928aaf0601341d9121c429a501a74260dd37c89754c2bb4288fda572a.html"
    strings:
        $wlist = "const wlist = \"gentle" ascii wide
        $app_name = "Microsoft Edge Updates Helper" ascii wide
        $func1 = "writePositionsToFile" ascii wide
        $func2 = "safeMakeDir" ascii wide
        $func3 = "launchExecutable" ascii wide
        $spawn = "require('child_process')" ascii wide
        $programdata = "process.env.PROGRAMDATA" ascii wide
    condition:
        filesize > 1MB and
        $wlist and $app_name and $func1 and $func2 and $func3 and $spawn and $programdata
}

Sigma rule — Node.js poem dropper execution

title: Node.js Poem-Stego Dropper Execution
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        CommandLine|contains:
            - 'Update_'
            - '.js'
        ParentImage|endswith:
            - '\node.exe'
        CommandLine|contains:
            - 'Microsoft Edge Updates Helper'
    condition: selection
falsepositives:
    - Unlikely; the directory name and filename pattern are attacker-controlled.
level: high

IOC list

Artifact Value Notes
JS filename pattern Update_*.js or Update.js Build counter or plain wave
Staging directory %ProgramData%\Microsoft Edge Updates Helper <12-char suffix>\ Random alphanumeric suffix
Dropped EXE Microsoft Edge Updates Helper.exe Signed Revo component (SHA-256 8b94af60...)
Dropped DLL1 msvcp140.dll Rotates per build (17 distinct morphs observed)
Dropped DLL2 vcruntime140.dll Stable across cluster (SHA-256 ff43e813...)
Dropped DLL3 vcruntime140_1.dll Stable across cluster (SHA-256 7b8f70dd...)
Dropped BAT *.bat HKCU Run persistence (SHA-256 dff20059...)
Registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Run Value name Microsoft Edge Updates Helper

Behavioral fingerprint

This sample is a Node.js script that, when executed via node.exe, creates a subdirectory under %ProgramData% named Microsoft Edge Updates Helper <random12>, writes five files to it (EXE + three DLLs + BAT), then spawns the BAT file and the EXE via child_process.spawn with shell: true. No network activity from the carrier. The BAT sets an HKCU Run key pointing to the EXE. All payloads are decoded at runtime from a 256-word English poem lookup-table with numbered suffix obfuscation.

Detection Signatures

Capability ATT&CK Technique Evidence
JavaScript execution T1059.007 require('child_process'), spawn(..., {shell: true}) ^[strings.txt:3,30]
Obfuscated payload encoding T1027.002 256-word poem lookup-table with numbered suffixes ^[strings.txt:6]
Masquerading T1036.005 Microsoft Edge Updates Helper directory and filename ^[strings.txt:4,12]
Registry Run persistence T1547.001 BAT writes HKCU\...\Run with reg add ^[strings.txt:11]
Create system process T1543.003 child_process.spawn with shell: true ^[strings.txt:30]

References

  • letsdiskusscom entity page: entities/letsdiskusscom.md
  • poem-word-list-steganography technique page: techniques/poem-word-list-steganography.md
  • registry-run-persistence procedure page: procedures/registry-run-persistence.md
  • Sibling b23bb560 (16th sibling, Update_19.js): /intel/analyses/b23bb560a20c587c6888813fc06a53d4eac46af78a3813fdeefa6b6667176024.html

Provenance

Analysis derived from strings.txt (the JS source itself, as file.txt confirms plain ASCII text), metadata.json, exiftool.json, file.txt, and manual decoding of the poem-word payloads. No dynamic execution performed; CAPE skipped because the sample is JavaScript source, not a supported binary class. Tool versions: file 5.44, exiftool 12.76.