Skip to content

[pull] master from kevoreilly:master#457

Merged
pull[bot] merged 7 commits intothreatcode:masterfrom
kevoreilly:master
Apr 21, 2026
Merged

[pull] master from kevoreilly:master#457
pull[bot] merged 7 commits intothreatcode:masterfrom
kevoreilly:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Apr 21, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

wmetcalf and others added 7 commits April 20, 2026 09:24
Tie every network artifact CAPE captures (suricata alerts/tls/http/files,
network.tcp/udp/dns/hosts) back to the originating Windows process so
analysts and downstream signatures can answer "which process did this?"
without manual correlation work.

Sources, in confidence order:

  1. Sysmon Event ID 3 (NetworkConnect) from evtx.zip — full image path,
     destination hostname, src/dst 5-tuple
  2. Microsoft-Windows-Kernel-Network ETW captured live by a new analyzer
     auxiliary, periodically uploaded so attribution survives crashes
  3. Sigma EID 3 matched events — tertiary catch for late-fire flows
  4. DNS-Client ETW (originating-process DNS) cross-referenced with
     suricata.dns/network.dns/network.hosts/sigma EID 22 QueryResults
     to attribute IPs we never saw a direct connect for. Avoids the
     "everything routes to svchost (dnscache)" failure mode.
  5. Sysmon EID 22 (DnsQuery) — covers queries that fired before the
     DNS-ETW auxiliary subscribed (early CDN resolutions, etc.)
  6. Sysmon EID 1 (ProcessCreate) — names processes that aren't
     monitored by capemon but show up in connection/DNS data

A single AttributionIndex consumes all sources; per-target enrichment
(suricata.alerts/tls/http/files, network.tcp/udp/dns/hosts, sigma
detections) goes through one of four query methods. 5-tuple matching
with src_port disambiguates multi-process flows to the same destination.

New analyzer aux:
  analyzer/windows/modules/auxiliary/network_etw.py
    Captures TCP/UDP connect events from Microsoft-Windows-Kernel-Network
    with periodic full-snapshot uploads. Off by default in
    auxiliary.conf.default — opt-in with [Network_ETW] enabled = yes.

Stop-priority on Network_ETW + Evtx:
  Set stop_priority = -20 so they shut down AFTER the capemon-related
  auxiliaries. Late-fire C2 callbacks that fire between the analysis-
  stop signal and VM teardown still get captured + attributed.

Result-server transport:
  resultserver.py refactor (allowlisted RESULT_UPLOADABLE +
  RESULT_DIRECTORIES) tightens path-traversal protection and adds an
  is_replaceable_result_upload() helper so periodic re-uploads from
  the auxiliaries (tlsdump.log, dns_etw.json, network_etw.json,
  wmi_etw.json, sslkeylogfile/sslkeys.log) truncate-write instead of
  silently failing with EEXIST after the first upload.

Decryption pipeline:
  decryptpcap.py wraps gogorobocap to produce dump_decrypted.pcap +
  dump_mixed.pcap. network.py + suricata.py honour a new pcapsrc
  config knob (auto/original/mixed/decrypted) so users explicitly
  choose which pcap variant to analyse.

UI:
  _suricata_http.html, _suricata_files.html, _hosts.html render
  process attribution columns/rows, gated on the existing
  NETWORK_PROC_MAP setting. _hosts.html shows multi-process attribution
  as badges with hover tooltips that explain the attribution chain
  (direct connect / DNS-resolved / etc). Pre-existing "asn cell skipped
  when empty causes column shift" bug fixed in the same edit.

Tests:
  tests/test_network_capture_integration.py covers AttributionIndex
  build + query, pcapsrc resolution, and replaceable-upload behaviour.
* Gate _suricata_http.html and _suricata_files.html Process columns on
  NETWORK_PROC_MAP (consistent with _hosts.html and per the PR description).
* _hosts.html: fall back to legacy host.process_name / host.process_id when
  host.processes is missing (preserves existing process_map enrichment for
  users who don't run the network_etw module).
* network_etw.py: include IPv6 unspecified address ":" in the localhost
  filter; lowercase hostnames in for_http / set_http_owner; strip
  whitespace from XML element text in _read_evt_data; correct docstring
  on _parse_kernel_network_etw (was naming the wrong auxiliary); store
  basename + path separately when hoisting sigma matched_events processes.
* analyzer/network_etw.py: same IPv6 ":" filter; clean up the random
  C:\<dir> output directory after the final upload so it doesn't
  accumulate on VMs that aren't reverted from snapshot.
* test_network_capture_integration.py: assert against the actually-patched
  open mock (and that open_exclusive is NOT called for replaceable
  uploads); document the sys.modules stub pattern.

Note: the gemini-code-assist suggestion to rename ProcessID -> ProcessId
in sigma matched_events lookups was checked against real sigma output
on three different reports — sigma's matched_events use ProcessID
(capital D). Existing code is correct; suggestion not applied.
Removed unused import of 'socket' and 'encode'.
Removed unused import statements from the test file.
Removed configuration for decrypting PCAP files.
Process-to-network attribution for sandbox analyses
@pull pull Bot locked and limited conversation to collaborators Apr 21, 2026
@pull pull Bot added the ⤵️ pull label Apr 21, 2026
@pull pull Bot merged commit 976b369 into threatcode:master Apr 21, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants