Research note N.12 · 2026-10-16

How we would hunt ourselves.

Every implant obeys a conservation law: execution leaves evidence somewhere, and evasion only chooses where. This note inverts our usual vantage. Instead of how the agent survives the stack, here is how we would hunt it — memory signatures, beacon periodicity, named-pipe hygiene — and the telemetry gaps we deliberately leave, because a product that claims to leave none is a product that is lying.

READ TIME ≈ 8 MIN AUTHOR THE AXIS TEAM

The conservation law

Detection engineering against an in-memory C2 starts from one axiom: nothing is invisible; evidence is conserved. A bypass does not delete the signal — it moves the signal to a layer the sensor is not watching, which is the whole argument of the previous note. So the hunter's first question is not is there an implant but which layer did this implant choose to pay in. Four hunting grounds cover most of the ledger: the shape of memory, the rhythm of time, the named-pipe table, and the wire. We will walk each one the way we would walk it against ourselves — what we spend there, what survives anyway, and the rule we would write.

Memory: hunt the shape, not the bytes

Byte signatures die young against our agent, and we know why better than anyone: at rest it encrypts and unmaps itself — registered regions XOR-locked with a per-sleep key, paged PAGE_NOACCESS, the key zeroed on wake; modules arrive keyed per build and are wiped, not freed, on unload. So we would not scan for bytes. We would scan for the shape of the hiding: private PAGE_NOACCESS regions inside a process that also holds unbacked executable memory; committed private pages that map to no module on disk; timer-queue registrations on a process that never had them before; a thread whose start address no longer resolves to anything; a DOS header that has been stomped — wiping MZ removes a signature and installs an anomaly, and anomalies are rule-worthy. None of these convict alone. All of them cluster, and clustering is what detection engineering is.

Encrypted bytes are safe bytes. A hidden shape is not a hidden thing.

Periodicity: jitter loses to statistics

The folklore says jitter defeats the hunter. It defeats a stopwatch; it does not defeat a distribution. A beacon with generous jitter still clusters around its mean; a session still opens with a handshake of characteristic size; tasking still arrives in bursts timed by an operator's workday, not by a human's browsing. Given a month of netflow, we would never look for an interval — we would look for autocorrelation: the host that keeps time like a machine, however fuzzy the metronome. What we spend against this: a per-build traffic profile, session-identity rotation on a fixed cadence, and a dual-pool architecture that separates tasking from payload delivery. What survives anyway: rotation resets the implant's identity, not its behavior — byte-count cadence and session rhythm outlive every rename. Follow the shape of the session, not the name of the implant.

The hunter's stopwatchStatusWhat survives jitter
Fixed-interval timersdeadInterval distribution around a mean
Known-bad destinationsdeadHandshake and session byte counts
Implant identity, per sessiondeadSession rhythm across rotations
Static TLS fingerprintspentTasking bursts vs. human hours
Fig. A — the stopwatch, retiredJitter is a costume; the distribution is the face

Named pipes: the table everyone forgets

SMB pivots live in the pipe table, and the pipe table is public reading. Every SMB beacon is a named pipe; every named pipe is a row the operating system will happily enumerate for any defender who asks. We would ask. The hunt writes itself: pipe names with generated entropy, or names that imitate well-known system pipes but are owned by the wrong process; pipes created by userland processes that have no service reason to create one; ACLs hardened past what the pipe's alleged purpose needs; pipe lifetimes that correlate with session windows. Our own doctrine is hygiene — profile-named pipes, tight ACLs, teardown when the task ends — and we are honest about what hygiene buys: it shrinks the row; it cannot delete it. A baseline of pipe names per host role, diffed daily, catches the class. The implant can be polite about it. It cannot be absent from it.

The gaps we leave on purpose

Here is the part most vendors skip. A resident agent must hold memory somewhere. A C2 must move bytes. A session has a first packet. A pivot has a process that opened a handle it never needed before. We do not claim otherwise — not in the panel, not in the docs, not here. What we choose is where our evidence lives: away from the layers that convict by default — hooked user-mode APIs, unsigned binaries on disk, child-process lineage — and into the layers that require a hunter with budget and patience: VAD audits, statistical traffic analysis, pipe-table baselining. That choice is the product. The rest is adjectives.

LayerWe spendWe concede
User-mode APIIndirect syscalls, routed around hooksThe kernel still logs the call
Memory at restEncrypted, unmapped, key zeroedThe silhouette of the hiding
TimingJitter, per-build traffic profilesThe distribution underneath
IdentitySession-identity rotationThe session's shape across rotations
PivotsNamed, ACL'd, torn-down pipesThe row exists while it lives
Fig. B — the concession ledgerPublished so defenders can price us, and buyers can check our math

The defender's angle

If we ran the hunt, the notebook would have four questions, in this order — and we publish them because a customer who can verify our claims is worth ten who believe them:

hunter's notebook — four questions, in ordercategory level, as always
// 1. where does this process keep its secrets?
vad_audit(host)  // private NOACCESS + unbacked RX, timer queues, orphan threads
// 2. does this host keep time like a machine?
autocorr(sessions, 30d)  // distributions, not intervals; byte-count cadence
// 3. who owns this pipe, and since when?
pipe_baseline(role)  // new owners, imitative names, over-tight ACLs
// 4. what stopped talking when this started?
silence_corr(etw, sysmon)  // absent telemetry is telemetry — see N.09, N.11

Write these four as scheduled hunts and the concession ledger above becomes your shopping list. We would rather be caught by teams running this notebook than heard about through adjectives — and we would rather our detection surface be a documented engineering trade than a marketing secret. That is what measured, not marketed means when the sentence has to survive contact with the people hunting us.

Next note: Eight ways to survive a reboot, priced. The persistence audit — the eight autostart locations we ship, what each costs under modern telemetry, and why Run and RunOnce count as one row.