No detection rule fired.
The hunt found 9 compromised hosts.
A seven-day cross-boundary hunt for Living-off-the-Land attacks. The agent followed PowerShell into
.NET compilation, into net1 accounts enumeration bursts, into a banking trojan, a
keylogger, and a staged wiper. Nine hosts confirmed compromised across Windows, Linux, and
AWS. One suspected user compromise the existing detection stack had no record of.
status_id null on every detection record. Confirmed connector architectural gap.This case starts from a hypothesis, not an alert. The agent’s specialists assemble cross-boundary evidence that no alert modeled in advance. Severity 8.9 in an environment where status_id is null on every detection.
The wiper is staged but not detonated. The credential recon has completed but the spray hasn’t started. The keylogger is loaded but the data hasn’t left. This is the moment a hunt is for.
Windows + Linux + AWS + identity in one investigation. Mesh-level scope is what made the four-phase narrative possible. Single-domain hunts close before the picture forms.
Find the attack before the alert fires.
Living-off-the-Land tradecraft uses legitimate system tools (PowerShell, certutil, bitsadmin, rundll32, cron, ld.so.preload) to execute attacker objectives without dropping recognizable malware. Signature-based detection misses it. Single-domain hunts miss it. The hunt is worth running precisely because if alerts were going to fire, they already would have.
The agent’s scope: seven-day window, two OS families, four telemetry domains (endpoint, identity, cloud, network). The intake query confirmed worst-case visibility:
Without a working status filter, the hunt’s value isn’t filtering unresolved alerts. It’s finding patterns no alert ever modeled.
Staging. Compilation. Reconnaissance. Suspected compromise.
The agent’s specialists (classifier, lotl-detector, identity-investigator, enricher) assembled a four-phase picture of an active campaign in pre-detonation staging across nine hosts.
/etc/ld.so.preload on Linux. DOS.Yesmile wiper staged on Windows. AppInit_DLLs persistence on DESKTOP-353.powershell → cvtres /OUT:RES[hex].tmp across 4 Windows hosts. Sustained hundreds of events. Cobalt Strike / Empire signature.net1 accounts burst (10+ calls in 30-60s). SYSTEM-level token. Staggered across 5h. Methodical, not blast.travis.b*** in detection + data-security findings. Zero authentication events via actor path. Pass-the-hash hypothesis.
The highest-yield query in the entire investigation was the cross-host PowerShell process_activity
sweep, 380,918 characters returned, with the cvtres.exe compilation pattern present
on all four Windows hosts simultaneously beginning at 2026-05-14T17:00:
The powershell.exe → cvtres.exe /NOLOGO /READONLY /MACHINE:IX86 /OUT: C:\Windows\TEMP\RES[hex].tmp
sequence with random temp filenames is the standard signature of inline C# payload compilation —
Cobalt Strike, Empire, and Metasploit all produce it when using Add-Type
or Invoke-Expression with embedded C# source.
Cross-boundary means cross-blind-spot.
| Host | OS | Status | Key finding |
|---|---|---|---|
| ubuntu-platform-626 | Linux | SENSOR GAP | Keylogger.zip via /etc/ld.so.preload (FATAL). Process telemetry sensor returned 327 chars, likely tampered or offline. |
| EC2AMAZ-GS16M39 | Windows / AWS | VERIFIED | ZeusBankingVersion_26Nov2013.zip (HIGH). Production AWS instance compromised with banking trojan. |
| WS-659 | Windows | VERIFIED | DOS.Yesmile.zip wiper staged in svchost path (FATAL). Not yet detonated. |
| DESKTOP-353 | Windows | VERIFIED | HKLM AppInit_DLLs persistence, android-cts zip injected into every GUI process. |
| WS-879 | Windows | VERIFIED | Catapillar.zip detected (HIGH). Payload classification under investigation. |
| newschrutefarms | Windows | VERIFIED | net1 accounts burst, 07:49:59–07:50:31, 10+ calls in 32 seconds. SYSTEM token. |
| EC2AMAZ-93G20K9 | Windows / AWS | VERIFIED | net1 accounts burst, 12:35:29–12:36:06. |
| scrantonbranch | Windows | VERIFIED | net1 accounts burst, 12:41:23–12:41:53. Three bursts staggered across 5 hours. |
| rhel-mlops-164 | Linux / ML | UNVERIFIABLE | Zero records returned (1d window). 7-day query timed out. Cannot distinguish clean from sensor-offline. |
Banking trojan on AWS, keylogger on Linux, wiper on Windows, automated enumeration on three more. That range is the cross-boundary tell. No single-domain tool sees the whole shape. The mesh-level hunt does.
Active in findings. Absent from authentication.
One signal jumped from the cross-source view: account travis.b*** appears in
detection_finding (Query #22) and data_security_finding (Query #33, 1,137
chars, file-level security events). But the same account’s authentication telemetry returned 327
characters. Zero substantive auth events when queried via the actor.user.name path.
For a user actively appearing in detection and data-security events, missing authentication telemetry is itself a finding. Three explanations, all of which elevate risk:
- Log forwarding gap for the account’s source system (low risk if isolated).
- Service or machine account authenticating via Kerberos/NTLM without interactive session logging (medium risk).
- Pass-the-hash or pass-the-ticket lateral movement. No interactive auth event because the attacker is reusing a harvested token (high risk, consistent with the campaign’s enumeration phase).
The agent did not declare a verdict. It listed all three explanations, named pass-the-hash as consistent with the rest of the evidence, and recommended disabling the account while the investigation continues.
The single highest-value query is a cross-host process sweep.
One query (Q49), process_activity ICONTAINS ‘powershell’ AFTER 1d, returned the cvtres compilation pattern across four Windows hosts simultaneously. The shape was the finding. Cross-host process_activity is the highest-leverage query when hunting from technique hypotheses.
Absence is evidence.
travis.b*** active in detection + data-security findings but absent from authentication telemetry. The absence is what raised the pass-the-hash hypothesis. The agent did not invent positive evidence. It surfaced the gap as a finding.
Sensor offline ≠ host clean.
ubuntu-platform-626 has a FATAL keylogger detection and a process telemetry sensor that returned 327 chars. Treating “no process data” as “host healthy” would have closed the loudest finding in the hunt. The agent treats sensor gaps as elevated risk, not silence.
Cross-boundary is non-negotiable for LOTL.
This campaign spans Windows, Linux, AWS, and identity simultaneously. A single-domain hunt sees a fragment and concludes the fragment is the threat. Mesh-level scope is the only way to see the whole picture.
Key queries across the hunt
Q49PowerShell process_activity sweep, highest-yield queryCORE FINDING
Q22HIGH/CRITICAL/FATAL detection sweep (7d)11,630 CHARS
Q34Outbound network activity for 192.168.191.15925 KB
Q54Authentication via actor path, travis.b*** (7d)NEAR-EMPTY
Q55account_change events for net1-burst hostsCONNECTOR GAP
account_change event type not supported by any connector. Zero visibility into backdoor accounts / MFA changes during enumeration windows.
Showing 5 of 67 tool calls (21 queries + 10 remediation pass + 36 specialist sub-queries). Full audit trail in queries.md.
Sources queried · with status
| Source | Status | Notes |
|---|---|---|
| detection.alerts (all connectors) | PARTIAL | 11,630 chars across 6 hosts; status_id null on every record |
| process_activity (mesh-wide) | HIT | 380,918 chars. cvtres + net1 patterns confirmed cross-host |
| process_activity (ubuntu-platform-626) | SENSOR GAP | 327 chars (3d window), sensor effectively offline |
| data_security_finding (DLP) | HIT | travis.b*** file-level events confirmed |
| network_activity | PARTIAL | 25 KB outbound from 192.168.191.159, schema extraction deferred |
| authentication (actor.user.name) | GAP | travis.b*** returns 0 substantive events, load-bearing absence |
| account_change (any connector) | GAP | Event type not supported, backdoor account creation invisible |
Gaps explicitly catalogued
- status_id null on every detection record: connector architectural gap. NEW vs RESOLVED bucketing structurally impossible.
- ubuntu-platform-626 process telemetry: sensor returns 327 chars. Most likely tampered post-compromise.
- rhel-mlops-164 unverifiable: 0 records on 1d window; 7d query timed out. Could be clean or compromised; cannot tell.
- 192.168.191.159 destinations not extracted: Q34 returned 25 KB, schema extraction deferred. Follow-up query validated and ready.
- travis.b*** authentication absent: via actor path. Compromise inference based on circumstantial evidence.
- account_change connector unsupported: no visibility into post-enumeration credential persistence.
Run Workers against your environment.
Bring a hypothesis or a technique to hunt.
