Persistence and post-exploitation
Code execution is the start, not the win. Attackers spend most of their dwell time on persistence, lateral movement, and exfiltration — each a noisy step a defender can catch.
A red team lands code execution on one CI runner at 02:14. By the time the engagement debrief runs three weeks later, the question nobody on the blue team can answer cleanly is: what did they do between 02:14 and now? The shell was the easy part — minutes of work. The other twenty-one days were spent quietly: a scheduled task that re-spawns the implant every reboot, a service account’s token reused to hop to the build server, a deploy key copied to read a private repo, gigabytes of source dribbled out 8KB at a time inside what looked like ordinary HTTPS telemetry. None of it tripped a single alert. That gap — minutes to break in, weeks to get caught — is the real subject of this lesson. The break-in is loud and brief; everything an attacker actually wants happens after, and almost all of it is detectable if you know what it looks like.
By the end of this lesson you’ll know what an attacker does after getting a shell — persistence, lateral movement, and exfiltration — and the detection signal each step leaves for a defender to catch.
Authorization first — this is the defender’s map, not a runbook
Everything below describes the post-exploitation lifecycle — what an intruder does once they already have code running — taught so you can detect and disrupt it. There is no attack tooling here, and you don’t need any to understand the mechanism: persistence, lateral movement, and exfiltration are behaviors that leave traces, and the entire point is learning to recognize those traces in your own logs. The only legitimate place to actually exercise these techniques is an authorized engagement with written scope, a CTF, or a lab you built. In MITRE ATT&CK terms, the moment we pick up — code is running on one host — is the handoff from Execution into the long tail of Persistence (TA0003), Lateral Movement, Collection, and Exfiltration. We study the chain so a defender can break it at any link, because breaking it at any one link defeats the whole operation.
The breach is a beachhead, not the objective
The single most common junior misconception about offensive security is that “popping a shell” is the win. It is not — it is the start of the work. A foothold on a single, often low-value host (a build agent, a marketing CMS box, an intern’s laptop) almost never sits where the attacker’s actual objective lives. The objective is the customer database, the signing keys, the cloud admin role, the source repo. The entire post-exploitation phase is the gap between where you landed and what you came for, and it decomposes into a handful of repeating goals: stay (survive a reboot, a logout, a password reset), understand (where am I, what can this account reach), spread (move toward the objective host by reusing what I find), and take (collect and exfiltrate the data) — usually while staying quiet enough to do all of it before anyone notices.
This is why dwell time — the interval between initial compromise and detection — is the metric the whole defensive industry obsesses over. Industry reports have for years measured global median dwell time in the range of roughly one to three weeks, down from many months a decade ago but still vast: weeks is enough to map an entire network, find the crown jewels, and leave. Every day of dwell time is a day the attacker spends in the post-exploitation phase — which means every detection you place in that phase is a chance to cut the operation short long after the initial break-in succeeded.
Persistence: making the foothold survive
The first thing a competent attacker does after gaining execution is buy durability, because their initial access is fragile — a reboot, a crashed process, a rotated password, or a patched vulnerability can evict them at any moment. Persistence is any mechanism that re-establishes code execution automatically, so the attacker doesn’t have to re-exploit the original bug. The defining property of every persistence technique is the same: it hooks a legitimate, automatic execution trigger so the malicious code runs as a side effect of normal system behavior.
The triggers are mundane, which is exactly why they work. A scheduled task or cron job runs the implant every few minutes or every boot. A new or modified service / daemon starts it at system startup. A shell profile or autostart entry runs it at every login. On a compromised cloud or CI environment, persistence often looks even more innocuous: a new deploy key, a service-account token, an extra IAM user or access key, a malicious step quietly added to a pipeline definition — credentials and config that survive every reboot because they’re supposed to. The cloud-native version of “survive a reboot” is “survive being kicked out,” and an added access key does that perfectly: rotate the compromised password and the attacker still walks in through the key you didn’t know existed.
The detection signal is creation and modification of these triggers. A new cron entry, a new systemd unit, a new IAM access key, a new deploy key, a change to a pipeline file — each is a write to a sensitive, rarely-changed surface, and each is a high-signal alert. The defender’s leverage here is that persistence is one of the few attacker actions that must leave a durable artifact behind: the whole point is that something persists, so something is there to find.
| Post-ex stage (ATT&CK tactic) | What the attacker does | Detection signal for the defender |
|---|---|---|
| Persistence (TA0003) | New cron/service/login hook; added IAM key or deploy key | Writes to startup surfaces; new long-lived credential created |
| Discovery | Enumerate hosts, accounts, shares, cloud roles | Burst of enumeration API calls / scanning from one host |
| Credential access | Dump tokens, read secrets files, scrape memory | Reads of secret stores; access to credential material |
| Lateral movement | Reuse stolen creds to authenticate to the next host | Auth from an unusual source/identity pair; new east-west path |
| Collection / Exfiltration (TA0010) | Stage data, compress, send out slowly over an allowed channel | Anomalous outbound volume/destination; egress to new endpoint |
Lateral movement: spreading by reuse, not by re-exploiting
Once persistent, the attacker rarely needs another exploit. The dominant technique for reaching the objective is lateral movement by credential reuse: harvest a credential on the host you own — a cached password, a service-account token, an SSH key, a Kubernetes service-account JWT, a cloud access key sitting in an environment variable — and use it to authenticate to the next host as a legitimate user. This is the heart of why a single low-value foothold is so dangerous: networks are full of shared and over-scoped credentials, and one of them on your build agent may be the key to the artifact registry, which holds a key to production.
The mechanism that makes this devastating is trust topology. Most internal networks were built assuming “inside is safe,” so once you’re inside, services authenticate each other with long-lived shared secrets and flat reachability — any host can talk to any other. An attacker treats this as a graph: each compromised credential is an edge to a new node, and they walk the graph from the disposable beachhead toward the high-value target. The defensive counters are structural: network segmentation (so a CI box can’t reach the production database at all), least-privilege scoping (so a stolen token can do one thing, not everything), and short-lived / workload-bound credentials (so a harvested secret is useless minutes later or off its origin host). The detection signal is an authentication that’s normal in isolation but anomalous in context: this identity, from this source, to this destination, at this time, has never happened before. That east-west auth is the tell, because the credential is valid — only the path is new.
▸Why this works
Why is east-west (internal, host-to-host) traffic so much harder to monitor than north-south (in/out of the network)? Architecture and volume. North-south traffic funnels through a small number of chokepoints — the firewall, the proxy, the egress gateway — where you can afford deep inspection and rich logging. East-west traffic is everywhere at once: thousands of internal service-to-service calls, most of them legitimate and using valid credentials, with no natural chokepoint to inspect them at. Historically teams logged the perimeter and trusted the interior, which is precisely the assumption lateral movement exploits. This is the core motivation for zero-trust: stop treating “inside the network” as an authorization, authenticate and authorize every hop, and put policy enforcement on the east-west path so a valid credential on a wrong path is still denied. It moves the chokepoint from the perimeter to every connection.
Exfiltration: the last and most catchable mile
Collecting the target data is one thing; getting it out is another, and it’s where a careful attacker is most exposed — because data leaving the network is the one action that, by definition, has to cross a boundary you control. The craft of exfiltration is therefore about blending in: rather than open a suspicious connection to an unknown IP and push a 4GB tarball (which any egress monitor would flag instantly), the attacker tunnels the data out over a channel that’s already allowed and already noisy. The classic choices are HTTPS to a benign-looking domain, DNS queries (every network resolves DNS, and the data rides in the subdomain labels), or a trusted SaaS API the org already uses. They throttle the transfer to a trickle and spread it over hours or days, so the volume never spikes above the background.
The detection signal is the statistical shape of egress, not its content (which is encrypted): an unusual volume of outbound data, a new or rare destination, a long-lived low-and-slow connection, or DNS traffic with abnormally high query entropy and volume to one domain. This is why egress filtering and DLP are the last line: a host that should only ever talk to two internal services has no business opening a connection to the open internet, and an allowlist-by-default egress policy turns “blend into allowed traffic” into “there is no allowed traffic to blend into.” The defender’s structural win is the same one that appears at every stage — make the legitimate paths few and explicit, so the anomalous one stands out instead of hiding in a sea of permitted noise.
Red team got code execution on a CI runner. You can fund exactly one structural control this quarter to most reduce the damage of THIS class of foothold reaching production. Pick it.
How a senior reads the post-exploitation chain
The unifying lesson is that detection-in-depth mirrors defense-in-depth: the attacker has to chain many steps, and each one is a separate chance to catch them. A senior doesn’t bet everything on preventing the initial breach — breaches happen — but instruments the after: alert on new persistence artifacts, on anomalous east-west authentication, on reads of secret stores, and on the statistical shape of egress. Equally, a senior shrinks the chain structurally so each remaining step is louder: segmentation removes lateral edges, least privilege shrinks what a stolen credential buys, short-lived credentials expire the loot, and allowlist egress removes the cover that exfiltration hides in. The thing to internalize is that catching the attacker anywhere in the post-exploitation chain defeats the operation — so dwell time isn’t a measure of how good your perimeter is, it’s a measure of how well you watch what happens after it’s already been crossed.
An attacker compromises a low-value CI build agent that has no access to customer data. Why is this still a serious incident?
A defender wants the single highest-signal place to detect persistence. Which is it, and why?
Order a typical post-exploitation chain, from the moment code first runs to the data leaving the network:
- 1 Code execution on one initial, often low-value host
- 2 Establish persistence so the foothold survives a reboot
- 3 Harvest credentials and move laterally toward the objective host
- 4 Collect the target data and exfiltrate it slowly over an allowed channel
- 01Explain why 'popping a shell' is the start of the work, not the win, and what the four repeating goals of post-exploitation are.
- 02How does lateral movement by credential reuse work, why does flat trust topology make it devastating, and what are the structural defenses?
Code execution is a beachhead, not the objective — the attacker lands on one usually low-value host and the real work is everything after. Post-exploitation decomposes into a repeating set of goals: persistence (hook a legitimate automatic execution trigger — a cron job, a service, a login hook, or in the cloud an added IAM key or deploy key — so the foothold survives a reboot or a password reset), discovery, lateral movement (harvest a credential on the owned host and reuse it to authenticate to the next host, walking the trust graph from the disposable beachhead toward the objective), and collection plus exfiltration (tunnel the data out low-and-slow over an already-allowed, already-noisy channel like HTTPS, DNS, or a trusted SaaS API so the volume never spikes). The defender’s whole advantage is that this chain is long and each link leaves a distinct, observable signal: a write to a rarely-changed startup surface, an authentication that’s normal in isolation but anomalous in context, a read of a secret store, or an unusual statistical shape of outbound traffic. So detection-in-depth mirrors defense-in-depth — you don’t have to catch the initial exploit, because catching persistence, an anomalous east-west auth, or a slow egress ends the operation just as completely. And you shrink the chain structurally so every remaining step is louder: segmentation removes lateral edges, least privilege shrinks what a stolen credential buys, short-lived credentials expire the loot, and allowlist egress removes the cover exfiltration hides in. Dwell time, then, isn’t a measure of how strong your perimeter is — it’s a measure of how well you watch what happens after it’s been crossed.
Practice
Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.
Something unclear?
Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.