typeanalysisfamilyletsdiskusscomconfidencehighmalware-familyloaderscriptnodejsobfuscationevasionpersistence
SHA-256: 7d9ac86521aba5d8989dd21ed08ab3b138c7aeb4dd41bf8566c10d3d240f55a1

letsdiskusscom: 7d9ac865 — Update_24.js, twenty-eighth confirmed sibling (twenty-eighth distinct msvcp140.dll morph)

Executive Summary

Node.js dropper Update_24.js (8.8 MB) encodes five Windows PE files inside a 256-word English poem via numbered-suffix steganography (gentle1, hush2...fail164). Decoded payload is the same signed Revo System-Restore utility (RevoSrp.exe) plus three Microsoft VC++ runtime DLLs and a BAT-based HKCU Run persistence script seen across all 27 prior siblings in this cluster. The only delta is a twenty-eighth distinct msvcp140.dll build (1,063,936 bytes, MSVC 14.27.29016.0, compiled 2020-06-16). Static-only; CAPE skipped JS source. ^[file.txt] ^[dynamic-analysis.md]

What It Is

Field Value
SHA-256 7d9ac86521aba5d8989dd21ed08ab3b138c7aeb4dd41bf8566c10d3d240f55a1
Filename Update_24.js
Size 8,828,881 bytes (8.4 MB encoded JS + ~400 KB scaffolding)
Type JavaScript source, ASCII text, CRLF line terminators
Carrier language Node.js (fs, path, child_process)
Obfuscation 256-word poem lookup-table steganography with numbered suffixes
CAPE status Skipped — JS source not a supported binary class ^[dynamic-analysis.md:3]

Decoded payloads

Decoded using the standard writePositionsToFile(listA, listB, outPath) routine: split poem vocabulary into array, map each payload word to its index, write indices as bytes.

File SHA-256 Size Type Notes
exe.bin 8b94af60...7fc55f 52,400 PE32+ x64 console RevoSrp.exe, VS Revo Group, MSVC 14.44, signed (DigiCert), compiled 2025-06-02. Same hash as all 27 prior siblings.
dll1.bin (msvcp140.dll) abce40f1...ad3f852 1,063,936 PE32+ x64 DLL Microsoft, MSVC 14.27.29016.0, compiled 2020-06-16, signed. Twenty-eighth distinct morph in cluster.
dll2.bin (vcruntime140.dll) ff43e813...54c833 101,672 PE32+ x64 DLL Microsoft, MSVC 14.27, signed. Same hash as all 27 prior siblings.
dll3.bin (vcruntime140_1.dll) 7b8f70dd...6dfc7 44,328 PE32+ x64 DLL Microsoft, MSVC 14.27, signed. Same hash as all 27 prior siblings.
bat.bin dff20059...b06919 440 DOS batch HKCU Run persistence + EXE launcher. Same hash as all 27 prior siblings.

^[decoded/exe.bin] ^[decoded/dll1.bin] ^[decoded/dll2.bin] ^[decoded/dll3.bin] ^[decoded/bat.bin]

How It Works

  1. Staging directory created at %ProgramData%\Microsoft Edge Updates Helper DneCMKUGkQqy ^[triage.json:5]
  2. Poem vocabulary wlist split into 256-entry array. Each payload (exe, dll1, dll2, dll3, bat) is a space-separated sequence of words; runtime lookup writes byte values to disk via Buffer.from(positions.map(p => p & 0xFF)). ^[floss.txt] ^[decoded/]
  3. Execution: launchExecutable(autorunPath, [exePath]) spawns BAT with EXE as argument; then launchExecutable(exePath) spawns EXE directly. Both use child_process.spawn(..., { shell: true, stdio: 'inherit' }). ^[dynamic-analysis.md] ^[decoded/bat.bin]
  4. Persistence: BAT calls reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "Microsoft Edge Updates Helper" /t REG_SZ /d "\"%~1\"" /f pointing to the staged EXE. ^[decoded/bat.bin]

Decompiled Behavior

No Ghidra decompilation performed — the threat logic is entirely in plaintext Node.js. The writePositionsToFile function is the sole decoding routine:

function writePositionsToFile(listA, listB, outPath) {
  const a = listA.split(' ');
  const b = listB.split(' ');
  const positions = b.map(word => {
    const idx = a.indexOf(word);
    return idx >= 0 ? idx : 0;
  });
  const buffer = Buffer.from(positions.map(p => p & 0xFF));
  fs.writeFileSync(outPath, buffer);
}

Template artifact: const dll4Path = path.join(folder, "DneCMKUGkQqy.bat") declared but never written — a known builder artefact across the numbered-suffix template wave. ^[decoded/]

C2 Infrastructure

None observed. The carrier is self-contained — no network I/O, no download, no C2. The malicious act is deceptive local staging and silent execution of a signed utility under a Microsoft Edge masquerade identity.

Interesting Tidbits

  • Build-counter filename: Update_24.js continues the Update_N.js naming pattern observed across siblings Update_1.js through Update_25.js, suggesting a large batch of builds from the same template. ^[triage.json]
  • Twenty-eighth distinct msvcp140.dll: The msvcp140.dll rotates with every sibling (now 28 distinct builds) while the Revo EXE and vcruntime DLLs remain bit-identical across the entire cluster. This suggests the builder pulls the EXE/DLLs from a fixed template and swaps only the VC++ runtime DLL — possibly to evade hash-based IOC blacklisting. ^[decoded/dll1.bin]
  • Same poem vocabulary: The numbered-suffix poem (gentle1 through fail164) is identical to siblings 3465e6ee, ae2e9acd, ff3ae2e7, 1fbaf8ab, 26155786, b23bb560, a27bda89, 7d47ca60, b53d6a32, 4c57911f, 2c86df65, bf5c69a5, 5ebd96a1, bfc9e6e7, adc5a0b4, 50a8668b, 71e6cb9e. ^[decoded/]
  • Staging suffix: DneCMKUGkQqy — random alphanumeric, unique per sibling.

How To Mess With It (Homelab Replication)

  1. Encode any file as poem-word indices using a 256-word vocabulary.
  2. Wrap in a Node.js script with fs.writeFileSync + child_process.spawn.
  3. Add a BAT-based HKCU Run persistence layer.
  4. Verify: run node Update_24.js on a Windows VM with Node.js; observe files written to %ProgramData%\Microsoft Edge Updates Helper DneCMKUGkQqy and the BAT executing reg add.

Deployable Signatures

YARA rule

rule letsdiskusscom_poem_stego_js : letsdiskusscom {
    meta:
        description = "Node.js dropper using 256-word poem steganography with numbered suffixes"
        author = "PacketPursuit"
        date = "2026-08-24"
        hash = "7d9ac86521aba5d8989dd21ed08ab3b138c7aeb4dd41bf8566c10d3d240f55a1"
    strings:
        $wlist = "const wlist = \"gentle hush that wraps the midnight air" ascii wide
        $func = "function writePositionsToFile(listA, listB, outPath)" ascii wide
        $exe = "Microsoft Edge Updates Helper.exe" ascii wide
        $bat = "DneCMKUGkQqy.bat" ascii wide
        $spawn = "child_process" ascii wide
    condition:
        filesize > 7MB and
        $wlist and $func and $exe and $spawn
}

Behavioral hunt query (Sigma-like)

title: letsdiskusscom Node.js Poem Dropper Execution
logsource:
  product: windows
  category: process_creation
detection:
  selection:
    CommandLine|contains:
      - 'Microsoft Edge Updates Helper'
      - 'DneCMKUGkQqy'
    ParentImage|endswith: 'node.exe'
  condition: selection

IOC list

Type Value Context
SHA-256 7d9ac86521aba5d8989dd21ed08ab3b138c7aeb4dd41bf8566c10d3d240f55a1 Carrier JS
SHA-256 abce40f1b4d0937c7b4aa8beff7a610096d287393e1c02a9ae925fd12ad3f852 msvcp140.dll (28th morph)
SHA-256 8b94af60bb58bc1629edb3b4f6a86ccff5769bb9b96d8826f06686af2d7fc55f RevoSrp.exe
SHA-256 ff43e813785ee948a937b642b03050bb4b1c6a5e23049646b891a66f65d4c833 vcruntime140.dll
SHA-256 7b8f70dd3bdae110e61823d1ca6fd8955a5617119f5405cdd6b14cad3656dfc7 vcruntime140_1.dll
SHA-256 dff20059f161090c76f9f45ac2269f2965bdc96023c78c1072f8d1aa66b06919 BAT persistence script
File path %ProgramData%\Microsoft Edge Updates Helper DneCMKUGkQqy\* Staging directory
Registry HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Microsoft Edge Updates Helper Persistence
Process node.exe → cmd.exe /c "DneCMKUGkQqy.bat" Execution chain

Behavioral fingerprint

A Node.js script (Update_24.js, >7 MB) creates a directory under %ProgramData% named Microsoft Edge Updates Helper <random> and writes five files to it: a 52 KB signed PE named Microsoft Edge Updates Helper.exe, three VC++ runtime DLLs, and a BAT script. The script then spawns the BAT via child_process.spawn with shell: true, which in turn writes an HKCU Run registry key and launches the EXE. No network activity from the carrier. The script body contains a 256-word English poem with numbered suffixes used as a lookup table to decode embedded binaries.

Detection Signatures

ATT&CK ID Name Evidence
T1059.007 Command and Scripting Interpreter: JavaScript Node.js require('fs'), require('child_process') ^[triage.json]
T1027.002 Obfuscated Files or Information: Software Packing 256-word poem lookup-table steganography with numbered suffixes ^[decoded/]
T1036.005 Masquerading: Match Legitimate Name or Location Microsoft Edge Updates Helper directory and filename ^[decoded/bat.bin]
T1547.001 Boot or Logon Autostart Execution: Registry Run Keys BAT calls reg add HKCU\...\Run ^[decoded/bat.bin]
T1543.003 Create or Modify System Process spawn(execPath, args, { shell: true, stdio: 'inherit' }) ^[decoded/]

References

Provenance

  • File type: file v5.44 on carrier JS ^[file.txt]
  • JS decoding: custom Python 3 script mapping a.indexOf(word) to byte values ^[decoded/]
  • PE metadata: rabin2 v5.9.8 on decoded binaries ^[decoded/]
  • ExifTool v12.76 on msvcp140.dll ^[decoded/dll1.bin]
  • Triage metadata: triage.json ^[triage.json]
  • Dynamic analysis: CAPE skipped (JS source not supported) ^[dynamic-analysis.md]