SkillGridLearn computer science by doing

Attacks on the wire and on services

What TLS really prevents and what it does not, ARP and DNS spoofing on a network you do not own, why denial of service resists filtering, and rate limiting as the mitigation that actually ships.

16 min · 50 XP

The networking track already showed you the TLS handshake and certificate validation. The security question that follows is narrower and more useful: given a working TLS implementation, what can an attacker on the path still do? The answer is more than nothing and much less than everything, and the interesting part is exactly where the line falls. Everything below assumes the protocol is implemented correctly. Broken implementations are their own subject, and a much rarer one than the headlines suggest. TLS gives you three things. Confidentiality, so the bytes on the wire are not readable. Integrity, so a modified byte is detected rather than accepted. And authentication of the server, so you know the key you agreed on belongs to the name you asked for. That last one is the part attackers actually go after, because it is the part that depends on something outside the protocol: your trust store. If an attacker can install a root certificate on your device, or if the software you use was shipped with one already installed, the handshake succeeds, the padlock appears, and the traffic is decrypted in the middle. This is not a TLS vulnerability. It is TLS working exactly as designed, with a trust anchor that should not be there. The other route is simpler and needs no cryptography at all: a page that looks like the login page and is not. TLS cannot help, because the certificate on a lookalike domain is perfectly valid for that domain.

ClientOn-path attackerServerClientHello, SNI example.orgTLS is not broken. M cannot forge a certificatecertificate for example.org signed by attacker CAis this issuer in my trust store?only if the attacker installed a root, or the user clicked throughFinishedseparate TLS session with the real server

ARP has no authentication. A host asks who owns an IP address, anyone may answer, and the answer is cached. On a network where you control the switch, this is a manageable problem; on a shared network it is a free pass. The attack is not exotic and does not require breaking anything: it requires repeatedly announcing that a given address is at your MAC, so that the victims send their traffic to you first. Switching to a network you do not own is the practical mitigation, and it is more effective than any software you can install afterwards. The reason this matters even for encrypted traffic is metadata. An on-path attacker may not read your bytes, but they see which addresses you talk to, when, how often and how much. They can also choose not to forward, which turns a passive position into a denial of service. Defending at the endpoint means binding the gateway address to a known MAC, or using a VPN that tunnels all traffic to a point you trust. Defending at the switch means features that drop announcements a port has no business making. Both are real; neither is available on the conference Wi-Fi. The poisoning idea without the mechanics. What makes it damaging is not the false answer but the caching of it.

who has 192.168.1.1? tell 192.168.1.50     <- gateway ARP, normal
who has 192.168.1.1? tell 192.168.1.77     <- repeated, from a laptop

victim ARP cache
  192.168.1.1  ->  MAC of 192.168.1.77    <- poisoned entry

result: victim sends gateway-bound traffic to the laptop first

mitigation  dynamic ARP inspection on the switch
mitigation  port security, one MAC per port
mitigation  encrypted protocols with certificate checkingThe mechanism, at the level of detail needed to defend against it. What makes it work is that the answer is trusted without any proof.

DNS is the part of the network that turns a name into an address, and it was designed when the network was small and everyone on it was trusted. A resolver that accepts records it did not ask for, and then caches them, will keep serving them until the time to live runs out. That is the shape of cache poisoning: the attacker influences one answer and the resolver spreads it to every client that asks afterwards. The cache is what turns a momentary influence into a lasting one, which is why the time to live is the number that decides how bad it is. DNSSEC signs answers, so a resolver can verify that a record came from the zone that owns it and was not modified. It does not encrypt anything, and it does not make the query private. DNS over HTTPS and DNS over TLS encrypt the query so a network observer cannot read or rewrite it, but they do not prove the answer is correct; they simply move who you trust from the local network to the resolver you chose. The honest summary is that both are partial, deployment of DNSSEC is uneven, and the practical advice for a user is to configure a resolver you trust rather than to rely on whatever the network hands out. Denial of service is the attack category where defence is genuinely hard, and it is worth understanding why rather than collecting countermeasures. Filtering works when the malicious traffic is distinguishable from the legitimate traffic. In a denial of service it is often not: the packets are well-formed, they come from real addresses, and they ask for real pages. The only difference is how many of them there are and where they point. A firewall rule that drops the attack also drops the customers. This is what is meant by saying you cannot filter what you cannot distinguish from real traffic, and it is a structural limit, not a missing feature. SYN cookies are the classic answer, and they are instructive because of what they give up. Instead of storing state for each half-open connection, the server encodes what it needs into the sequence number it sends back and verifies it when the final acknowledgement arrives. The cost is that some TCP options cannot be negotiated in that mode, so connections are slightly less capable. It is still the right trade for a public service, because the alternative is that a modest amount of spoofed traffic takes the service down. What SYN cookies do not fix is a flood of complete connections, which is why the rest of this lesson is about rate limiting. An amplification attack does not need much bandwidth from the attacker. It sends a small request with a spoofed source address to a service that produces a large reply, and the reply lands on the victim. The ratio between request and reply is the amplification factor, and it is a property of the protocol, not of the attacker. The well-known cases are all services that answer over UDP with no handshake, so the source address is never verified. This is why an open resolver, an open NTP server or an exposed memcached instance is not a neutral fact about your network: it is a weapon that someone else will point at a third party, with your address on it. Amplification factors by protocol. The last row is the reason memcached on a public interface became an emergency rather than a misconfiguration. The defence has two halves and they belong to different people. If you operate the service being abused, you close it to the public internet: an authoritative resolver should not answer recursion from strangers, and nothing that speaks amplification-prone UDP should listen on a public address. If you are the target, you need capacity you do not own, which in practice means a provider that can absorb and filter the traffic upstream, before it reaches your link. The uncomfortable truth is that the second half costs money in proportion to the attack, and no amount of server-side tuning substitutes for it. Rate limiting is the mitigation that actually gets deployed, and it is a study in collateral damage. Every layer at which you can count has a group of legitimate users who look like one attacker. Counting by source address punishes everyone behind a shared office connection or a carrier-grade NAT, which is to say most mobile users. Counting by account lets an attacker with many accounts stay under the limit while a script that exports data legitimately gets blocked. There is no layer that avoids this, because the limit is a boundary drawn through a continuum, and it will always cut through somebody. The practical design is to combine several weak signals, to raise the cost of acquiring the thing you count, and to make sure the limit fails in a way that degrades rather than breaks. Every layer you can count at, and the legitimate traffic that gets caught in it. The right answer is usually more than one of these at once.

normal open
  client  SYN          ->  server
  server  SYN-ACK      ->  client
  client  ACK          ->  server      connection established

backlog pressure
  client  SYN          ->  server     half-open, in the backlog
  server  SYN-ACK      ->  client     no reply ever comes
  ... thousands more, backlog fills, new SYNs are dropped

SYN cookies  the server answers without storing state
             the ACK carries back everything it needs

cost to the server: one SYN, 40 bytes
cost to the attacker: one spoofed source addressA SYN flood in detail. The asymmetry that makes it work is that the attacker spends one small packet and the server spends memory and a timer.

Practice

  1. A user on a hotel network reports that a browser warns about the certificate for their bank, and that the page looks normal after clicking through. Which explanation fits the evidence best?

    Hints
    • Ask what the attacker would have to produce for the client to accept the connection. A certificate is a signature, and the signature has to chain to something the device already trusts.
    • If TLS really were broken by a network attacker, changing the password would not help either, because the new password would travel over the same channel.
  2. Match each attack to the layer it works at and what it needs to succeed.

    Hints
    • Name the layer each attack works at: link, name resolution, transport, or the shape of the traffic itself.
    • One attack here does not break anything at all. It just sends more traffic than the link can carry, which is why no amount of filtering on the server side fully answers it.
  3. Write rateLimiter(limit, windowMs). It returns allow(key, now), which returns true when that key has made fewer than limit requests in the last windowMs milliseconds, counting only requests that were allowed.

    The code runs on your machine, not on ours — we do not execute it. Check your solution against each requirement and mark the ones it satisfies.

    Hints
    • Keep a list of the timestamps you have already accepted. On every new request, discard the ones that fell out of the window, then look at what is left.
    • Limit per key first and per source second. A single global counter is the one design that always fails, because it lets one noisy client lock out everybody.

Questions about this lesson

Is it free?

Yes. The first level of every subject is free and needs no account. Deeper levels and the senior grades are paid — that is what keeps the project running.

What age is this for?

It is written for curious teenagers from about 12 and for adults starting from zero. Nothing assumes prior programming experience; lessons about networking and physics need no mathematics beyond school level.

Do I need to know programming already?

No. The logic, physics and networking tracks start from nothing. The languages track is where you actually write code, and it also starts from the beginning.

Do I need to install anything?

No. Everything runs in the browser: theory, practice and the interactive simulations. There is nothing to download and no environment to configure.

How long does one subject take?

A lesson takes 10 to 15 minutes. A junior grade is roughly 12 to 20 lessons, so expect a few weeks of steady practice rather than one evening.

Do I have to follow the order?

Within a grade, levels open one after another, because each builds on the previous one. Between subjects you are free: start with logic, physics or networking.