Skip to content

The Mitigation Stack: Which Defenses, In Order

Every exploit walks the same stages: bug, corruption, hijack, code execution, escalation. A defender's checklist of which mitigation stops each — across Linux, ARM, Windows and the kernel.

Published on 4 min read

This is the capstone of the Exploit Mitigations area. Every walkthrough on this site ends by re-enabling the mitigation that breaks it. Read together, those endings form a single picture: an exploit is a chain of stages, and a defender's job is to break as many stages as possible. This guide assembles that picture across Linux, ARM, Windows and the kernel, and gives a prioritized order to enable everything.

Every exploit walks the same stages

Whatever the platform, memory-corruption exploitation follows the same path. Break any link and the chain fails.

The exploitation chain — a mitigation that breaks any stage stops the exploit
1. Bugan unbounded copy, a lifetime error, a bad index
corrupts
2. Memory corruptionoverwrite a return address, pointer, or metadata
needs an address
3. Know where to aimdefeat ASLR/PIE, usually via a leak
hijack
4. Control-flow hijackseize the instruction pointer
run code
5. Code execution / reuseshellcode, ROP, ret2libc, one-gadget
(kernel) escalate
6. Privilege escalationcommit_creds, sandbox escape
datawritable memorycodelibrary

Which mitigation breaks which stage

The same stage has a different mitigation name on each platform, but the role is identical.

StageLinux x86-64ARM64WindowsKernel
1. Prevent the bugmemory-safe language, -Wall -Wformat=2, sanitizers in CIsamesame, /analyzesame, subsystem hardening
2. Detect corruptionstack canary, FORTIFY_SOURCEstack canary/GS cookieCONFIG_STACKPROTECTOR_STRONG, freelist hardening
3. Hide addressesASLR + PIEASLR + PIEASLR (/DYNAMICBASE)KASLR + kptr_restrict
4. Protect return edgeshadow stack / CETPACCET (/CETCOMPAT), SEHOPshadow stack, canary
5a. No injected codeNXNXDEP (/NXCOMPAT)SMEP
5b. Constrain reuseCFI, Full RELROBTICFGkernel CFI, SMEP/SMAP
6. Contain the winseccomp, least privilegeseccompACG/CIG, AppContainerKPTI, lockdown, seccomp

Each row is one link. The techniques that attack each are catalogued in the Exploitation Techniques, ARM64, Windows and Kernel areas.

A prioritized enablement order

For a C or C++ project, enable in this order — cheapest and most universal first:

  1. Compile-time hygiene. -Wall -Wextra -Wformat=2 -Werror=format-security; treat warnings as errors. This alone prevents format-string bugs from shipping.
  2. The four cheap classics. Stack canary (-fstack-protector-strong), NX, ASLR + PIE (-fPIE -pie), and Full RELRO (-Wl,-z,relro,-z,now). Each breaks a distinct stage; see binary hardening flags.
  3. FORTIFY_SOURCE. -D_FORTIFY_SOURCE=3 -O2 adds bounds checks to common libc calls and blocks %n in writable format strings.
  4. The backward edge in hardware. Intel CET shadow stack, or ARM PAC (-mbranch-protection=standard also enables BTI). This is the most direct answer to ROP.
  5. Find bugs continuously. AddressSanitizer and fuzzing in CI. Mitigations do not fix bugs; this is how you remove them.
  6. Contain what remains. seccomp for exposed services (see the ORW guide), least privilege, and sandboxing.
  7. Remove the bug class. Where feasible, write new components in a memory-safe language. This is the only measure that eliminates stages 1–2 entirely.

Verify, don't assume

A flag that is silently dropped protects nothing. Confirm what actually shipped:

  • Linux/ARM: checksec --file=./bin (canary, NX, PIE, RELRO); readelf -n for ARM BTI, PAC.
  • Windows: check /guard:cf, /DYNAMICBASE, /NXCOMPAT, /CETCOMPAT on every loaded module — one unhardened DLL is the usual gap.
  • Kernel: verify KASLR, SMEP/SMAP (/proc/cpuinfo), KPTI, and the CONFIG_* hardening options in the running config.

Key takeaways

  • Exploitation is a chain of stages: bug → corruption → address knowledge → control-flow hijack → code execution/reuse → escalation. Breaking any stage stops the exploit.
  • The same stage has a different mitigation name per platform, but the role is identical — use the cross-reference table to see the whole grid.
  • Enable in cost order: compile-time hygiene, the four classics (canary/NX/PIE/RELRO), FORTIFY, the hardware backward edge (CET/PAC), sanitizers+fuzzing, containment, and finally memory-safe languages.
  • Verify every mitigation actually shipped, on every module — a dropped flag is a silent gap.

This capstone ties together the whole site: the vulnerability classes, the exploitation, ARM64, Windows and kernel techniques, and the mitigations that answer each.

Related guides

0x9000 · Kernel Exploitation

KASLR, KPTI and Modern Kernel Defenses

Kernel address randomization, page-table isolation, and the config options that harden a Linux kernel against memory-corruption exploits — what each one stops and how to enable it.

0xa000 · Windows Exploitation

Windows Flow-Integrity Mitigations: CFG and CET

How SafeSEH, SEHOP, ASLR, Control Flow Guard and hardware CET each close a Windows exploitation technique — what they check, how to enable them, and their limits.

0x8000 · ARM64 Exploitation

PAC and BTI: ARM's Answer to Code Reuse

Pointer authentication signs return addresses so a forged one faults; BTI forces indirect branches onto landing pads. How both work, how to enable and verify them, and their limits.