From defense to offense: the threat landscape
The first two guides gave you the defender's toolkit. Guide 1 separated protection (the OS's internal mechanisms that stop one process from accidentally trampling another) from security (protection versus security — defending against a deliberate adversary), and planted the principle of least privilege. Guide 2 turned the access matrix into real machinery with capabilities and ACLs. All of that is the fortress. This guide introduces the people trying to climb the walls — and crucially, what they want. Everything an attacker does is aimed at one of three goals, the CIA triad.
The CIA triad is the simplest honest summary of what 'secure' even means. Confidentiality is keeping secrets secret — your password, your private files, another tenant's data on a shared server. Integrity is making sure data is not altered behind your back — a banking app must not let a 100 transfer silently become 10000. Availability is keeping the service running at all — a ransomware lockout or a flood of traffic that takes a site down both attack availability, even if no secret leaks. Every attack in this guide can be read as a move against one of those three. Naming the goal is what lets you reason about whether a defense actually addresses the real risk.
Malware: a field guide to hostile code
Malware is simply software written to do harm — but the family has distinct species, and the differences are mechanical, not just labels. A virus is code that attaches itself to a host program (or document); it spreads only when a human runs the infected host, like a flu that needs someone to shake hands. A worm, by contrast, is self-propagating: it copies itself across a network with no human help at all, which is why worms can sweep the globe in hours. The famous ones — Morris, Blaster, WannaCry — were worms precisely because they did not wait for you to click.
A trojan (Trojan horse) takes a third route: it pretends to be something you want — a free game, a pirated app, a 'codec' you need to watch a video — so that you yourself grant it the privileges it craves. There is no clever exploit here at all; the trick is social, aimed at the human, and it is devastating precisely because you ran it willingly. A rootkit is the endgame: code that, once it has high privilege, hides itself from the very OS that should detect it — patching the kernel's list of running processes so its process never appears, or intercepting the file-listing call so its files are invisible. A rootkit is less an entry method than a way to stay.
Notice how cleanly these map onto the OS concepts you already own. A virus exploits the fact that running a program means handing it your privileges (recall a program is not a process — the danger appears only when the dormant file becomes a running process with your rights). A worm exploits a service that listens on the network. A rootkit must reach kernel mode to lie convincingly, which is why every defense ultimately cares about who is allowed to cross into the kernel. The taxonomy is not trivia; it tells you where in the system each one lives, and therefore where to put the guard.
The buffer overflow: how one sloppy line hands over control
The buffer overflow is the most famous low-level bug in computing, and it is worth understanding in full because it explains half of guide 5. The setup is innocent: a program reserves a fixed-size buffer on its stack — say a 64-byte array meant to hold a username — then copies input into it without checking the length. The hardware does not stop you. If the input is 200 bytes, all 200 are written, and the 136 bytes past the buffer's end overwrite whatever was sitting next to it on the stack. The bug is a single missing length check.
Why is that catastrophic rather than just a crash? Because of what sits next to the buffer. On the call stack, just past a function's local buffer lives the return address — the place the CPU will jump back to when the function finishes. The stack grows toward lower addresses while a copy writes toward higher ones, so overflowing the buffer marches straight into that return address. An attacker who controls the input controls those overwritten bytes, and therefore controls where the program jumps next. Overwrite the return address with the address of the attacker's own bytes, and when the function returns, the CPU starts executing the attacker's code.
stack grows DOWN (toward lower addresses) copy writes UP (toward higher addresses) -> higher addresses +----------------------+ | return address | <-- (4) overflow overwrites THIS +----------------------+ | saved frame pointer | <-- (3) ...then this +----------------------+ | buf[63] | <-- (2) ...keeps going past the end | ... (64 bytes) | | buf[0] | <-- (1) copy starts here +----------------------+ lower addresses Normal return: jump to caller Hijacked: jump to attacker's bytes -> attacker code runs
Be honest about the root cause, because it shapes the fix. The overflow is possible only because, classically, the stack held both data (the buffer) and control information (the return address) in the same writable, executable region, and the copy routine trusted the input's length. That is two assumptions, and guide 5's defenses attack each one: a stack canary places a secret value between the buffer and the return address so an overflow is detected before the return, and DEP/NX marks the stack non-executable so even injected bytes cannot run as code. The overflow is not magic — it is a violation of a boundary the OS now helps enforce.
Privilege escalation: turning a foothold into the keys
A buffer overflow gives an attacker code execution — but as whom? Typically as the user or service whose program was vulnerable, which may have very little power. The attacker's next move is privilege escalation: turning limited access into more. There are two flavours. Vertical escalation climbs from a low-privilege account to a high one — an ordinary user becoming root or Administrator, or any user-mode process punching into kernel mode. Horizontal escalation moves sideways: still an ordinary user, but now acting as a different ordinary user, reading their files. Both are failures of the same boundary the access matrix was supposed to enforce.
How does code on the powerless side reach the powerful side? The classic vertical path abuses a program that is allowed to run with elevated privilege on purpose — a setuid program on Unix, or a system service. The password-changing tool, for instance, must edit a root-owned file, so it runs as root even when you launch it. If such a trusted-but-buggy program has a buffer overflow, the attacker's injected code inherits its root privilege. This is the dark mirror of least privilege: the more programs that carry extra power 'just in case,' the more doors an attacker can knock on. Least privilege is not bureaucracy — every removed privilege is one fewer escalation target.
- Get in. The attacker exploits a vulnerability — say a buffer overflow in a network-facing service — to run code as that service's low-privilege account. This is the foothold.
- Look around. From inside, the attacker enumerates what this account can touch: world-readable secrets, misconfigured file permissions (a config left as rwxrwxrwx), a setuid binary, an out-of-date kernel.
- Escalate. The attacker abuses one of those — exploits the setuid binary's bug, or a kernel bug reachable via a system call — to gain root or to slip into kernel mode. Now they have the keys.
- Persist and hide. With high privilege the attacker installs a rootkit to survive reboots and stay invisible, completing the journey from one unchecked input to total ownership of the machine.
Why the kernel is the prize — and the trusted computing base
Every escalation story ends at the same place: the kernel, or root, which on most systems is nearly as good. Recall dual-mode operation from the early rungs — the CPU runs either in restricted user mode or in all-powerful kernel mode, and the only legitimate door between them is the system call. That single door is exactly why it is so heavily guarded, and exactly why attackers obsess over it: code in kernel mode can read any memory, rewrite the malware-hiding process list, disable the very checks that would catch it. There is no higher authority on the machine to appeal to. Win the kernel and you have won everything.
This is why security people obsess over the trusted computing base (TCB): the set of all hardware and software you are forced to trust completely, because if any part of it is compromised, no other defense can save you. The kernel is in the TCB. So is the firmware that boots it (which is why secure boot matters — guide 5), and the privileged services that run as root. The single most important design rule follows directly: keep the TCB as small as possible. Every line of code in the TCB is a line whose bug becomes a total compromise. A bug in your text editor is a nuisance; a bug in the kernel is the end of the game.