typeanalysisfamilyletsdiskusscomconfidencehighmalware-familyloaderscriptnodejsobfuscationevasionpersistence
SHA-256: c075aeba57f002acf9e317f9bde29914031090de3444718af334a39d8cf0651d

letsdiskusscom: c075aeba — 7.8 MB fifth poem-stego sibling with unique msvcp140.dll

A 7.8 MB Node.js dropper encoding four embedded PE payloads (one signed EXE + three signed VC++ runtime DLLs) and a BAT persistence script inside a 256-word English poem lookup table. At runtime it reconstructs the payloads by poem-word index mapping, stages them to a fake Microsoft Edge Updates Helper xp7v5lqfYx3t directory under %ProgramData%, writes a BAT that adds the EXE to HKCU\Run, then spawns the BAT and the EXE. No C2. This is the fifth confirmed sibling in the letsdiskusscom cluster.

What It Is

Field Value
SHA-256 c075aeba57f002acf9e317f9bde29914031090de3444718af334a39d8cf0651d
File name Update_17.js
Size 7,855,201 bytes (7.5 MB) ^[file.txt]
Type JavaScript source, ASCII text, very long lines (63,365), CRLF terminators ^[file.txt]
Family letsdiskusscom — Node.js dropper cluster (high-confidence, n=5)

Build / RE

Carrier. Plain JavaScript (Node.js require surface: fs, path, child_process). No javascript-obfuscator; the entire obfuscation is the poem-word-list steganography. ^[strings.txt:1-5]

Encoding. A 256-word English poem serves as a lookup table (indices 0–255). Payloads are stored as space-separated sequences of poem words. The helper writePositionsToFile(listA, listB, outPath) splits listA, finds each listB word's index, masks to 0xFF, and writes the byte buffer. ^[strings.txt:18-26]

Embedded payloads (decoded).

File SHA-256 Size Note
EXE 8b94af60...7fc55f 52,400 Same signed Revo EXE as all prior siblings ^[manual decode]
DLL1 (msvcp140) 2ee431f4...2c3ec 956,416 Fifth distinct msvcp140.dll in cluster ^[manual decode]
DLL2 (vcruntime140) ff43e813...4c833 101,672 Same as prior siblings ^[manual decode]
DLL3 (vcruntime140_1) 7b8f70dd...6dfc7 44,328 Same as prior siblings ^[manual decode]
BAT dff20059...b06919 440 Same BAT as d0ca14b3/247b54b5/af4313e4 ^[manual decode]

Build quality. The dll4Path variable is dead code (copy-paste remnant from DLL pattern) — the BAT is written to autorunPath instead. ^[strings.txt:17]

Deploy / ATT&CK

ID Technique Evidence
T1059.007 Command and Scripting Interpreter: JavaScript Node.js require('fs') + child_process.spawn ^[strings.txt:1-3]
T1027.002 Obfuscated Files or Information: Software Packing 256-word poem lookup-table hides PE payloads as natural-language prose ^[strings.txt:6]
T1547.001 Boot or Logon Autostart Execution: Registry Run Keys BAT calls reg add HKCU\...\Run with masquerade value name ^[manual decode of bat payload]
T1543.003 Create or Modify System Process: Windows Service spawn(..., { shell: true, stdio: 'inherit' }) launches BAT then EXE ^[strings.txt:30-41]
T1036.005 Masquerading Microsoft Edge Updates Helper directory and registry value name ^[strings.txt:4-5]

Cluster delta. Prior siblings used detached: true, stdio: 'ignore' (9dc2cded) or shell: true with the same BAT (d0ca14b3/247b54b5/af4313e4). This sample uses shell: true, stdio: 'inherit' for both the BAT and the direct EXE launch — a minor variation that keeps the child attached to the parent's console. ^[strings.txt:30-41]

C2. None. Fully self-contained. No network references in the carrier. The Revo EXE may phone home at runtime, but that requires PE-level detonation. ^[strings.txt] ^[dynamic-analysis.md]

Deployable Signatures

YARA rule — poem-word-list Node.js dropper

rule letsdiskusscom_poem_stego_js {
    meta:
        description = "Node.js dropper using 256-word poem lookup table to encode PE payloads"
        author = "PacketPursuit"
        family = "letsdiskusscom"
    strings:
        $node_fs = "const fs = require('fs')"
        $node_path = "const path = require('path')"
        $node_spawn = "const { spawn } = require('child_process')"
        $wlist = "const wlist = "
        $func = "function writePositionsToFile"
        $mask = "p & 0xFF"
        $folder = /Microsoft Edge Updates Helper [a-zA-Z0-9]+/
    condition:
        filesize > 1MB and
        $node_fs and $node_path and $node_spawn and
        $wlist and $func and $mask and $folder
}

Behavioral hunt query — Sigma

title: Node.exe writing Microsoft Edge helper files to ProgramData
logsource:
    category: file_event
    product: windows
detection:
    selection:
        Image|endswith: '\node.exe'
        TargetFilename|contains:
            - 'ProgramData\Microsoft Edge Updates Helper'
            - 'Microsoft Edge Updates Helper.exe'
            - 'xp7v5lqfYx3t'
    condition: selection
falsepositives:
    - Unlikely — path is attacker-controlled random suffix
level: high

IOC list

Type Value Context
SHA-256 (JS carrier) c075aeba57f002acf9e317f9bde29914031090de3444718af334a39d8cf0651d Update_17.js
SHA-256 (embedded EXE) 8b94af60bb58bc1629edb3b4f6a86ccff5769bb9b96d8826f06686af2d7fc55f Revo Uninstaller Pro component
SHA-256 (msvcp140.dll) 2ee431f485e193c64071583f4535ecc9e1cbd0222078a88aad2f7d6b1142c3ec This sample's variant
SHA-256 (vcruntime140.dll) ff43e813785ee948a937b642b03050bb4b1c6a5e23049646b891a66f65d4c833 Shared across cluster
SHA-256 (vcruntime140_1.dll) 7b8f70dd3bdae110e61823d1ca6fd8955a5617119f5405cdd6b14cad3656dfc7 Shared across cluster
SHA-256 (BAT) dff20059f161090c76f9f45ac2269f2965bdc96023c78c1072f8d1aa66b06919 Shared across poem-stego siblings
Staging directory %ProgramData%\Microsoft Edge Updates Helper xp7v5lqfYx3t Attacker-controlled random suffix
Registry persistence HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Microsoft Edge Updates Helper BAT-written REG_SZ

References

  • Wiki: letsdiskusscom — cluster entity page
  • Technique: poem-word-list-steganography — 256-word poem encoding
  • Concept: natural-language-payload-encoding — prose-based payload hiding
  • Procedure: registry-run-persistence — BAT-based Run key technique
  • Sibling reports: raw/analyses/9dc2cded.../report.md, raw/analyses/d0ca14b3.../report.md, raw/analyses/247b54b5.../report.md, raw/analyses/af4313e4.../report.md

Provenance

  • file.txt — file utility (file type, size)
  • strings.txt — static string extraction via strings -n 8
  • dynamic-analysis.md — CAPE sandbox status (skipped, unsupported file class)
  • floss.txt — flare-floss (error, unsupported file class)
  • capa.txt — Mandiant capa (error, unsupported file class)
  • Manual decode via Python re-implementation of writePositionsToFile against the raw JS source
  • SHA-256 verification via hashlib.sha256 on decoded byte buffers