typeanalysisfamilyletsdiskusscomconfidencehighcreated2026-08-24updated2026-08-24scriptnodejsobfuscationevasionpersistencemalware-family
SHA-256: bfc9e6e703793e0fd480b98a95351d1b3b5c64bcf6ecf0afece8064a8954b316

letsdiskusscom: bfc9e6e7 — Twenty-fourth confirmed sibling, Update_4.js poem-stego dropper (largest in cluster)

Executive Summary

An 11 MB Node.js self-extracting dropper (Update_4.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-fourth confirmed sibling in the letsdiskusscom cluster — and the largest by file size at 11,086,748 bytes. 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 bfc9e6e703793e0fd480b98a95351d1b3b5c64bcf6ecf0afece8064a8954b316
Filename Update_4.js
File type JavaScript source, ASCII text, CRLF line terminators ^[file.txt]
Size 11,086,748 bytes (11 MB)
ssdeep 6144:rubnYpscL3SqA5mPYsTvQw1z8jBZlLtH+Bp89S5mfsowpNWVwS0msFJvXiESUWj6:NP3kO ^[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/bfc9e6e703793e0fd480b98a95351d1b3b5c64bcf6ecf0afece8064a8954b316/exe.bin] | | msvcp140.dll | 1,378,304 B | d58de9dc9a1404d1597ba8c68e9a284cd302c08cc244f559ee5cb2aa75444bb9 | MSVC 14.27.29016.0, compiled 2020-06-16 (timestamp 0x5EE83852). PE32+ x64. Twenty-fourth distinct morph in cluster. ^[raw/analyses/bfc9e6e703793e0fd480b98a95351d1b3b5c64bcf6ecf0afece8064a8954b316/dll1.bin] | | vcruntime140.dll | 101,672 B | ff43e813785ee948a937b642b03050bb4b1c6a5e23049646b891a66f65d4c833 | Same as all 23 prior siblings | | vcruntime140_1.dll | 44,328 B | 7b8f70dd3bdae110e61823d1ca6fd8955a5617119f5405cdd6b14cad3656dfc7 | Same as all 23 prior siblings | | vIQNgHpMmTiD.bat | 440 B | dff20059f161090c76f9f45ac2269f2965bdc96023c78c1072f8d1aa66b06919 | HKCU Run persistence — adds "Microsoft Edge Updates Helper" pointing to EXE path |

Execution Chain

  1. Creates %ProgramData%\Microsoft Edge Updates Helper vIQNgHpMmTiD with mode 0o755. ^[strings.txt:27]
  2. Decodes all five payloads from poem-word indices to disk via writePositionsToFile. ^[strings.txt:18]
  3. Launches the BAT file with the EXE path as argument — BAT adds HKCU\Software\Microsoft\Windows\CurrentVersion\Run entry. ^[strings.txt:30]
  4. 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

  • Largest in cluster: At 11,086,748 bytes, this is the largest letsdiskusscom sibling observed. The size inflation comes from the encoded payload strings, not the lookup table, suggesting the builder pads or the msvcp140.dll morph is simply larger. ^[triage.json]
  • Build counter gap fill: Filename Update_4.js fills a gap between Update_1.js (bf5c69a5) and Update_5.js (b53d6a32). Combined with Update_9.js (5ebd96a1), 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), and Update_25.js (1fbaf8ab), the internal counter now spans 1–25 with only Update_2, Update_6–Update_8, Update_10–Update_11, Update_20–Update_21, and Update_23–Update_24 unobserved. The builder is clearly producing large batches. ^[triage.json]
  • Template artifact — dll4Path: A fourth DLL path is computed (vIQNgHpMmTiD.bat) but never passed to writePositionsToFile. The BAT path is already handled by the bat variable. This suggests a builder template that optionally emits four DLLs, and this build left the fourth slot empty. ^[strings.txt:17]
  • module.exports dead code: The script ends with module.exports = writePositionsToFile;, which has no effect in a standalone .js file 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-fourth 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. The 1,378,304-byte size is notably larger than most prior morphs (~900 KB–1.1 MB range). ^[raw/analyses/bfc9e6e703793e0fd480b98a95351d1b3b5c64bcf6ecf0afece8064a8954b316/dll1.bin]

How To Mess With It (Homelab Replication)

  1. Create a 256-word lookup table with numbered suffixes after the first cycle:
    gentle1 hush2 that3 wraps4 ... fail164
    
  2. Encode a file:
    words = lookup.split()
    with open('payload.exe','rb') as f:
        data = f.read()
    encoded = ' '.join(words[b] for b in data)
    
  3. Carrier script: Wrap in a Node.js file using the writePositionsToFile pattern with fs.writeFileSync and child_process.spawn.
  4. Verify: Decode the poem string back to the original payload; compare SHA-256.
  5. 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/bfc9e6e703793e0fd480b98a95351d1b3b5c64bcf6ecf0afece8064a8954b316.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'
        - 'vIQNgHpMmTiD'
        - 'writePositionsToFile'
  selection2:
    - ParentImage|endswith: 'node.exe'
    - Image|endswith:
        - 'reg.exe'
        - 'cmd.exe'
    - CommandLine|contains:
        - 'Microsoft Edge Updates Helper'
        - 'vIQNgHpMmTiD'
  condition: selection or selection2
falsepositives:
  - Unknown
level: high

IOC List

Indicator Type Value
SHA-256 Hash bfc9e6e703793e0fd480b98a95351d1b3b5c64bcf6ecf0afece8064a8954b316
Filename String Update_4.js
Staging directory Path %ProgramData%\Microsoft Edge Updates Helper vIQNgHpMmTiD
Registry key Registry HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Microsoft Edge Updates Helper
Revo payload Hash 8b94af60bb58bc1629edb3b4f6a86ccff5769bb9b96d8826f06686af2d7fc55f
msvcp140.dll (this build) Hash d58de9dc9a1404d1597ba8c68e9a284cd302c08cc244f559ee5cb2aa75444bb9
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-four 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: bfc9e6e703793e0fd480b98a95351d1b3b5c64bcf6ecf0afece8064a8954b316 (Update_4.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. PE headers inspected with pefile 2023.2.7. 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-24.