Academy

Systems Security experimental

Systems Security Defence in depth as engineering, not slogans: privilege, isolation, threat models, memory safety and exploit classes, with attack-then-harden labs. Privilege and isolation. Privilege and isolation. Explain least privilege and apply it alongside isolation boundaries.. Privilege, Sandboxing, Isolation, Attack surface Privilege Every running piece of code holds some set of rights: which files it can open, which syscalls it can make, which users it can act as. 'Least privilege' means a component gets only the rights it needs for its job, no more. A web server that only ever reads static files should not be able to write to /etc, open raw sockets, or run as root. Privilege is not a courtesy setting; it is the boundary that limits how much damage a compromised component can do. Ask, for every process: if this is fully owned by an attacker right now, what can they reach? That reachable set is the privilege you handed out, whether you meant to or not. Sandboxing A sandbox is a constrained execution environment that enforces a policy on what code inside it can do, independent of what the code asks for. Operating-system sandboxes (seccomp-bpf filters, AppArmor, SELinux profiles, Windows AppContainers) restrict syscalls, file paths, and capabilities at the kernel boundary. Language-level sandboxes (WebAssembly (WASM), Java Virtual Machine (JVM) security managers, browser tab isolation) restrict behaviour above the Operating System (OS). A good sandbox fails closed: if the policy does not explicitly allow an action, it is denied, not merely discouraged. Isolation Isolation separates trust domains so that a compromise in one does not automatically become a compromise in another. Mechanisms sit on a spectrum: process boundaries and separate user identifiers (UIDs) are cheap but leaky if the kernel is compromised; containers add namespaces and cgroups but share a kernel; virtual machines add a hypervisor boundary; physical separation is strongest and most expensive. Choosing an isolation mechanism is a cost/blast-radius trade: the question is always 'what do I still trust across this boundary', because nothing is isolated from a shared kernel bug or a shared secret. Attack surface Attack surface is the sum of every entry point an attacker can touch: open ports, parsed file formats, exposed APIs, command-line flags, environment variables, Inter-Process Communication (IPC) endpoints, even error messages that leak state. Reducing attack surface means removing code paths and privileges that are not load-bearing for the product: disable unused features, close unneeded ports, drop capabilities after startup, run parsers in a stripped-down sandbox. Attack surface reduction and least privilege reinforce each other: fewer reachable entry points times fewer rights per entry point yields a much smaller blast radius when, not if, something is compromised. Attack-surface reduction and isolation are complementary, not substitutes: dropping privileges after startup narrows what a compromised process can do, while closing an unused port removes an entry point before compromise is even possible, and a mature hardening checklist applies both together rather than treating either as sufficient alone. A useful audit exercise for any running service is to list every open file descriptor, every listening socket, and every capability it holds, then ask of each one whether the service actually needs it right now; anything that survives that question unjustified is attack surface that should be closed, and anything that cannot be justified in one sentence is usually a historical accident rather than a deliberate design choice. Related CCI capabilities Cambridge Cyber International's Hardware Domain Separation (Finance Edition) offering applies this module's isolation principle at the hardware layer: two physically isolated domains in one device, engineered from electron to interface with no backdoor or physical bypass path, for institutions that cannot accept a shared-kernel trust boundary between sensitive and general-purpose workloads. See cambridgecyberinternational.com for current availability. Threat modeling. Threat modeling. Explain threat-modeling method and build a threat model using it.. Assets and boundaries, STRIDE, Trust boundaries, Prioritisation Assets and boundaries Threat modeling starts by naming what you are protecting (assets: credentials, customer data, signing keys, availability itself) and drawing the system as data flows between components. Each component, data store, and external entity gets placed on a diagram, and every place trust level changes becomes a boundary worth marking explicitly. You cannot threat-model a system you have not first drawn; the diagram forces you to notice the data flow you assumed did not exist. STRIDE Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, and Elevation of privilege (STRIDE) is a mnemonic for six threat categories applied to each element of the diagram: Spoofing (pretending to be something you are not), Tampering (modifying data or code in transit or at rest), Repudiation (denying an action without accountability), Information disclosure (exposing data to those unauthorised), Denial of service (degrading availability), and Elevation of privilege (gaining rights you should not have). Walking every data flow and every trust boundary against all six letters is mechanical by design: the value is in forcing coverage rather than relying on whatever threats happen to come to mind. Trust boundaries A trust boundary is any point where data crosses from one privilege level or ownership domain to another: a network socket accepting external input, a process boundary between a sandboxed renderer and a privileged broker, a database call carrying user-supplied parameters. Threats cluster at boundaries because that is where assumptions from one side stop holding on the other. Marking boundaries on the diagram tells you exactly where validation, authentication, and authorisation checks must live. Prioritisation A threat model produces more findings than any team can fix at once, so prioritisation is part of the discipline, not an afterthought. Score each threat by likelihood and impact (Damage, Reproducibility, Exploitability, Affected users, Discoverability (DREAD); the Common Vulnerability Scoring System (CVSS); or a simple high/medium/low rubric are all acceptable if applied consistently), and prioritise threats that cross the highest-value boundaries with the least existing mitigation. A threat model that is not converted into a ranked, owned backlog of fixes is documentation, not security work. Revisiting the model is as important as building it the first time: a threat model drawn once at design time and never updated drifts out of sync with the system the moment a new component, data flow, or trust boundary is added, and a stale diagram gives false confidence precisely because it looks authoritative. Treating the threat model as a living artefact, reviewed whenever the architecture changes materially and not merely on a fixed calendar schedule, is what keeps the STRIDE walkthrough and the prioritised backlog it produces actually describing the system that is running today rather than the system that was running when the diagram was last drawn. Scoring consistency matters more than scoring precision: a team that argues for an hour over whether a finding is a 7 or an 8 on a ten-point scale is spending effort on false precision, while a team that applies the same rough rubric the same way across every finding produces a ranking that is actually useful for deciding what to fix first, even if any single score would not survive close scrutiny in isolation. Related CCI capabilities Cambridge Cyber International's Global Cyber Incident Database (GCIDB) grounds threat-model prioritisation in this module in documented real-world outcomes rather than guesswork: which boundaries were actually crossed, by which technique, and at what cost, across a running register of incidents. See cambridgecyberinternational.com for current coverage. Memory safety and exploits. Memory safety and exploits. Explain exploit classes and evaluate which mitigation defeats each one.. Buffer overflows, Use-after-free, Mitigations, Exploit classes Buffer overflows A buffer overflow happens when a write goes past the end of an allocated buffer, corrupting adjacent memory. On the stack, overflowing a local array can overwrite the saved return address, letting an attacker redirect execution to code of their choosing (classic stack smashing) or to existing code via return-oriented programming (ROP) once direct code injection is blocked. On the heap, overflowing a chunk can corrupt allocator metadata or adjacent objects, giving an attacker a write primitive that is harder to reason about but just as dangerous. The root cause is almost always unchecked length: strcpy, gets, manual loops without bounds checks, or trusting an attacker-supplied length field. Use-after-free A use-after-free (UAF) occurs when memory is freed but a dangling pointer to it is dereferenced or reused later. Because allocators recycle freed memory, an attacker can often arrange for the freed slot to be reallocated with attacker-controlled data before the dangling pointer is used, turning a logic bug into an arbitrary read/write primitive. UAF bugs are common in complex object lifetimes (callbacks, reference-counted objects, C++ destructors run in the wrong order) and are notoriously hard to spot by inspection because the bug is a temporal property, not a static one. Mitigations No single mitigation stops memory-corruption exploitation; they compose. Stack canaries place a random value before the saved return address and check it before returning, catching linear stack overflows before they hijack control flow. No-eXecute (NX), often called Data Execution Prevention (DEP) on Windows, marks memory as either writable or executable but not both, blocking injected shellcode from running directly. Address Space Layout Randomisation (ASLR) randomises the base addresses of the stack, heap, and libraries per run, forcing an attacker to also leak an address before a ROP chain can be built reliably. Together these mitigations do not make exploitation impossible, but they raise the cost from 'write shellcode' to 'chain an info leak plus a corruption bug plus a working gadget set'. Exploit classes Beyond stack and heap corruption, the same root cause (memory safety violations) produces a family of related classes: integer overflows that turn a validated size into a small or negative number before an allocation; format-string bugs where attacker-controlled input is passed as a format specifier, leaking or writing memory; type confusion where an object is reinterpreted as the wrong type. Recognising the class tells you which mitigation matters and which fix is real (bounds checks and safe integer arithmetic) versus cosmetic (hiding the symptom without removing the unchecked write). Distinguishing a real fix from a cosmetic one matters because a cosmetic fix can pass a specific proof-of-concept exploit while leaving the underlying memory-safety violation fully intact, ready to be triggered by a slightly different input the original exploit did not happen to use. Bounds checks, safe integer arithmetic, and memory-safe language choices address the root cause directly, while catching a specific crash and adding a special case around it addresses only the one input that was tested, which is why regression tests derived from the original bug report are necessary but not sufficient evidence that a memory-safety class of bug has actually been eliminated rather than merely hidden from that one test case. Related CCI capabilities Cambridge Cyber International's Mirage mediation bastion sidesteps much of this module's exploit surface by design: operators interact through a formally specified mediation point, an Augmented Backus-Naur Form (ABNF) grammar plus a finite-state machine, so a compromised client cannot deliver the kind of attacker-controlled bytes a buffer overflow or use-after-free exploit needs directly to the target. See cambridgecyberinternational.com for current status. Harden and verify. Harden and verify. Configure hardening measures on a system and explain how to verify each one.. Defence in depth, Hardening, Verification, Regression Defence in depth Defence in depth means stacking independent controls so that the failure of any single one does not equal a full compromise. It is the practical answer to 'we cannot guarantee any one control is perfect': input validation, least privilege, sandboxing, memory-safety mitigations, network segmentation, and monitoring should each independently reduce risk, so that an attacker who defeats one layer still meets another. The test of a defence-in-depth design is asking, for each layer, 'if this layer were absent, would the others still catch the attack': if the answer is no for every layer but one, you have a single point of failure dressed up as depth. Hardening Hardening is the systematic removal of unnecessary capability and the tightening of configuration toward the minimum needed to function: disabling unused services, applying the principle-of-least-privilege to file and process permissions, enabling every available memory-safety mitigation (canaries, No-eXecute (NX), Address Space Layout Randomisation (ASLR), and where possible safer languages or bounds-checked libraries), patching known vulnerabilities, and turning on compiler and Operating System (OS) hardening flags (-fstack-protector, _FORTIFY_SOURCE, Position Independent Executable (PIE), Relocation Read-Only (RELRO)). Hardening is not a one-time event; it is a checklist applied consistently to every build and deployment. Verification A hardened system is only as good as the evidence that the hardening works. Verification means testing the specific claim, not just the presence of a setting: if you enabled ASLR, prove an exploit that depended on fixed addresses now fails; if you dropped a capability, prove the action requiring it is now denied; if you closed a port, prove a connection attempt is refused. Verification should be automated and repeatable so it runs on every change, not performed once and trusted forever. Regression Security regressions happen quietly: a refactor re-adds a debug endpoint, a dependency bump silently disables a hardening flag, a container base image update drops a seccomp profile. Guard against this by turning every verified attack (from earlier labs, from past incidents, from known Common Vulnerabilities and Exposures (CVE) entries in your stack) into a permanent regression test that runs in Continuous Integration (CI). A hardened system that cannot prove, on every commit, that yesterday's fixed attacks still fail is one refactor away from being exploitable again. The discipline this module builds toward is closing the loop between the earlier modules and this one: privilege boundaries and sandboxing from isolation work reduce what a compromise can reach, threat modeling identifies which boundaries matter most, memory-safety mitigations raise the cost of exploiting a bug that gets through, and hardening plus verification plus regression testing is what proves, on every single change, that none of the earlier work has silently eroded. A system that passes this full chain is not invulnerable, no system is, but it is one where a successful attacker has had to defeat several independent, continuously verified layers rather than walking through a gap nobody was checking. Each hardening flag mentioned above closes off one specific technique rather than memory corruption in general, which is precisely why a checklist listing them without a regression test proving each one is actually enabled on the shipped build has not yet demonstrated anything. Related CCI capabilities Cambridge Cyber International's EviGen offering supports the verification discipline this module argues for: automated technical evidence collection across Windows, macOS, and Linux endpoints without a persistent agent, producing the kind of dated, reviewable proof that a hardening flag or a closed capability is actually enforced on the shipped build, not merely configured. See cambridgecyberinternational.com for current availability.