typeanalysisfamilyletsdiskusscomconfidencehighloaderscriptnodejsobfuscationevasionpersistencepoem-word-list-steganographynatural-language-payload-encodingregistry-run-persistence
SHA-256: 50a8668bad8043c6fa7610f0fc8bb119dd998e183f20a15e78f32efee108a753

letsdiskusscom: 50a8668b — Update_6.js, 26th sibling, 26th distinct msvcp140.dll morph

7.4 MB Node.js script dropper using numbered-suffix poem-word-list steganography (gentle1, hush2, etc.) to encode a signed Revo Uninstaller EXE, three signed Microsoft VC++ runtime DLLs, and a BAT registry-persistence launcher. The 26th confirmed sibling in the letsdiskusscom cluster and the first to carry a 26th distinct msvcp140.dll morph (869,888 B, MSVC 14.27.29016.0). Filename Update_6.js continues the internal build-counter pattern. Static-only (CAPE skipped — JS source not a supported binary class).

What It Is

Field Value
SHA-256 50a8668bad8043c6fa7610f0fc8bb119dd998e183f20a15e78f32efee108a753
Filename Update_6.js
Size 7,420,361 bytes ^[file.txt]
Type JavaScript source, ASCII text, very long lines (63,365), CRLF terminators ^[file.txt]
Family letsdiskusscom (high confidence) — 26th confirmed sibling ^[entities/letsdiskusscom.md]
Tier Deep (static-only; CAPE skipped JS source) ^[triage.json]

How It Works

The carrier is a Node.js script that decodes five embedded payloads from a 256-word English poem lookup table with numbered suffixes on repeated vocabulary (gentle1, hush2, etc.). At runtime it:

  1. Creates %ProgramData%\Microsoft Edge Updates Helper jlEFdrhYiMC4 ^[strings.txt:1-5]
  2. Decodes the poem-word indices to bytes via writePositionsToFile(wlist, payload, outPath) ^[strings.txt:45-55]
  3. Writes the decoded payloads to disk:
    • Microsoft Edge Updates Helper.exe (52,400 B, signed RevoSrp.exe) ^[exiftool: exe]
    • msvcp140.dll (869,888 B, signed Microsoft VC++ runtime) ^[exiftool: dll1]
    • vcruntime140.dll (101,672 B, signed Microsoft VC++ runtime) ^[exiftool: dll2]
    • vcruntime140_1.dll (44,328 B, signed Microsoft VC++ runtime) ^[exiftool: dll3]
    • jlEFdrhYiMC4.bat (440 B, registry Run persistence) ^[strings.txt:60-70]
  4. Launches the BAT with the EXE path as argument, then launches the EXE directly ^[strings.txt:75-80]

The BAT adds HKCU\Software\Microsoft\Windows\CurrentVersion\Run with value "Microsoft Edge Updates Helper" pointing to the EXE path. ^[decoded BAT content]

C2 Infrastructure

None observed in the carrier. The script is fully self-contained. All payloads are poem-encoded and embedded; no HTTP/HTTPS, DNS, socket, or IP references recovered. The Revo EXE may phone home at runtime, but that requires dynamic detonation of the PE, not the JS carrier. ^[strings.txt] ^[dynamic-analysis.md]

Interesting Tidbits

  • 26th distinct msvcp140.dll morph. The embedded msvcp140.dll (SHA-256 575bcf6ab68317b455284d92e44df912b19f31b6f9c35167db471b53f87142e5, 869,888 B) has zero matches across all 25 prior sibling reports, confirming a fresh DLL rotation. All other payloads (EXE, DLL2, DLL3, BAT) match the invariant cluster set exactly. ^[manual hash comparison across corpus]
  • Build-counter filename. Update_6.js fills the gap between Update_5.js (b53d6a32) and Update_9.js (5ebd96a1), confirming the internal build counter continues to increment. ^[entities/letsdiskusscom.md]
  • Dead code dll4Path. The script defines const dll4Path = path.join(folder, "jlEFdrhYiMC4.bat") but never calls writePositionsToFile with it; the BAT is written to autorunPath instead. This copy-paste error has persisted across every poem-stego sibling. ^[strings.txt:65]
  • Signed payload reuse. The embedded EXE and DLL2/DLL3 have identical SHA-256 hashes to all 25 prior siblings. The operator reuses the same signed Revo Uninstaller component and runtime dependencies, rotating only the msvcp140.dll morph and the carrier encoding. ^[manual hash comparison]
  • MSVC 14.27.29016.0 timestamp. The new msvcp140.dll carries a 2020-06-16 compilation timestamp, identical to the majority of prior morphs, suggesting the operator is drawing from a fixed pool of pre-compiled VC++ redistributable versions. ^[exiftool: dll1]

How To Mess With It (Homelab Replication)

Goal: Reproduce the poem-word-list steganography encoder/decoder.

Toolchain: Node.js LTS, any text editor.

Steps:

  1. Create a 256-word vocabulary list (English poem works well — it defeats entropy checks).
  2. For each byte of payload, emit the vocabulary word at index byte.
  3. For repeated words, append a numbered suffix (word1, word2, ...) to keep the lookup unambiguous while bloating file size.
  4. At runtime, split the vocabulary, build a word→index map, then map each payload word back to its index (byte value).
  5. Write the decoded bytes to disk with fs.writeFileSync.

Verification: The resulting .js file should be ~7–11 MB, contain no Base64 blobs, and decode to the same PE payload when run under Node.js.

Deployable Signatures

YARA Rule

rule letsdiskusscom_poem_stego_dropper {
    meta:
        description = "Node.js poem-word-list steganography dropper (letsdiskusscom cluster)"
        author = "PacketPursuit"
        date = "2026-08-24"
        sha256 = "50a8668bad8043c6fa7610f0fc8bb119dd998e183f20a15e78f32efee108a753"
        family = "letsdiskusscom"
    strings:
        $node_fs = "const fs = require('fs');"
        $node_path = "const path = require('path');"
        $node_spawn = "const { spawn } = require('child_process');"
        $app_name = "Microsoft Edge Updates Helper"
        $wlist = "const wlist = \"gentle"
        $exe = "const exe = \""
        $dll1 = "const dll1 = \""
        $dll2 = "const dll2 = \""
        $dll3 = "const dll3 = \""
        $bat = "const bat = \""
        $write_positions = "function writePositionsToFile(listA, listB, outPath)"
        $launch = "function launchExecutable(execPath, args = [])"
        $safe_mkdir = "function safeMakeDir(dir)"
    condition:
        filesize > 5MB and
        all of ($node_*) and
        $app_name and
        $wlist and
        $write_positions and
        $launch and
        $safe_mkdir and
        any of ($exe, $dll1, $dll2, $dll3, $bat)
}

Sigma Rule

title: letsdiskusscom Poem-Stego Dropper Execution
logsource:
    product: windows
    category: process_creation
detection:
    selection:
        CommandLine|contains:
            - 'Microsoft Edge Updates Helper'
            - 'jlEFdrhYiMC4.bat'
    condition: selection
falsepositives:
    - None expected; this directory name and BAT filename are unique to the cluster.
level: high

IOC List

Indicator Type Value Notes
Carrier SHA-256 Hash 50a8668bad8043c6fa7610f0fc8bb119dd998e183f20a15e78f32efee108a753 Update_6.js
Embedded EXE SHA-256 Hash 8b94af60bb58bc1629edb3b4f6a86ccff5769bb9b96d8826f06686af2d7fc55f RevoSrp.exe, invariant across cluster
Embedded DLL1 SHA-256 Hash 575bcf6ab68317b455284d92e44df912b19f31b6f9c35167db471b53f87142e5 msvcp140.dll, 26th distinct morph
Embedded DLL2 SHA-256 Hash ff43e813785ee948a937b642b03050bb4b1c6a5e23049646b891a66f65d4c833 vcruntime140.dll, invariant
Embedded DLL3 SHA-256 Hash 7b8f70dd3bdae110e61823d1ca6fd8955a5617119f5405cdd6b14cad3656dfc7 vcruntime140_1.dll, invariant
Staging directory Path %ProgramData%\Microsoft Edge Updates Helper * Randomized suffix per sample
Registry Run value Registry HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Microsoft Edge Updates Helper Added by BAT
BAT filename File jlEFdrhYiMC4.bat Randomized per sample

Behavioral Fingerprint

This binary is a Node.js script that requires fs, path, and child_process, creates a directory under %ProgramData% with a name containing Microsoft Edge Updates Helper, decodes embedded payloads from a poem-word lookup table, writes a signed EXE and three signed VC++ runtime DLLs to disk, writes a BAT file that adds the EXE to HKCU\Run, then spawns both the BAT and the EXE. No network activity from the carrier. File size is typically 7–11 MB. The poem vocabulary includes words like gentle, hush, midnight, moonlight, stitches, silver.

Detection Signatures

Capability ATT&CK ID Evidence
JavaScript execution T1059.007 require('fs'), require('child_process') ^[strings.txt:1-3]
Obfuscated Files or Info T1027.002 Poem-word-list steganography with numbered suffixes ^[strings.txt:6-40]
Masquerading T1036.005 Microsoft Edge Updates Helper directory and registry value ^[strings.txt:4]
Registry Run Keys T1547.001 BAT calls reg add on HKCU\...\Run ^[decoded BAT]
Create/modify system process T1543.003 child_process.spawn(..., {shell: true}) ^[strings.txt:78-80]

References

  • entities/letsdiskusscom.md — Cluster entity page (25 prior siblings documented)
  • techniques/poem-word-list-steganography.md — 256-word poem encoding technique
  • procedures/registry-run-persistence.md — BAT-based Run key procedure
  • concepts/natural-language-payload-encoding.md — Cross-family prose-based payload hiding

Provenance

  • file.txt — file utility output (file type, size)
  • triage.json — Triage pipeline metadata (family, tier, source)
  • strings.txt — Full script source (7.4 MB of JS strings)
  • dynamic-analysis.md — CAPE sandbox status (skipped)
  • Manual hash comparison across 25 prior sibling reports in raw/analyses/
  • exiftool run on decoded DLL1 (msvcp140.dll) at /tmp/msvcp140_50a8668b.dll
  • Decoded BAT content verified via Python re-implementation of writePositionsToFile