Volver al hub

LeakNet Campaign: Deno Runtime & Klist Suspicious Execution Detection

Detects indicators of the LeakNet campaign (analyzed by ReliaQuest, March 2026), which uses ClickFix a social engineering tactic where compromised websites display fake error dialogs that coerce users into manually pasting and executing a malicious PowerShell/CMD command. This delivers a portable Deno (JavaScript runtime) binary to user-writable directories that runs malicious payloads entirely in memory, avoiding disk-based detection. The query targets the post-delivery kill chain: Deno execution from AppData/Temp/ProgramData paths, klist.exe usage from interactive shells indicating Kerberos ticket harvesting, Deno spawning reconnaissance and living-off-the-land binaries, and dangerous Deno runtime flags or remote code fetch patterns. A noise reduction filter excludes Deno running from standard developer or Program Files paths.

EDRhuntingdetectionT1204.001T1059
FDR intermediatepor cap10 (cql-hub.com) 2 min read

Query

#event_simpleName=ProcessRollup2
| (
    /* ── Clause 1: Deno launched from user-writable locations ── */
    (
      ImageFileName=/\\deno(\.exe)?$/i
      AND ImageFileName=/\\(Users\\[^\\]+\\AppData\\(Local|Roaming)|Temp|ProgramData)\\/i
    )

    OR

    /* ── Clause 2: klist launched from interactive shells or script hosts ── */
    (
      ImageFileName=/\\klist\.exe$/i
      AND ParentBaseFileName=/^(cmd|powershell|pwsh|wscript|cscript|mshta)\.exe$/i
    )

    OR

    /* ── Clause 3: Suspicious child processes spawned by Deno ── */
    (
      ParentBaseFileName=/^deno(\.exe)?$/i
      AND ImageFileName=/\\(cmd|powershell|pwsh|net|net1|whoami|hostname|nltest|dsquery|quser|qwinsta|vssadmin|wbadmin|reg|wevtutil|ipconfig|systeminfo|tasklist|qprocess|schtasks|wmic|bitsadmin|certutil)\.exe$/i
    )

    OR

    /* ── Clause 4: Deno with dangerous flags or remote code execution patterns ── */
    (
      ImageFileName=/\\deno(\.exe)?$/i
      AND CommandLine=/(eval|--allow-all|--allow-net|--allow-run|https?:\/\/|atob\(|base64|WebSocket|fetch\()/i
    )
  )

/* ── Noise reduction: exclude Deno running from known-good install/dev paths ── */
| !(
    ImageFileName=/\\deno(\.exe)?$/i
    AND ImageFileName=/\\(Program Files|Program Files \(x86\)|tools|dev|repos|source|git)\\/i
  )

| table([@timestamp, aid, ComputerName, UserName, ParentBaseFileName, ImageFileName, CommandLine, SHA256HashData])
| sort(@timestamp, order=desc)

//══════════════════════════════════════════════════════════════════════════════════════════════════
// ENHANCEMENT OPTIONS
//══════════════════════════════════════════════════════════════════════════════════════════════════
//
// ── Option A: Correlate Deno process execution with outbound network connections ──
// Uses selfJoinFilter to link ProcessRollup2 with NetworkConnectIP4 on the same
// agent and process ID, then filters out internal RFC1918/loopback traffic.
//
//   #event_simpleName = /ProcessRollup2|NetworkConnectIP4/
//   | falconPID := ContextProcessId_decimal
//   | falconPID := TargetProcessId_decimal
//   | selfJoinFilter(field=[aid, falconPID], where=[
//       {#event_simpleName = ProcessRollup2 | ImageFileName = /\\deno(\.exe)?$/i},
//       {#event_simpleName = NetworkConnectIP4}
//   ])
//   | RemoteAddressIP4 != "10.*"
//   | RemoteAddressIP4 != "172.16.*"
//   | RemoteAddressIP4 != "192.168.*"
//   | RemoteAddressIP4 != "127.*"
//   | groupBy([aid, ComputerName, ImageFileName, RemoteAddressIP4, RemotePort], function=[count(), collect(CommandLine)])
//   | sort(_count, order=desc)
//
// ── Option B: Correlate Deno with DNS requests for domain-based C2 detection ──
//
//   #event_simpleName = /ProcessRollup2|DnsRequest/
//   | falconPID := ContextProcessId
//   | falconPID := TargetProcessId
//   | selfJoinFilter(field=[aid, falconPID], where=[
//       {#event_simpleName = ProcessRollup2 | ImageFileName = /\\deno(\.exe)?$/i},
//       {#event_simpleName = DnsRequest}
//   ])
//   | groupBy([aid, ComputerName, DomainName], function=[count(), collect(CommandLine)])
//   | sort(_count, order=desc)
//
// ── Option C: Group by user to surface high-frequency discovery bursts ──
//
//   // Append after the main query's table() line:
//   // | groupBy([UserName, ComputerName], function=count(as=exec_count))
//   // | sort(exec_count, order=desc)
//   // | test(exec_count > 5)
//
//══════════════════════════════════════════════════════════════════════════════════════════════════

Explicación

Importado desde cql-hub.com. Agrega explicación de pipes aquí.

Variables a ajustar

Revisa y ajusta los valores según tu entorno.