Supplementary Theory Curriculum – Computer Security
Audio version created with Paper2Audio.
Listen on Paper2Audio
Supplementary Theory Curriculum – Computer Security
The depth layer beneath the compendium and the exam guide: the mechanisms behind the concepts, topic by topic
Introduction
Computer Security, Politecnico di Milano
This is the depth layer beneath the compendium and the exam guide. The compendium tells you what you need to know, meaning the definitions and the bullet points. The exam guide tells you how to answer, meaning the recipes for each type of question. This document tells you why and how the mechanisms actually work. It is the connective tissue that makes the concepts stick and hang together.
The goal is holistic understanding, not memorisation. As the guiding idea of the course puts it: once you understand why counter mode without a message authentication code is malleable, you do not need to memorise it, because you can derive it.
The curriculum is built around twelve topics, drawn from slide decks zero through twelve, and it maps onto six exam questions for the Computer Security course at the Politecnico di Milano. Everything here is oriented towards the exam.
How each topic is built
Each of the twelve sections follows the same template. First comes the intuition, which is the big picture in plain language. Second comes the mechanism, the why and the how, which is the real understanding of what actually happens under the hood.
Third come the details you should have precise, meaning the numbers, names, and facts you have to get right. Fourth come the common misconceptions, the mistakes that cost people points, many of them taken from the guide's list of common traps. Fifth comes the connection to the exam, meaning where the topic shows up and what you are actually expected to write.
The red thread
Three ideas recur throughout the whole course. Keep them in the back of your mind as you read, and you will see that the subject is really quite small.
The first idea is that authentication is the root of almost everything. Most network attacks, such as those against the Address Resolution Protocol, the Domain Name System, the Internet Control Message Protocol, and the Border Gateway Protocol, work precisely because the protocol does not authenticate. Transport Layer Security fixes the network precisely by adding authentication on top.
The second idea is that encryption is not the same as integrity. Hiding data, which gives confidentiality, does not prevent the data from being changed. Integrity requires its own separate mechanism, namely a message authentication code or a signature. This theme repeats across cryptography, web security, and network security.
The third idea is fail-safe, or default deny. When in doubt, deny. This applies to firewalls, to access control, and to input validation.
Topic 1: Introduction to Computer Security
This topic draws on slide decks one and three. It is the basis of exam question one, worth four points, where you are asked to think like a security analyst.
Intuition
Security is about protecting valuable things, called assets, against an intelligent and adaptive adversary. This is the difference between security and safety. Safety protects against accidental failures, such as a disk that breaks.
Security protects against an attacker who actively searches for the weakest spot and changes tactics the moment you plug one hole. For that reason, security is always a trade-off and never a final, solved state.
When you meet an exam scenario, whether it is in-flight entertainment, a smart city, a dam or industrial control system, or an artificial-intelligence calculator, ask three questions like an analyst. What is worth protecting? What can go wrong? And who would want to exploit it, and why?
The mechanism: the triad as goals, not tools
The three security goals, confidentiality, integrity, and availability, are properties you want, not mechanisms. Confidentiality means that only authorised parties can read the data. Integrity means that only authorised parties can change the data, and only in permitted ways. Availability means that the service or the data is reachable for those who have a right to it.
The mechanisms, such as encryption, access control, firewalls, and message authentication codes, are how you achieve those three goals. They are not the goals themselves. A common moment of insight is realising that encryption is not a goal but a tool, one that primarily provides confidentiality, and, when combined with a message authentication code, also integrity.
There is an inherent tension here. Availability often conflicts with confidentiality and integrity. The most available system is one that everyone can reach, which is also the least confidential. Balancing these is an engineering problem with no fixed answer, and the right balance depends on what is at stake.
There are also extended goals, which often appear indirectly. Authenticity means the data or the sender is genuine. Non-repudiation means the sender cannot later deny the action. Accountability means actions can be traced back to an actor. These three are the reason digital signatures are more than message authentication codes, a point developed in Topic 2 on cryptography.
Details to get precise: the vocabulary chain
This vocabulary is the lens for exam question one, and the guide explicitly penalises mixing up the terms. Learn the distinctions, not just the words.
An asset is the valuable thing. The course defines four categories of asset, taken from slide twenty-seven: hardware, software, data, and reputation. A vulnerability is a weakness that makes a violation of confidentiality, integrity, or availability possible, for instance an outdated protocol, a missing bounds check, or poor password storage.
People often confuse a vulnerability with an exploit. An exploit is a concrete method for taking advantage of a vulnerability. A threat is a potential violation of confidentiality, integrity, or availability, meaning the event or circumstance itself, such as a data breach, a denial of service, or identity theft. People often confuse a threat with a threat agent. The threat agent is the actor who causes the threat, meaning who they are plus their motive. An attack is the intentional use of an exploit.
So, to compress the chain: a vulnerability is the weakness, and a threat is the danger that can exploit the weakness.
There are two classic mix-ups worth stating clearly. The first is threat versus threat agent. The threat is the event, such as unauthorised access to card data.
The agent is the actor, such as a financially motivated hacker. Write both of them separately. The second is that an attacker is not the same as a hacker. A hacker is a skilled, curious person who may be benign, whereas an attacker is malicious. A black hat is malicious, and a white hat is ethical. The guide deducts marks for imprecise word choice.
Risk is treated as a matter of risk management. Conceptually, risk is a function of assets, vulnerabilities, and threats together. The slides define risk as a statistical and economic assessment of exposure to harm, given the vulnerabilities and threats. It is a conceptual relationship rather than a literal calculation, and it splits the variables into two groups, following slide thirty-seven. Assets and vulnerabilities together are the controllable variables. You can influence both: which assets you choose to hold or expose, and how many vulnerabilities you have, through patching and secure design.
Threats are the independent variable. You do not control the threat landscape, because the fact that attackers exist and are motivated lies outside your control. Therefore security is a balance between, on the one hand, reducing vulnerabilities and limiting damage, and, on the other hand, cost.
Here is a common error, one that even appears in the compendium. It is tempting to say that the asset is the independent variable, because its value is given by the business. Slide thirty-seven says the exact opposite: assets and vulnerabilities are controllable, and threats are the independent variable.
Use the slide version on the exam. A related nuance from slide forty-five is that a system with few vulnerabilities but a high threat level can be less secure than one with many vulnerabilities but a low threat level.
It also helps to understand why more money does not automatically mean more security. An expensive but misconfigured firewall protects nothing, and an overly complex authentication system ends with passwords on sticky notes. Security is an optimisation under constraints of cost and usability.
The load-bearing principles
A handful of principles recur in every topic. Security is a process, not a product, and it must be maintained, because new vulnerabilities appear all the time. Defence in depth means using several independent layers, so that one breach does not give away everything.
Least privilege means giving each component as few rights as possible. The weakest-link principle says that a system is only as strong as its weakest part. And security must always be weighed against usability and cost.
Trust and the trusted computing base
Every system rests on a trusted computing base, meaning the components you must assume are secure, such as the operating system, the compiler, and the hardware. This creates a chicken-and-egg problem: who can you really trust? In nineteen eighty-four, Ken Thompson, in his lecture “Reflections on Trusting Trust”, showed that a trojanised compiler can inject a backdoor into, for example, the login program, and at the same time recognise when it is compiling itself and re-inject the trojan, so that the backdoor disappears from all source code but survives in every new binary.
The lesson is that you cannot verify trust all the way down unless you built everything yourself with tools you built yourself. Trust is fundamental and ultimately unverifiable.
Common misconceptions
Availability is a property of the triad; a denial of service is a threat, not an asset. The guide is explicit about this nuance. Safety, uptime, and quality of service are scenario-specific additions, not among the four official asset categories, so anchor your answer in hardware, software, data, and reputation. Choose assets relevant to the specific scenario, not generic ones like “data”: ask what would harm the business most if it were lost. And do not forget the justification, because the instruction to motivate all elements is printed on the front page of the exam.
Connection to the exam, question one
The recurring task is an asset, threat, and threat-agent table. Pick the two most relevant assets, attach a concrete threat and a credible agent with a motive to each, and justify each briefly. Related sub-questions draw from Topic 3 on authentication, covering password storage and recovery and biometrics, and from Topic 11 on network security protocols, covering the move from the Hypertext Transfer Protocol to its secure version. Use the engine: which box is it, hardware, software, data, or reputation; which leg of the triad fails; and who would do it, and why.
Topic 2: Introduction to Cryptography
This topic draws on slide decks two and eleven. It is the basis of exam question two, worth six points, where entropy calculations and the modes of the Advanced Encryption Standard dominate.
Intuition
Cryptography is a set of mathematical building blocks for achieving confidentiality, integrity, and availability in the presence of an attacker who sees, and perhaps changes, everything that crosses the channel. The central exam insight is not to compute the Rivest–Shamir–Adleman algorithm by hand, but to know which building block provides which property, because nearly every mistake on question two comes from confusing them, typically by believing that encryption provides integrity.
The mechanism: which primitive provides what
This is the most important relationship in the whole cryptography section. Learn it until you can derive it.
Encryption, whether the Advanced Encryption Standard or the Rivest–Shamir–Adleman algorithm, provides confidentiality only. It does not provide integrity, authentication, or non-repudiation. A hash function, such as the Secure Hash Algorithm with a two-hundred-fifty-six-bit output, provides none of these properties on its own; it is a building block used inside the others. A message authentication code, such as the hash-based one called H.M.A.C, is symmetric and provides integrity, but, on this course, it does not provide authentication or non-repudiation. A digital signature is asymmetric and is the only primitive that provides all three of integrity, authentication, and non-repudiation.
The course takes an explicit stance on message authentication codes that you must respect on the exam. The slides say, word for word, that the nomenclature misleads, and that message authentication codes do not provide data authentication. So a message authentication code gives you integrity, meaning the message has not been changed, but on this exam it does not count as authentication. The reason is the same as for non-repudiation: both parties share the key, so a valid tag does not bind the message to one particular sender.
Authenticity and non-repudiation come only from a digital signature, which uses a private key that only one party holds. Be aware that in general textbooks a message authentication code is often counted as integrity plus origin authentication between the parties; this course deliberately separates them, treating a message authentication code as integrity only.
Here is the core reasoning for why a message authentication code does not give non-repudiation, nor authentication, while a signature does. A message authentication code uses a shared secret key. Both sender and receiver hold it. If Bob presents a valid message-and-tag pair, he cannot prove that Alice created it, because he himself also had the key and could have made it. Therefore you get integrity, but no binding to one specific sender, and hence neither data authentication nor non-repudiation.
A signature, by contrast, uses the sender's private key, which only the sender has. A valid signature can only have come from that private key, so Alice cannot deny it, which gives non-repudiation. In practice, one signs the hash of the document rather than the whole document.
As for why encryption does not provide integrity, see the discussion of counter mode below: you can change decrypted content without being able to decrypt it. Confidentiality and integrity are orthogonal properties.
Details to get precise
Consider symmetric versus asymmetric cryptography, and why hybrid systems exist. Symmetric cryptography, such as the Advanced Encryption Standard, uses the same key in both directions and is fast; its problem is key distribution, that is, how the two parties agree on a key over an insecure channel. Asymmetric cryptography, such as the Rivest–Shamir–Adleman algorithm, elliptic-curve cryptography, or Diffie–Hellman, uses a public and private key pair, which solves key distribution but is ten to a thousand times slower. The hybrid approach, which all real systems use, including Transport Layer Security, uses asymmetric cryptography to agree on a symmetric session key and then symmetric cryptography for the actual data traffic, taking the best of both.
Next, perfect security versus computational security. Perfect security, defined by Shannon in nineteen forty-nine, means the ciphertext gives zero information about the plaintext. It is achieved by the one-time pad, where the ciphertext is the plaintext bitwise zored with a fresh, uniformly random key as long as the message.
It is provably secure but impractical, because the key is as long as the message and can never be reused. Computational security, used in practice, builds the cipher so that breaking it also solves a computationally hard problem. None of these schemes are provably secure, because a proof would prove that the complexity classes P and N.P differ; we trust them because no one has managed to break them. As for security margins, two to the power eighty is outdated, two to the power one hundred twenty-eight is safe for five to ten years, and two to the power two hundred fifty-six is for the long term. Note that these numbers apply to symmetric, bit-level operations. For asymmetric cryptography, the key length is not equal to the security level, and comparing bit sizes directly is, in the words of the slides, really wrong: a two-thousand-forty-eight-bit Rivest–Shamir–Adleman key gives only about one hundred twelve bits of security, because factoring is sub-exponential rather than scaling as two to the power of the key length.
Kerckhoffs's principle says the security should lie in the key, not in the secrecy of the algorithm. In other words, there is no security through obscurity.
Block cipher modes are an exam favourite. Electronic codebook mode encrypts each block independently with the same key, and you should never use it, because identical plaintext blocks produce identical ciphertext blocks, so patterns leak. This is the famous encrypted-penguin image, where the outline of the penguin is still visible.
Cipher block chaining mode chains the blocks: each block is zored with the previous ciphertext before encryption, and a random initialisation vector starts the chain, so identical blocks produce different ciphertexts. A note on the syllabus: the slides treat cipher block chaining mainly as a message authentication code for integrity, and the encryption modes they actually teach are electronic codebook, which is insecure, and counter mode. Cipher block chaining is included here as standard general knowledge, but on the exam it is electronic codebook and counter mode that matter.
Counter mode turns a block cipher into a stream cipher: the keystream is the encryption of a counter under the key, and the ciphertext is the plaintext zored with that keystream. The counter is incremented for each block. Counter mode is provably a pseudo-random generator, and therefore secure, if the encryption function is a pseudo-random permutation and it is used correctly.
To resist a chosen-plaintext attack the encryption must be non-deterministic, and the course gives three fixes: re-keying, also called ratcheting; randomness; or a non-one, which is a public value used as the counter's starting point.
Counter mode has two deadly sins, which appear almost guaranteed on question two. The first is malleability, meaning the absence of integrity. Because the ciphertext is the plaintext zored with the keystream, zoring a chosen difference into the ciphertext zors exactly the same difference into the plaintext. Flip one bit in the ciphertext and exactly the same bit flips in the plaintext, without the attacker knowing the key, and predictably so. An attacker can change data in a targeted way, for instance flipping “pay one hundred” into “pay eight thousand one hundred” if they know the position.
Therefore counter mode always requires a message authentication code, in the encryption-then-authenticate construction, or an authenticated mode such as the Galois/Counter Mode. The second sin is that reusing a nonce or counter is fatal. The same counter with the same key gives the same keystream. Then the zor of the two ciphertexts equals the zor of the two plaintexts, which is a two-time pad that leaks the relationship between the plaintexts, and often both of them. The classic trap is using the filename or something predictable as the initialisation vector, so that two files with the same prefix reuse the keystream.
Now entropy and diceware. Entropy is a measure of uncertainty or unpredictability. A uniformly random choice among N possibilities carries the base-two logarithm of N bits. A two-hundred-fifty-six-bit key carries two hundred fifty-six bits of entropy, if it is truly random. With diceware passprhases, you choose a number of words from a dictionary of a certain size, uniformly.
Each word contributes the base-two logarithm of the dictionary size in bits, and the total is the number of words multiplied by that per-word value. The minimum entropy, written H-infinity, is the negative base-two logarithm of the largest single probability; it is the worst-case guessability, used when the distribution is not uniform, and it is governed by the most likely outcome. The Shannon entropy is the average, computed as the sum over all outcomes of the negative probability times its base-two logarithm. For a uniform distribution, the two are equal.
Here is the step-by-step method for the question “how many words do I need to match a key of a given number of bits?” First, the bits per word is the base-two logarithm of the dictionary size. If instead you are given a compressed size, the bits per word is approximately the number of compressed bits divided by the number of words. Second, the target in bits is the key length, for example two hundred fifty-six. Third, the number of words is the target divided by the bits per word, rounded up. Fourth, show the calculation, because that is where the marks are.
For examples: a dictionary of two to the power sixteen words gives sixteen bits per word, so for two hundred fifty-six bits you need two hundred fifty-six divided by sixteen, which is sixteen words, and for one hundred twenty-eight bits you need eight words. A diceware list of two thousand words gives the base-two logarithm of two thousand, which is about eleven bits per word, so three words give about thirty-three bits.
Be aware of a confirmed arithmetic error in the official answer key, in the set from the second of April twenty-five. The set gives the text “The Tempest”, with twenty-six thousand five hundred eighteen words, compressed to fifty-three thousand two hundred ten bytes, which works out to about sixteen bits per word, and it asks for an equivalent of one hundred twenty-eight bits. The correct answer by the method is eight words, that is one hundred twenty-eight divided by sixteen. The answer key, however, writes word for word that picking sixteen random words is sufficient to gather one hundred twenty-eight bits, but sixteen words times sixteen bits is two hundred fifty-six bits, not one hundred twenty-eight. So this is a confirmed mistake in the answer key, verified against the set.
Trust the method, which is the target divided by the bits per word, and you will get credit for the right formula and calculation. Always use the base-two logarithm, never the base-ten logarithm.
Hash functions map a string of any length to a fixed-length output, and they have three hardness properties. Preimage resistance means it is hard to find an input given its hash, at a cost on the order of two to the power of the output length. Second-preimage resistance means it is hard, given one input, to find a different input with the same hash, again at a cost on the order of two to the power of the output length.
Collision resistance means it is hard to find any two distinct inputs with the same hash, at a cost on the order of two to the power of half the output length. The reason a collision is square-root cheaper is the birthday paradox: you are not looking for one specific value, but for any matching pair, and with about two to the power of half the output length random hashes the probability of a coincidence becomes large. So a hash of a given length is only half that many bits secure against collisions. Use the Secure Hash Algorithm two or three. Do not use the first Secure Hash Algorithm, which is broken for collisions, nor the Message Digest five algorithm, which is completely broken.
Now the asymmetric mechanisms. Diffie–Hellman, from nineteen seventy-six, lets Alice and Bob agree on a shared secret over an open channel. They agree on a base and a modulus. Alice sends the base raised to her secret, Bob sends the base raised to his secret, and both compute the base raised to the product of the two secrets.
Alice by raising Bob's value to her secret and Bob by raising Alice's value to his secret. An eavesdropper sees the two transmitted values but cannot compute the shared value without solving the discrete logarithm, under the computational Diffie–Hellman assumption. The genius is that the secret was never sent. Public-key encryption, such as the Rivest–Shamir–Adleman algorithm or ElGamal, encrypts with the recipient's public key and decrypts with their private key.
Digital signatures sign with the private key and verify with the public key, the opposite direction from encryption, which gives authenticity and non-repudiation.
Finally, public key infrastructure, which binds a key to an identity. The problem is that a public key is just a number, so how do you know it belongs to your bank and not to an attacker? An X-five-oh-nine certificate binds an identity to a public key, signed by a certification authority. This forms a chain of trust: a root authority, which is self-signed and sits in the browser's trust store, signs intermediate authorities, which sign end certificates. You trust the certificate because you trust the authority that signed it. The Achilles heel is that if an authority is compromised, it can issue false certificates for anyone; the countermeasure is Certificate Transparency, discussed in Topic 11. There is also a trade-off in certificate lifetime: a short lifetime means a smaller window of exposure if a key is compromised, but more frequent renewal and a higher volume of signatures.
Common misconceptions
Do not believe that encryption provides integrity; integrity comes from a message authentication code or a signature. Do not propose stronger encryption when the answer is hashing, because passwords must not be decryptable, as discussed in Topic 3. Do not forget that counter mode without a message authentication code is trivially malleable. Do not propose asymmetric cryptography when symmetric cryptography plus a message authentication code is cheaper and sufficient, because the exam penalises overkill. And never use the base-ten logarithm in entropy calculations.
Connection to the exam, question two
The recurring sub-questions are: entropy and diceware, where you calculate and show your work; the counter-mode weakness, meaning malleability or nonce reuse, where you propose a message authentication code or the Galois/Counter Mode; designing a cryptographic protocol, where you choose the cheapest primitive that meets the requirement, and often the requirement is integrity on a firmware update, so you need a message authentication code rather than encryption, and you derive a per-device key as the hash of the device identifier concatenated with a master secret; brute force, comparing lockout against delay; and occasionally public key infrastructure.
Topic 3: Authentication
This topic draws on slide deck three. It supplies sub-questions for exam question one, and password storage and recovery come up often.
Intuition
Authentication is proving a claimed identity. It always comes before authorisation: first “who are you, and prove it”, then “what are you allowed to do”. Most of the exam points here lie in password storage, because that is where nearly all systems get it wrong, and because it links directly to Topic 2 on cryptography, namely the difference between hashing and encryption.
The mechanism: the three factors and why multi-factor works
There are three authentication factors. The first is something you know, such as a password or a personal identification number, whose weakness is that it can be guessed, sniffed, or reused. The second is something you have, such as a hardware token, a smart card, or a time-based one-time-password app, whose weakness is that it can be stolen or lost. The third is something you are, such as a fingerprint or a face, whose weakness is that it cannot be changed and can be spoofed.
Multi-factor authentication, also called two-factor authentication, means using two different factors. The point is that the attacker has to break two independent things at the same time: stealing your password does not help if they also need your phone. Two passwords are not two-factor authentication, because they are the same factor with the same attack vector.
Details to get precise: password storage, the most important part
Think through why each step exists, and then you can criticise any scheme on the exam. First, never store passwords in plaintext, because a single database breach leaks every password directly, and since people reuse passwords, the breach spreads. Second, never use reversible encryption. “Encrypted” sounds safe, but if the system can decrypt the password, then an attacker who obtains the key can too, which is as bad as plaintext. Passwords should never be recoverable. Third, hash the password, but not with a fast hash alone.
Storing the hash of the password is better, but then an attacker can precompute rainbow tables, which are enormous lookup tables from hash to password, or simply brute-force with a graphics processor doing billions of fast hashes per second. Fourth, add salt. Store the hash of the salt concatenated with the password, using a random salt for each user; the salt is not secret and is stored next to the hash. This has two effects: it kills rainbow tables, because the table would have to be precomputed per salt, and it makes each hash unique even if two users have the same password, so the attacker cannot crack everyone at once and must attack one at a time. Fifth, use a slow hash, also called key stretching. Use bcrypt, script, Argontoo, or the password-based key derivation function P.B.K.D.F.2, with a work factor.
These are deliberately slow or memory-intensive, so each guess costs a lot and brute force becomes impractically expensive. Argontoo is also memory-hard, so it resists graphics processors and custom chips.
Here is the standard fix, worth learning as a single sentence. Use a salted slow hash such as bcrypt or Argontoo: the salt kills rainbow tables, the slow hash makes brute force expensive, and hashing is one-way, so the password can never be recovered.
On password recovery: never send the password by email. That would mean, first, that you store it reversibly, which is forbidden as discussed above, and second, that email is an insecure channel. The correct approach is to send a time-limited, single-use reset link that lets the user set a new password.
Now password attacks and their countermeasures. A dictionary attack tries words from a list, and the countermeasures are a slow hash and lockout. A brute-force attack tries all combinations, and the countermeasures are a slow hash and length and complexity requirements. Rainbow tables are precomputed hash tables, and the countermeasure is salt. Credential stuffing reuses leaked passwords from other services, and the countermeasures are multi-factor authentication and unique passwords.
There is a subtler point, from slides nineteen through twenty-three, about which countermeasure works against which attack. The slides split password attacks into three: snooping, where the password is stolen or eavesdropped; cracking, meaning enumeration or brute force; and guessing. Password policy works differently against each.
The exam trick, from slide nineteen, is to estimate the most likely attack in the scenario and then choose the countermeasure that actually helps, while remembering the indirect costs of strict requirements. Complexity, meaning a long password with a rich character set, does not help against snooping, because the attacker already has the password; it is important against cracking, because it enlarges the search space; and it can help against guessing. Frequent change or expiry is important against snooping, because it limits the window; it can help against cracking; and it is not relevant against guessing.
Making the password unrelated to the user is important against guessing. The intuition is this: if the password was snooped, complexity does not help, because the attacker already has it, and only frequent change limits the window; against cracking, complexity counts, because it enlarges the search space; and against guessing, what counts is that the password cannot be derived from the user's information.
There is also a brute-force variant comparing lockout and delay, which is a variant of question two. The probability of a single guess succeeding is one divided by the size of the password space; for diceware, that is one divided by the dictionary size raised to the number of words. With a lockout after a certain number of attempts, the success probability is approximately that number of attempts. divided by the password space, which you compare against the requirement. With an increasing delay, the expected number of attempts to hit is approximately half the password space; you sum the delays to get the expected time and compare it against the system's lifetime. The trade-off is that lockout can be abused for denial of service, by locking other people's accounts, whereas a delay avoids that but only slows brute force rather than stopping it.
One-time passwords give you a “something you have” factor without a physical gadget. The hash-based one-time password, defined in request for comments four-two-two-six, is counter-based, computed as a truncation of the hash-based message authentication code of the key and the counter. The time-based one-time password, defined in request for comments six-two-three-eight, is time-based, typically with a thirty-second window, and it is what Google Authenticator does.
Biometrics have several nuances. There are two error rates in a constant trade-off: the false-accept rate, which lets in the wrong person, and the false-reject rate, which rejects the right person. A threshold adjusts the balance, and lowering the false-accept rate raises the false-reject rate.
Biometrics cannot be reset: if your fingerprint leaks, you cannot change your finger, which is why biometrics are dangerous as the sole factor. They can be spoofed, for instance with a silicone finger or a photo, but they are practical and hard to forget. They are used either for identification, which is a one-to-many question of “who is this?”, or for verification, which is a one-to-one question of “is this the claimed person?”.
Some related concepts: single sign-on uses one identity and one trusted service, with the risk of a single point of failure; password managers give unique strong passwords but become a single point of attack; and passkeys use an asymmetric key pair bound to the domain, which makes them resistant to phishing, because the key does not work on a fake domain.
Common misconceptions
Do not believe reversible encryption is safe for passwords; if the attacker gets the key, it reveals every password, so use hashing. Two passwords are not two-factor authentication, because they are the same factor. Salt does not need to be secret; it is stored in plaintext, and it is the uniqueness, not the secrecy, that matters. And do not propose “better encryption” when the answer is hashing.
Connection to the exam, question one
Classic sub-questions ask you to criticise a password or authentication scheme. Is it plaintext or reversible? Is the password sent by email? Is the password space too small? Is a static hash vulnerable to replay? Other sub-questions ask for the advantages and disadvantages of biometrics, or the attack surface of an authentication protocol, where a replay weakness is fixed with a nonce and a hash-based message authentication code. The recipe is to identify the weakness precisely, explain the consequence, and give the standard fix.
Topic 4: Access Control
This topic draws on slide deck four. It is supporting theory and may appear as a sub-question in questions one or two.
Once authentication has answered “who are you”, access control answers “what are you allowed to do”. It is a binary decision, allow or deny, for each combination of a subject, an object, and an action. The challenge is scale: you cannot list every answer explicitly, so you need rules, meaning a policy, and a component that enforces them.
The mechanism: the reference monitor
The reference monitor is the component that checks each access against the policy. It has three requirements, and you should learn them, because they reappear in Topic 10 on secure network architectures and in the malware topic. First, it must be tamper-proof, meaning it cannot be modified by an attacker. Second, it must be non-bypassable, also called complete mediation, meaning all access goes through it with no shortcuts. Third, it must be verifiable, meaning small enough to analyse and trust.
The entities are the subject, which is active, such as a process or user; the object, which is passive, such as a file or resource; and the action, such as read, write, or execute. The access matrix records, for each subject and object, the rights that the subject has on that object. The matrix is conceptual and very sparse, since most cells are empty, so in practice it is stored sliced in one of two ways. An access control list slices by object, that is, by column, answering “who has access to this file?”, and is best for per-object operations; it is the most common form, as in Unix file permissions. A capability list slices by subject, that is, by row, answering “what does this user have access to?”, and is best for per-subject operations and delegation, where a capability works like a key. An authorisations table stores the non-empty rights as subject-object-action triples and is used in database management systems.
Details to get precise: the three models
There are three access-control models. Discretionary access control lets the owner of the resource decide freely; it is used in Unix, Windows, and social media. Mandatory access control has a central administrator assign rights via a classification, and the user cannot override it; it is used in the military, in government, and in companies. Role-based access control assigns rights to roles and users to roles, with administration through roles.
Discretionary access control has a clear strength, flexibility, but two problems. The first is the Trojan-horse problem: a malicious program runs with the user's rights and can read or copy the user's secrets to someone the user would not have shared them with. Discretionary access control cannot control the flow of information after access has been granted. The second is captured by the Harrison–Ruzzo–Ullman model, which is the access matrix plus commands that change it; the so-called safety problem, namely whether a right can ever leak to an unauthorised subject, is undecidable in general.
Mandatory access control uses classification. There are secrecy levels, which are strictly ordered; the slides' United States example is Top Secret, then Secret, then For Official Use Only, then Unclassified. Subjects have a clearance and objects have a sensitivity, and there is also a set of categories or labels. Dominance is defined as follows: one labelled level dominates another if and only if its secrecy level is greater than or equal to the other's, and the other's category set is a subset of its own. Levels and labels together form a lattice, which is a partial order that is reflexive, transitive, and antisymmetric; hence the name lattice-based access control. Not all pairs are comparable: for example, neither “Secret with the nuclear category” nor “Top Secret with the crypto category” dominates the other.
The Bell–LaPadula model concerns confidentiality. Its first rule is no read up, also called the simple security property: do not read above your level. Its second rule is no write down, also called the star property: do not write to a lower level.
The reason is to prevent someone with Top Secret clearance from copying secrets down to where an unauthorised party reads them; information flows monotonically upward. There is also tranquillity, meaning levels do not change dynamically, and declassification requires trusted subjects. Formally, Bell–LaPadula also has a third rule, the discretionary security property, which says that a discretionary access matrix is applied in addition to the two mandatory rules.
Bell–LaPadula covers only confidentiality, not integrity, which is why the Biba model exists. Biba is the mirror image of Bell–LaPadula and concerns integrity: no read down, no write up. The reason is to prevent low-integrity, untrustworthy data from flowing upward and contaminating high-integrity data; integrity flows downward.
Here is how to remember the two. Confidentiality fears that secrets leak down, so it blocks writing down, and also reading up. Integrity fears that dirt comes up, so it blocks writing up, and also reading down. The two models are exact opposites.
Common misconceptions
Do not confuse an access control list, which is per object, with a capability list, which is per subject. Do not swap the directions of Bell–LaPadula and Biba. And do not believe that the owner control of discretionary access control is secure, because of the Trojan-horse problem.
Connection to the exam
This is supporting theory, but it can appear as a sub-question. Have ready the three models, the difference between an access control list and a capability list, Bell–LaPadula and Biba in one sentence each, and the three requirements of the reference monitor.
Topic 5: Introduction to Software Security
This topic draws on slide deck five. It is the foundation for question three, the binary question, and for the bad-practice criticism in question one.
Software bugs become security holes when they break a security property. This section is the bridge to Topic 6 on buffer overflows and Topic 7 on format-string bugs: it explains why memory bugs are dangerous, and it gives you the design principles you cite when you propose fixes.
The mechanism: bug versus vulnerability versus exploit
A bug is an unmet functional specification, meaning the program does the wrong thing. A vulnerability is an unmet security specification, meaning a bug or design flaw that breaks confidentiality, integrity, or availability. An exploit is a concrete way to take advantage of the vulnerability. Not all bugs are vulnerabilities, and not all vulnerabilities are bugs, since some are design flaws. This distinction is the same as in Topic 1.
Details to get precise
Consider the lifecycle of a vulnerability, also called disclosure. A zero-day is known to the attacker but unknown to the vendor, with no patch available, which makes it the most dangerous. Full disclosure publishes everything immediately, which pressures the vendor but arms attackers.
Responsible, or coordinated, disclosure reports to the vendor, gives time for a patch, and then publishes. Non-disclosure keeps it secret. A bug bounty pays for responsible reporting. The slides frame the history as three epochs: non-disclosure, then full disclosure, then anti-disclosure, meaning a black market for exploits and the slogan “no more free bugs”.
In the lifecycle, the window of exposure is the time from when the exploit is released to when the patch is rolled out; the zero-day window is the part before the vulnerability is publicly known.
The Unix privilege model is critical for understanding why buffer overflows are so bad. The real user identifier records who actually owns or started the process. The effective user identifier is used for access-control decisions. The set-user-identifier bit, when set on an executable file, makes the process run with the effective user identifier of the file's owner, not the starter's. So running the change-mode command to set the set-user-identifier bit on a program owned by root makes it run as root no matter who starts it. This is necessary for certain tools, since the password-changing utility must write to the shadow password file, but it is dangerous: a bug in a program that is set-user-identifier root gives privilege escalation to root. This is why a buffer overflow in such a program is catastrophic, because the attacker's shellcode inherits root.
The slides give a worked example of a set-user-identifier program leaking the shadow password file. The program is set-user-identifier root, reads a configuration file, and writes the contents into an error message. If it runs privileged the whole way through, an attacker can run it with the shadow password file as the argument, and the error message leaks the password hashes that only root should be able to read. The vulnerability is that the developer kept root privileges while reading the configuration.
The exploit is to start the program with the shadow password file, or a specially crafted file, as the argument. The fix rests on two principles: acquire privileges as late as possible, and drop them, going from the set-user-identifier to the real user identifier via the set-user-identifier system call, as early as possible, ideally reading the configuration file with low privileges. That shrinks the attack surface to a minimum, though other bugs may still exist in the privileged part.
This is exactly the same vulnerability-versus-exploit distinction as in Topic 1.
Finally, the secure design principles of Saltzer and Schroeder. First, least privilege, meaning as few rights as possible. Second, keep it simple, also called economy of mechanism, because simple means verifiable. Third, drop privileges as soon as possible, going from set-user-identifier to real user identifier the moment you no longer need root. Fourth, open design, meaning no security through obscurity, which is Kerckhoff's again. Fifth, fail-safe defaults, meaning the default is deny. Sixth, complete mediation, meaning check every access, which is the reference monitor.
Seventh, filter input and output. Eighth, do not invent your own cryptography; use well-tested libraries. Ninth, avoid shared resources, which lead to race conditions, in particular the time-of-check-to-time-of-use flaw, for example the race in creating a temporary file.
Connection to the exam
These principles are what you cite as fixes in question three and in the bad-practice criticism: drop privileges, least privilege, validate input, and use a well-tested library.
Topic 6: Buffer Overflows
This topic draws on slide deck six. It is the basis of question three, worth six points. It is the heaviest topic, so spend the most practice time here. Assume a thirty-two-bit x86 architecture, the C declaration calling convention, and no mitigations unless stated otherwise.
If you write more data than a buffer can hold, the writing continues into adjacent memory, including control data such as the function's return address. If you manage to overwrite the return address with an address of your choosing, you hijack the control flow: when the function returns, the processor jumps to where you point it. The whole attack is mechanical once you understand the stack layout, which is why it pays to draw the stack until it is second nature.
The mechanism: process memory, the calling convention, and the stack frame
Process memory runs from low to high addresses as follows: the text segment, holding code; the data and block-started-by-symbol segments, holding global; the heap, which grows upward; and, much higher, the stack, which grows downward, towards low addresses.
The C declaration calling convention on thirty-two-bit x86 works like this. First, the caller pushes the arguments from right to left. Second, the call instruction pushes the return address, which is the saved instruction pointer. Third, the function's prologue pushes the caller's base pointer, copies the stack pointer into the base pointer, and subtracts a number from the stack pointer to allocate space for local variables. As for registers: the stack pointer points to the top of the stack, the base pointer marks the bottom of the current frame and is used as a base for relative addressing, and the instruction pointer holds the next instruction.
Here is the stack layout in words, which is more useful aloud than any diagram. Picture low addresses at the top and high addresses at the bottom, the orientation used on the exam. At the lowest addresses sit the local variables, including the buffer, with the stack pointer at the very top.
Above them, at higher addresses, sits the saved base pointer, then the saved instruction pointer, which is the return address, and finally the caller's arguments and frame at the highest addresses. The buffer is written towards higher addresses, that is, downward in this picture. So when you write past the end of the buffer, you go towards higher addresses and overwrite, in order, first the saved base pointer and then the saved return address.
The thing people get wrong is the orientation: in this exam drawing, low addresses are at the top, the buffer is at low addresses, and the saved return address is higher, so writing past the buffer moves downward in the drawing and upward in address.
The overflow itself comes from functions without bounds checking, such as gets, strcpy, strcat, sprintf, or scanf with the percent-s specifier, or a loop using less-than-or-equal, which is an off-byte error. These let you fill past the buffer. The order overwritten is local variables, then the saved base pointer, then the saved return address. On return, the epilogue runs the leave and return instructions, which copy the base pointer into the stack pointer, pop the saved base pointer, and then the return instruction pops the saved return address into the instruction pointer, so the processor jumps to your address and your code runs.
Details to get precise: building the exploit
The goal is to overwrite the saved return address with an address that points to your shellcode. The payload, in the slides' arrangement, is a sled of no-operation instructions, followed by the shellcode, followed by the target address repeated. The repeated address fills up to and overwrites the saved return address, and it points back into the sled.
The no-operation sled, made of the no-operation byte, hexadecimal ninety, exists because you rarely know the buffer's exact address. It is a landing strip of no-operations, so that if you land anywhere in the sled, the processor slides down into the shellcode, giving a much larger target area.
The offset to the saved return address is the distance from the start of the buffer to the saved return address, which is the buffer size, plus any other local variables, plus the four bytes of the saved base pointer. Fill exactly that much before the address so it lands on the saved return address, or repeat the address for robustness, because the processor is merciless: miss by one byte and it crashes.
The shellcode aims to execute the program that spawns a shell, namely a call to execute “/bin/sh”, which spawns a shell with the program's privileges, root if the program is set-user-identifier root, as in Topic 5. The shellcode must contain no null bytes, because string copying stops at a null, so you use an exclusive-or of a register with itself instead of moving a literal zero into it, and you use jump-and-call tricks to find the address of the string. As for where to place the shellcode: in the buffer, which has little space; in an environment variable, which has more space and a more predictable address but only works locally; or after the saved return address, in the caller's frame, when the shellcode is large.
What you can overwrite, from slide one-four-five, is usually the saved return address, giving a direct jump via the return instruction; alternatively a function pointer, taken at the next indirect call; or the saved base pointer, in a technique called frame teleporting, where popping the base pointer in the epilogue gives the caller a fake frame that you control.
Now the mitigations, what they stop and how they are bypassed. A stack canary, as in StackGuard, places a random guard value between the local variables and the saved base pointer and return address, and checks it before returning; it stops a contiguous stack overflow that crosses the canary. It is bypassed by a format string, which writes directly and skips over the canary, by overwriting a variable before the canary, or by leaking the canary and writing the right value back.
The no-execute or data-execution-prevention defence makes the stack non-executable, using a hardware no-execute bit, and it stops shellcode on the stack; it is bypassed by return-to-libc, meaning returning into a library function such as system, by return-oriented programming, or by jumping to an existing function in the text segment. Address space layout randomisation randomises the addresses of the stack, heap, and library code on each run, and it stops hardcoded addresses; it is bypassed by an information leak, such as using the percent-p specifier, to compute the address, and on thirty-two-bit systems the low entropy allows brute force.
In practice, real exploits stack these bypasses: with no-execute on, you use return-to-libc; with address space layout randomisation on, you first leak an address and then use return-to-libc. On the exam, mitigations are usually off unless stated, and you are asked to reason about whether each one would still allow the exploit. There are also several canary types: a terminator canary contains bytes such as null and newline so that string functions stop, a random canary, and a random exclusive-or canary.
Do not say that a stack canary stops a format string; it does not, because a format string writes directly to the target, as in Topic 7. Do not forget the caller's frame in the drawing, and do not draw the stack upside down. Do not ignore characters that stop or mangle input, such as newline, exclamation mark, space, or conversion to lowercase; adapt the payload. Do not propose shellcode on the stack when no-execute is on, in which case you must use return-to-libc or an existing function. And do not fail to state your assumptions about whether address space layout randomisation and no-execute are off and how the program is run, because that is explicitly required.
Connection to the exam, question three
There are three fixed parts. First, find the vulnerability, the unbounded write, and give the line number; the fix is a length-limited variant such as fgets with the buffer size, strncpy or strncat, or scanf with a width like percent-thirty-nine-s, and slide one-five-one also mentions the B.S.D functions strclpy and strlcat. Second, draw the stack before and after, with the growth direction, the variable names, the base and stack pointers, the saved return address, and the caller frame.
Third, write the exploit with explicit assumptions. Then reason about the canary, no-execute, and address space layout randomisation.
Topic 7: Format String Bugs
This topic draws on slide deck seven. It is part of question three, worth six points. It is almost always a print-formatted call on a buffer, and it beats the stack canary.
Intuition
The print-formatted family of functions blindly trusts its first argument as a format string. If the attacker controls that string, they control how the function walks the stack, turning a harmless print into arbitrary reading and arbitrary writing. The killer exam insight is that a format string beats the stack canary, because it writes directly to a chosen address instead of flooding over the canary.
The mechanism: why a format string is so dangerous
The bug is calling print-formatted on a user-controlled buffer directly, instead of calling it with a literal percent-s format and the buffer as the argument. As for how the function works, it scans the format string, and each percent specifier makes it fetch the next argument from where arguments are kept, which on thirty-two-bit x86 is the stack, just above the pointer to the format string. The function does not know how many arguments were actually passed; it trusts the string. If you give more specifiers than there are arguments, it reads stack memory that is not a real argument.
For reading from memory: a series of percent-x specifiers walks up the stack and prints values, which is an information leak that can expose the canary, the saved return address, and library addresses, defeating address space layout randomisation. The percent-s specifier interprets a stack value as a pointer and reads the string there, giving an arbitrary read if you place the target address on the stack or in the buffer. Direct parameter access, written as percent-N-dollar-x, reads the N-th argument directly without walking.
For writing to an arbitrary address, there is the percent-n specifier, which writes the number of bytes printed so far to the address given by its argument. The recipe is: first, place the target address in the buffer; second, walk to it with the direct-parameter-access notation; third, control the count with a width, since the percent-width-c specifier prints one character padded to the given width, so it prints that many characters; fourth, the percent-n specifier then writes that count to the target address. To write a whole thirty-two-bit value without printing billions of characters, split it into two sixteen-bit half-words using the percent-h-n specifier, which writes two bytes, to the address and the address plus two, writing the smaller half-word first.
As a concrete example, suppose you want to write the value b-seven-e-b-one-f-one-zero in hexadecimal to the address zero-eight-zero-four-nine-six-nine-eight. You place the target address and the target address plus two into the buffer, then make two writes. For the low half-word you print enough characters to total one-f-one-zero in hexadecimal, which is seven thousand nine hundred fifty-two characters, and write it with the half-word specifier.
For the high half-word you print up to b-sevenue-b in hexadecimal, which is forty-seven thousand eighty-three, so the difference from the previous count is thirty-nine thousand one hundred thirty-one more characters, and you write that. You write the low half-word first.
The targets for the write are the saved return address; an entry in the global offset table, which stores resolved addresses of dynamic library functions, so overwriting one makes the next call to, say, the print function jump where you want, and the table is writable and at a fixed address when the program is not built as a position-independent executable, making it a perfect target; and function pointers or hooks.
Here is why a format string beats the canary. A stack canary only protects against contiguous overwrites that cross it on the way to the saved return address. The percent-n specifier writes directly to an address you choose, jumping right over the canary.
Therefore the canary is irrelevant and the exploit is still valid. As an aside, print-formatted with format strings is Turing-complete, supporting counters and conditional writes and reads.
Details: the exam example from the twenty-first of June twenty-four
The code calls print-formatted on a user-controlled field at line thirty-six. There is no classic buffer overflow, because the scan was length-limited. The exploit uses the format-string bug at line thirty-six to overwrite the saved return address with the address of the buffer. The canary stops a buffer overflow, but we exploit a format string, which writes directly, so the canary is irrelevant. As for no-execute: to read a flag file without running shellcode, you use the same format string to overwrite the saved return address with the address of an existing function in the text segment, and you ensure the argument, the flag's filename, is passed correctly.
Do not say the canary stops a format string; it does not. Do not believe the percent-n specifier writes a value directly; it writes the number of characters printed so far, and you control the value through the width. And do not forget the half-word specifier, which is what lets you avoid printing billions of characters.
Connection to the exam, question three
Look for a user-controlled format argument, such as print-formatted on a buffer, file-print-formatted on a user field, or print-formatted on a description field, and give the line number; the fix is to call it with a literal percent-s format. Show that the exploit beats the canary, and read the flag by overwriting an entry in the global offset table or the saved return address to point at an existing function.
Topic 8: Web Application Security
This topic draws on slide deck eight. It is the basis of question four, worth six points, covering three vulnerabilities with three standard fixes: structured-query-language injection, cross-site scripting, and cross-site request forgery.
Intuition
Web applications are exposed to the whole world, and the Hypertext Transfer Protocol is stateless with weak authentication, so state and login are emulated with tokens and cookies. The golden rule is that the client is never trustworthy: the attacker controls their own browser and can forge any request. The three exam vulnerabilities all spring from the same root, namely that user data is trusted in three different sinks: the database query, the Hypertext Markup Language page, and the logged-in session.
The mechanism: the order of input filtering
There are three approaches to input filtering, in order of preference. First, allowlisting, meaning permit only what is expected, which is the safest. Second, blocklisting, meaning reject known-dangerous values, which is fragile, because you always forget a variant. Third, escaping, meaning transform special characters into something harmless, which is context-dependent.
Structured-query-language injection
The mechanism is that user input is concatenated directly into a query string, so the attacker breaks out of the string literal and changes the structure of the query. The root cause is that code, the query, and data, the input, are mixed in the same string. For example, if a query selects from the users table where the name equals a value taken straight from a request parameter, then an input of a single quote followed by “or one equals one” makes the condition always true, and an input that closes the string and appends a command to drop the users table can destroy data, if stacked queries are supported.
There are several variants. In-band injection, using a union, appends a union-select to pull extra data into the visible result. A subquery injection puts a select inside an insert or a value, to leak data into a field you can read. A blind injection produces no output, so you ask yes-or-no questions and read off the behaviour, for example asking whether the password is like a given letter pattern, leaking the password character by character.
The fix is prepared statements, also called parameterised queries. The reason this is the answer is that the structure of the query is sent to the database separately from the data, so the input is bound as a pure value and can never be interpreted as query code. Input validation is good as an extra layer, but prepared statements are the actual fix.
Cross-site scripting
The mechanism is that unsanitised user input is displayed in the page, so the attacker's JavaScript runs in the victim's browser, in the victim's session, leading to cookie theft, session hijacking, redirection, or defacement. There are three types. Reflected cross-site scripting reflects the input straight back in the response, so the attacker must lure the victim to a prepared link. Stored cross-site scripting is saved in the database and shown to other users, which is the worst, because it hits everyone who views the page. Document-object-model-based cross-site scripting happens through manipulation in the client's JavaScript, without the server.
The payloads are a script element, or, via an attribute, an event handler such as one that triggers on load, on mouse-over, or on click. This is why a blocklist that only removes angle brackets can be bypassed through attribute injection, the famous colour-field trick. The fix is allowlisting plus escaping, turning angle brackets, double quotes, and single quotes into Hypertext Markup Language entities, together with a content security policy header, which restricts which scripts may run, and cookies marked as H.T.T.P-only, which JavaScript cannot read, dampening cookie theft.
Cross-site request forgery
The mechanism is that a malicious page gets the victim's browser to send a state-changing request to a site the victim is logged into. The cookie is sent along automatically, which are called ambient credentials, so the request looks legitimate to the server. It requires a state-changing action, such as a post, a purchase, or a transfer, without cross-site-request-for-gery protection. The fix is a cross-site-request-for-gery token, which must be random, large, unguessable, bound to the session, and verified by the server, since a guessable or small-range token does not count, and the SameSite cookie attribute, set to strict or lax, so the cookie is not sent on cross-site requests.
Here is the difference between cross-site request forgery and cross-site scripting. Cross-site scripting runs the attacker's script on the trusted site. Cross-site request forgery abuses the victim's existing login from another site, without running a script on the target. They are different attacks with different fixes.
Details: exam assumptions and exploit patterns
Some useful assumptions from the exam are worth learning. A database function whose name ends in “with statement” is prepared and therefore safe. A plain execute-query function is not prepared and is therefore vulnerable.
A template-rendering function does not sanitise. A dedicated cross-site-scripting-sanitise function escapes correctly. And the database management system does not support stacked queries, so a semicolon fails, and you must use a subquery or a union instead.
For exploit patterns: a cross-site request forgery is an auto-submitting form on a malicious page the victim visits, with hidden fields for the amount and the receiver, submitted by a script so the cookie follows automatically; if the route accepts a get request, a plain crafted link with the parameters in the query string suffices. A subquery structured-query-language injection can steal credit-card numbers by embedding a select inside an inserted value. A blind structured-query-language injection can leak a password character by character using a like pattern.
Common misconceptions
Do not overlook attribute-based cross-site scripting, such as an on-load handler, when only angle brackets are filtered. Do not use stacked queries when the database management system does not support them; use a subquery or a union instead. Do not call a guessable or small-range token secure, because it is vulnerable to cross-site request forgery. Do not point at a “with statement” function for injection, because it is safe. And do not write vaguely that “there is an injection” without a line number and a concrete payload.
Connection to the exam, question four
Fill in the table of injection, cross-site scripting, and cross-site request forgery: does it exist, on which line, how is it classified, and what is the fix? Then reproduce the exploit as concrete code. Be brief and concrete, with a line number and one sentence, not an essay.
Topic 9: Network Protocol Attacks
This topic draws on slide deck nine. It is the basis of question five, worth six points, where you get a packet log and a network diagram and must learn the four fingerprints.
Most network attacks work because the underlying protocols do not authenticate: anyone can forge replies for the Address Resolution Protocol, the Domain Name System, and Internet Control Message Protocol redirects. On the exam you get a packet log and a network diagram; you recognise the attack by its fingerprint, name it precisely, and point out the attacker, the victim, and the spoofed address.
The mechanism: the building blocks, and why each is forgeable
The Address Resolution Protocol maps an internet address to a hardware address on the local network. It has no authentication, so anyone can claim any address. The switch's content-addressable memory table records which hardware address is on which port; if the table overflows, the switch fails open and broadcasts like a hub, which enables eavesdropping.
An Internet Control Message Protocol redirect lets a gateway tell a host about a better route, so an attacker can redirect a host's routing. The Domain Name System maps names to addresses; a resolver does recursive lookups and caches answers, so forged answers poison the cache. The taxonomy is: denial of service, which attacks availability; sniffing, which attacks confidentiality; and spoofing, which attacks integrity and authenticity.
Details to get precise: the four attacks and their fingerprints
Address Resolution Protocol spoofing shows up in the log as unsolicited replies that bind the gateway's or victim's address to the attacker's hardware address; its goal is a man-in-the-middle position. Content-addressable-memory, or media-access-control, flooding shows up as masses of frames with many different or random source hardware addresses, which makes the switch broadcast; its goal is to eavesdrop on a switched network. An Internet Control Message Protocol redirect shows up as redirect messages to the victim with the gateway set to the attacker's address, often several after a single packet; its goal is a man-in-the-middle position. Domain Name System cache poisoning shows up as forged answers, with a spoofed source, that arrive before the real one and map a domain to the attacker's address; its goal is to redirect traffic.
Now denial of service in depth. A synchronise flood sends many synchronise packets with a forged source address, so the server allocates half-open connections in the synchronise-received state, the state table fills, and legitimate users cannot get in; the defence is synchronise cookies, where the server encodes the state into the sequence number and allocates nothing until the acknowledgement arrives. The Smurf attack is an amplification attack: send an Internet Control Message Protocol echo to a broadcast address with the victim's address as the source, so every machine replies to the victim, amplifying the traffic. Killer packets exploit implementation bugs: the Ping of Death is an oversized Internet Control Message Protocol packet, the Teardrop attack uses overlapping fragments to crash reassembly, and the Land attack sets the source equal to the destination in a synchronise packet, causing a loop. A distributed denial of service is coordinated from a botnet, as in Topic 12.
On identifying the attacker, victim, and spoofed address: the source address is often forged, but at least one real address must be given, namely where the traffic actually goes, which is the attacker's controlled machine. In an Internet Control Message Protocol redirect, the gateway address is the attacker, because that is where the traffic is redirected. The victim is the one who receives the forged message, or whose cache is poisoned.
There is also sniffing, which is passive eavesdropping, using Ethernet promiscuous mode or WiFi monitor mode, with the defence being encryption such as Transport Layer Security or a virtual private network. And there is address spoofing, which is hard over the Transmission Control Protocol because it requires the three-way handshake but easy over the User Datagram Protocol, and Border Gateway Protocol hijacking, where weak or absent authentication lets a malicious router announce false routes. The conclusion is that almost all network attacks are made possible by the lack of strong authentication in the protocols, which is exactly what Transport Layer Security adds.
Common misconceptions
Do not confuse content-addressable-memory flooding, which shows many source hardware addresses, with Address Resolution Protocol spoofing, which shows replies aimed at the gateway, although they can occur together. Do not say all addresses are spoofed, because at least one real address is needed, namely where the traffic goes. And do not name the attack vaguely as “spoofing” instead of precisely as, say, Domain Name System cache poisoning.
Connection to the exam, question five
Recognise the attack from the log, name it precisely, and point out the attacker, the victim, and the spoofed address. This continues in Topic 10 with the defence.
Topic 10: Secure Network Architectures
This topic draws on slide deck ten. It is part of question five, worth six points, where you write firewall rules, which must be stateful and default-deny, and place a firewall or design a demilitarised zone.
Once you know the attacks, you defend with architecture: firewalls, zones such as a demilitarised zone, segmentation, and virtual private networks. The exam asks you to write firewall rules and to place a firewall or design a demilitarised zone.
The mechanism: the firewall
A firewall is a network access-control system that checks every packet that passes through it. There is a crucial limitation: a firewall only controls traffic that goes through it. It is powerless against insider threats and uncontrolled paths, such as a mobile-data modem on an internal machine, and the firewall itself can have vulnerabilities. The principle is default deny, meaning deny everything except what is explicitly allowed.
There are several types of firewall. A packet filter works at the network level, is stateless, and filters on source and destination address, port, and protocol. A stateful packet filter works at the network and transport levels and tracks the state of a Transmission Control Protocol connection, so return traffic is admitted automatically, which is safer. A circuit-level proxy works between the transport and application levels as a middleman for connections. An application proxy works at the application level with a full understanding of the application protocol.
The key to writing rules is statefulness. With a stateful firewall, you specify only the direction of the first packet, and the replies are admitted automatically, because the firewall remembers the established connection. With a stateless firewall, you would have to write rules for both directions manually.
Details: how to write the rules
First, put default deny first, at the bottom in priority, so everything is denied unless explicitly allowed. Second, write one flow per rule, in the order of the columns. Third, cover only what the business needs, such as users to the web on ports eighty and four-four-three, the Domain Name System on port fifty-three, employees to the internet, and administration or secure shell on port twenty-two, and nothing more. Fourth, keep the rules consistent with the placement, for instance a firewall that replaces a particular switch.
To describe a rule set in words rather than a table: the first rule, the default-deny rule, denies all traffic from any source and port to any destination and port. The next rule allows internal hosts to reach the web server on ports eighty and four-four-three. A further rule allows user hosts to reach the Domain Name System server on port fifty-three for name lookups.
And a final rule allows user hosts to reach the internet on ports eighty and four-four-three. Each rule names a source address, a source port, a direction, a destination address, a destination port, and a policy of allow or deny, plus a short description.
As for the demilitarised-zone architecture: the internet connects to a first firewall, then to the demilitarised zone holding the web server and mail server, then to a second firewall, then to the internal network. The demilitarised zone is an exposed zone for public services, separated from the internal network. A double firewall gives an extra layer, so internal resources are shielded even if the demilitarised zone is compromised. The thinking is zone-based: traffic between zones is controlled explicitly.
On virtual private networks and specific countermeasures: a virtual private network is a secure, encrypted overlay over a public network. Full tunnelling sends all traffic through the virtual private network, giving more control but being slower, whereas split tunnelling sends only company traffic through it, which is efficient but gives less control. The technologies include the Point-to-Point Tunnelling Protocol, which is weak; Openveepeen, based on Transport Layer Security; and Internet Protocol Security, whose authentication header gives integrity and whose encapsulating security payload gives encryption.
Port security on Cisco devices limits the number of hardware addresses per switch port, defending against content-addressable-memory flooding. Against Internet Control Message Protocol redirects, disable or restrict redirects in the operating system. And segmentation divides the network into zones, such as employees versus servers, which limits the spread of an attack.
Common misconceptions
Do not forget default deny, and do not write allow rules that unintentionally open everything. And do not write stateless rules, with both directions manually, when the question specifies stateful.
Connection to the exam, question five
Write firewall rules that are default-deny and stateful, place a firewall or build a demilitarised zone, and propose countermeasures, such as replacing a particular switch, port security, a virtual private network, or segmentation, that match the attack you identified in Topic 9.
Topic 11: Network Security Protocols — Transport Layer Security and the Secure Electronic Transaction
This topic draws on slide deck eleven. It supports question two, the protocol question, and question one, the move from the Hypertext Transfer Protocol to its secure version.
Transport Layer Security is the answer to the question “how do I get confidentiality, integrity, and authentication over a network where the protocols underneath, as in Topic 9, authenticate nothing?”.
This is why the standard fix for almost all bad practice in question one is moving from the Hypertext Transfer Protocol to its secure form, that is, Transport Layer Security version one-point-three. Transport Layer Security makes the whole cryptography curriculum concrete: hybrid cryptography, certificates, and message authentication codes, all in one place.
The mechanism: what Transport Layer Security actually provides, and how
Transport Layer Security provides confidentiality, through an encrypted channel; integrity, through a message authentication code; server authentication, always, via a certificate; and client authentication, optionally. It uses hybrid cryptography: asymmetric cryptography to exchange a symmetric session key, and symmetric cryptography for the actual traffic.
The handshake, presented as reasoning rather than a sequence to memorise, goes as follows. First, in the client-hello, the client proposes cipher suites and sends random data. Second, in the server-hello, the server chooses a suite and sends random data plus its certificate. Third, the client validates the certificate: is the validity period current, is the root authority trusted, is the signature valid, has it not been revoked, and does the domain name match? Fourth, key establishment: in classic Rivest-Shamir–Adleman mode, the client sends a pre-master secret encrypted with the server's public key, while in modern Transport Layer Security version one-point-three, ephemeral Diffie–Hellman is used. Fifth, both sides derive the same shared secret from the pre-master secret and both random values, and the encrypted traffic begins.
Here is why Transport Layer Security resists a man-in-the-middle, assuming a trustworthy certification-authority hierarchy. If the attacker passes through the real certificate, they lack the private key and cannot decrypt or respond. If they send a fake certificate from an unknown authority, the client rejects it. If they send a certificate with the wrong name, it is rejected because the name does not match. And if they forge the public key inside a real certificate, the signature becomes invalid and it is rejected. The robustness rests entirely on the certification-authority hierarchy being trustworthy; if an authority is compromised, it falls.
Details to get precise
The cipher suites are negotiated, covering key exchange, whether Diffie–Hellman, elliptic-curve Diffie–Hellman, or Rivest–Shamir–Adleman; the symmetric cipher, such as the Advanced Encryption Standard in Galois/Counter Mode or Chachatwenty; the signature, whether Rivest–Shamir–Adleman or the elliptic-curve digital signature algorithm; and the hash, such as the Secure Hash Algorithm with a two-hundred-fifty-six-or three-hundred-eighty-four-bit output. As for versions, anything up to and including version one-point-one is insecure, version one-point-two is acceptable but has older suites, and you should use version one-point-three, which has a faster handshake and removes weak algorithms. This is exactly the “version one-point-two to one-point-three” countermeasure on the exam.
There are several public-key-infrastructure challenges. Secure-sockets-layer stripping downgrades the secure protocol to the insecure one, and the defence is H.T.T.P Strict Transport Security. Miss-issued certificates from a compromised authority are countered by Certificate Transparency, where authorities log all certificates publicly. And key pinning, the H.T.T.P Public Key Pinning mechanism, is deprecated because of the risk of self-inflicted denial of service.
The Secure Electronic Transaction is historical but exam-relevant as an idea. Conceived by Visa and MasterCard in the nineteen-nineties, the idea was to protect the transaction itself, not just the connection. The cardholder sends order information only to the merchant and payment data only to the gateway. The dual signature is the signature, with the cardholder's private key, of the hash of the concatenation of the hash of the order and the hash of the payment; this binds the two parts together without either party seeing both.
It failed because it required a digital certificate for every cardholder, which was too heavy to scale, created friction, and never reached critical mass; it was replaced by simpler redirect-based solutions, such as three-domain secure. The lesson is that security that is not usable does not get adopted, the same point as in Topic 1.
Common misconceptions
Do not believe that Transport Layer Security authenticates the client by default; the server is always authenticated, the client only optionally. Do not forget that the Transport Layer Security guarantee falls if the certification authority is compromised. And do not propose “encryption” as the fix when the problem really requires authentication, that is, a certificate; Transport Layer Security gives both, but know which property solves what.
Connection to the exam
This topic appears as a countermeasure in question one, namely moving from the Hypertext Transfer Protocol to its secure form and upgrading from version one-point-two to one-point-three, and as protocol reasoning in question two. Know the handshake validation and the man-in-the-middle reasoning.
Topic 12: Malicious Software
This topic draws on slide deck twelve. It is the basis of question six, worth six points. It is concept-heavy with little writing, and there is high reward for precise names.
You are given malware code, in C or assembly, to analyse. The job is, first, to identify stealth and anti-analysis techniques; second, to choose static versus dynamic analysis with justification; and third, to propose how signature detection is bypassed. The “why” is half the marks, and vague names lose points.
The mechanism: the two types of analysis and what beats each
Static analysis examines the code without running it, using disassembly, strings, and signatures, and it catches dormant code; it is defeated by packing or encryption, by polymorphism, by metamorphism, and by obfuscation. Dynamic analysis runs the code in a sandbox or debugger and observes its behaviour, and it avoids obfuscation; it is defeated by anti-debugging, anti-virtual-machine checks, time bombs, and environment checks.
Signature detection is when antivirus matches a known byte sequence. It is static and fast, but it fails on unknown or altered code. This is why polymorphism and metamorphism exist.
Here is the distinction the exam tests. Anti-debugging, anti-virtual-machine checks, and time bombs hit dynamic analysis. Polymorphism and metamorphism hit static, or signature, analysis.
Do not swap them. And note the difference: polymorphism means an encrypted payload with a new key per sample, giving different bytes but the same code, whereas metamorphism means rewritten code, through inserting no-operations or using equivalent instructions.
Details to get precise: stealth and evasive techniques, recognised in code
Anti-debugging is done with a self-signal, such as a trap signal or a floating-point-exception signal raised via a division by zero: under a debugger the signal is caught by the debugger, so the malicious handler, which is the real code, does not run, or the malware detects the debugger; this hits dynamic analysis. Anti-virtual-machine detection uses the processor-identification instruction to check the hypervisor bit, bit thirty-one in a particular register; this hits dynamic analysis inside a virtual machine. Polymorphism uses an encrypted payload with a new key per sample, giving different bytes with the same behaviour; this hits static, signature-based analysis.
Metamorphism rewrites the code itself, through inserting no-operations, using equivalent instructions, and reordering; this also hits static, signature-based analysis. A time or logic bomb uses sleep, a timestamp, or a condition tied to a date; this hits dynamic analysis through a sandbox timeout. A rootkit hooks the operating system to hide itself from process and network listing tools; this hits observation.
The taxonomy of malware is as follows. A virus infects files and needs a host. A worm is standalone and spreads itself over the network. A trojan pretends to be useful. A rootkit hides itself in the operating system. A botnet is a set of infected machines steered by a command-and-control server. Ransomware encrypts for a ransom. And there is spyware, including keyloggers.
Rootkits in depth come in two kinds. A userland rootkit replaces tools such as the list, process-status, and network-statistics commands with trojanised versions; it is simpler to build and detectable through a cross-layer check. A kernel-space rootkit hijacks the system-call table, hiding files, pro- cesses, and connections completely; it is detectable only through post-mortem analysis or trusted boot.
Cohen's theorem, from nineteen eighty-three, states that a perfect virus detector is undecidable. The proof sketch is: assume a perfect detector exists. Build a virus that calls the detector on itself. If the detector says “virus”, the virus does not spread, contradicting the verdict; if the detector says “not a virus”, the virus spreads, again contradicting the verdict. The contradiction means the perfect detector cannot exist.
The malware lifecycle is: reproduction and infection, via a propagation vector; persistence, surviving a restart; hiding; and the payload. Historical worms include the Morris worm of nineteen eighty-eight, which used a buffer overflow in the finger daemon; Code Red; sequel Slammer, which used the User Datagram Protocol and was extremely fast; and WannaCry.
There is an exam example from the ninth of January twenty-five, combining a floating-point-exception signal with polymorphism. The code registers a handler for the floating-point-exception signal and then divides one by zero. The handler decrypts the payload and runs it. The techniques are, first, anti-debugging, because the division by zero triggers the floating-point exception that the handler catches, while a debugger normally catches error signals and does not pass them on, so the malicious code does not run under a debugger, frustrating dynamic analysis; and second, polymorphism, because the encrypted payload frustrates static, signature-based analysis. The analysis approach is dynamic analysis in a sandbox configured to forward the signal to the program, or static analysis after decryption.
On bypassing a signature: the metamorphic way is to break up the exact byte sequence without changing behaviour, by inserting no-operations or swapping in equivalent instructions, for example loading an address as the value minus one and then adding one. The polymorphic way is to encrypt the payload with a unique key per distributed sample, so each copy has different bytes. The reason this works is that the signature is a fixed string, so a single inserted no-operation byte, or a single new key, makes the match fail.
Common misconceptions
Do not use vague names like “it is stealthy”; name the technique exactly, or you lose points. Do not mix up polymorphism and metamorphism, that is, encryption with a new key versus rewritten code. Do not choose an analysis type without justification, because the “why” is half the marks. And do not swap them: anti-debugging hits dynamic analysis, while polymorphism hits static analysis.
Connection to the exam, question six
Match the code to the technique, name it precisely, choose static versus dynamic analysis with justification, and explain the signature bypass. Anti-debugging, anti-virtual-machine checks, and time bombs favour static analysis or an adapted sandbox; encrypted or polymorphic code favours static analysis on the decrypted code. State your assumptions, for instance that you have a sandbox and can patch the binary.
The Common Threads: How the Subject Hangs Together
When you see these patterns recur, the twelve topics stop being twelve things to memorise and become a few ideas used over and over.
The first thread is that authentication is the root of almost everything. Most network attacks, in Topic 9, work because the protocol does not authenticate: the Address Resolution Protocol, the Domain Name System, Internet Control Message Protocol redirects, and the Border Gateway Protocol. Transport Layer Security fixes the network by adding authentication, through a certificate. Spoofing is forged identity. Passwords, biometrics, and multi-factor authentication, in Topic 3, are the authentication of users. Message authentication codes and signatures, in Topic 2, are the authentication of messages.
The second thread is that encryption is not the same as integrity. Hiding data does not prevent it from being changed. Counter mode without a message authentication code is malleable; passwords should be hashed, not encrypted; Transport Layer Security uses both encryption and a message authentication code; and a firmware design often needs only integrity, that is, a message authentication code, not confidentiality. When you see the word "integrity", think message authentication code or signature, never "encryption".
The third thread is fail-safe, or default deny. When in doubt, deny. The firewall, in Topic 10, starts with default deny; access control, in Topic 4, uses fail-safe defaults; and input validation, in Topic 8, prefers allowing.
The fourth thread is least privilege plus damage limitation. Dropping privileges for a set-user-identifier program, in Topic 5; demilitarised-zone segmentation; least privilege in access control; and defence in depth all aim to limit what one breach can yield.
The fifth thread is do not invent your own cryptography; rely on what is well-proven. Custom cryptography is a common question-two trap; use proven libraries and standards, such as the Advanced Encryption Standard, Argontoo, and Transport Layer Security version one-point-three.
The sixth thread is that the vocabulary is the lens. The chain from asset to vulnerability to exploit to threat to threat agent to attack to risk, from Topic 1, is the framework you lay over any scenario in question one.
Exam mapping, from topic to question
To map topics onto questions: Question one, the introduction and asset table, worth four points, draws on Topic 1 for vocabulary and the triad, Topic 3 for passwords and biometrics, and Topic 11 for the move to the secure web protocol. Question two, on cryptography, worth six points, draws on Topic 2 for entropy, counter mode, message authentication codes, and public key infrastructure, with a little of Topic 11. Question three, the binary question, worth six points, draws on Topic 5 for the user-identifier and set-user-identifier model and the design principles, Topic 6 for buffer overflows, the stack, and mitigations, and Topic 7 for format strings. Question four, on the web, worth six points, draws on Topic 8 for injection, cross-site scripting, and cross-site request forgery.
Question five, on the network, worth six points, draws on Topic 9 for attack fingerprints and Topic 10 for firewalls, the demilitarised zone, and virtual private networks. Question six, on malware, worth six points, draws on Topic 12 for stealth, static versus dynamic analysis, and signatures. And the supporting theory of Topic 4, access control, can come up as a sub-question.
The final check before the exam
There are five parts that are practically guaranteed to appear. The asset, threat, and agent table, in question one. The buffer-overflow and format-string analysis with a stack drawing, in question three. The injection, cross-site scripting, and cross-site request forgery table, in question four.
The firewall rules with default deny, in question five. And the choice of static versus dynamic analysis with justification, in question six. If you can do these fluently, you have a solid foundation before you even open the exam set.
This document deepens the compendium with mechanisms and the “why”. For recipes per question type, see the exam guide. Always double-check details against the answer key and the slides; one known arithmetic-error case is noted under Topic 2 on cryptography.
You have reached the end of the document.