Internet security

Firewalls, packet filtering, proxies and stateful inspection; encryption, certificates and signatures; worms, trojans and viruses.

A12.7Networks and the webA level30 min

Do this lesson in the simulator

At GCSE (F11) you met malware, encryption and firewalls as ideas: a firewall "blocks unauthorised traffic", encryption "scrambles data". At A level you need to explain the mechanisms. There are three kinds of firewall that work in different ways, two kinds of encryption with different key arrangements, and a way of using keys backwards to prove who sent a message. Finally, the three classic kinds of malware are told apart by exactly how they spread.

Firewalls

A firewall is hardware or software that sits between a network and the outside world and controls which traffic may pass, according to a set of rules. There are three ways it can decide.

Packet filtering (static filtering) examines each packet's header on its own: the source and destination IP addresses, the source and destination port numbers, and the protocol. It compares them with a list of rules and accepts, drops (silently discards) or rejects (discards and tells the sender) the packet. Blocking port 23 blocks Telnet; blocking a source address blocks a known attacker. It is fast, but it only sees headers, and it judges each packet with no memory of the ones before.

A proxy server acts as an intermediary: clients inside send their requests to the proxy, which makes the request to the outside server on their behalf, receives the response, and passes it back. The outside server only ever sees the proxy's address, so the internal clients are hidden. Because the proxy handles whole requests, it can inspect the content as well as the headers, blocking particular websites or file types, and it can cache pages that many users request, so they are served faster. It also keeps a log of the requests made.

Stateful inspection keeps a state table of the connections currently open. When a device inside starts a connection, the firewall records it. An incoming packet is then allowed only if it belongs to a connection that was properly started and is in the right state; a packet that claims to be a reply to a connection nobody opened is dropped, even if its port would pass a simple filter. It judges each packet in context, which defeats attacks that forge packet headers to slip through a static filter.

Encryption

Encryption turns plaintext into ciphertext using a key, so that data intercepted on the way is useless without the key to decrypt it.

In symmetric encryption the same key encrypts and decrypts. It is fast, but both ends must already share the key, and sending the key over the network is exactly the risk encryption was meant to avoid: this is the key exchange problem.

In asymmetric encryption each person has a mathematically linked key pair: a public key, which they give to anyone, and a private key, which they keep secret. Data encrypted with one key of the pair can only be decrypted with the other. To send Ada a secret, you encrypt it with Ada's public key; only Ada's private key can decrypt it, so no secret ever has to be shared. Asymmetric encryption is much slower, so in practice (in HTTPS, for example) it is used to agree a symmetric key, which then encrypts the rest of the session.

Digital signatures

Encryption keeps a message secret. A digital signature proves who sent a message and that it has not been changed, which matters just as much: a robot should only obey commands from its real controller.

To sign a message, the sender:

  1. puts the message through a hash function, giving a short fixed-size digest;
  2. encrypts the digest with their own private key. The result is the signature, sent along with the message.

To check it, the receiver:

  1. decrypts the signature with the sender's public key, recovering the digest the sender made;
  2. hashes the message they received themselves;
  3. compares the two digests. If they match, the message was signed with the matching private key, so it came from the sender (authentication), and it has not been altered since (integrity).
# a toy key pair: real keys are thousands of bits long
n, public_e, private_d = 3233, 17, 2753

def digest(message):
    return sum(ord(ch) for ch in message) % n          # a toy hash

def sign(message):
    return pow(digest(message), private_d, n)          # encrypt the digest with the PRIVATE key

def verify(message, signature):
    return pow(signature, public_e, n) == digest(message)   # decrypt with the PUBLIC key and compare

signature = sign("forward 20")
print("signature:", signature)
print("genuine:", verify("forward 20", signature))
print("altered:", verify("forward 90", signature))

Run this in the simulator

But how does the receiver know the public key really belongs to the sender, and was not swapped for an attacker's? A digital certificate solves this. It is an electronic document, issued by a trusted certificate authority (CA), that contains the owner's identity (such as a website's domain name), the owner's public key, an expiry date, and the CA's own digital signature over all of it. A browser holds the public keys of the CAs it trusts, so it can check the CA's signature and know the public key inside is genuine. This is what the padlock in the address bar means for an HTTPS site.

Worms, trojans and viruses

Malware How it spreads
Virus attaches itself to a host program or file. It runs when the host runs, and copies itself into other files. It needs a user to run or share an infected file to spread to another computer.
Worm a standalone program that replicates itself and spreads across a network on its own, exploiting vulnerabilities in networked software. It needs no host file and no user action, so it can spread extremely fast.
Trojan disguises itself as legitimate, useful software, so the user installs it willingly. It then does something harmful, such as opening a back door. It does not replicate itself.

All three rely on vulnerabilities: flaws in software (such as code that does not check the length of its input), in configuration, or in how people behave. Defences address each:

  • Improved code quality: writing, reviewing and testing code so it validates input and does not have exploitable flaws, and patching quickly when a flaw is found. This stops worms at the source.
  • Monitoring: watching network traffic and system behaviour for unusual activity, such as a machine suddenly connecting to many others.
  • Protection: anti-malware software that scans for known signatures and suspicious behaviour, firewalls that block the ports worms use, and training users not to run programs from untrusted sources.

Task: a stateful firewall

Each packet is a tuple (direction, source IP, source port, destination IP, destination port), where direction is "out" (leaving the network) or "in" (arriving). Check each packet against these rules in order, and use the first that matches:

  1. If its source IP is 203.0.113.9 (a blocked address), the verdict is drop blocked.
  2. If it is going out, record the connection (its source IP, source port, destination IP and destination port) and the verdict is allow outbound.
  3. If it is coming in and is a reply to a recorded connection (its source is that connection's destination, and its destination is that connection's source, IP and port both), the verdict is allow reply.
  4. If it is coming in to IP 192.168.4.10 port 443 (the school's web server), the verdict is allow service.
  5. Otherwise the verdict is drop.

Print <packet number> <verdict> for each packet, numbering from 1. Then print allowed <a>, dropped <d>, counting verdicts that begin allow and drop. That is 8 lines. The robot does not drive.

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

BLOCKED = "203.0.113.9"
SERVER = ("192.168.4.10", 443)
packets = [
    ("out", "192.168.4.23", 49152, "203.0.113.80", 443),
    ("in", "203.0.113.80", 443, "192.168.4.23", 49152),
    ("in", "203.0.113.80", 443, "192.168.4.23", 49153),
    ("in", "203.0.113.9", 443, "192.168.4.23", 49152),
    ("in", "198.51.100.7", 51000, "192.168.4.10", 443),
    ("in", "198.51.100.7", 51000, "192.168.4.10", 22),
    ("in", "203.0.113.80", 443, "192.168.4.23", 49152),
]
connections = []

Challenges

  1. Packet 3 looks like a reply but was dropped. Explain what a static packet filter that allows all traffic from port 443 would have done with it.
  2. Add a rule before rule 2 that drops outgoing packets to port 23 (Telnet), and a test packet that shows it working.
  3. In the signature cell, find a different message with the same toy digest as forward 20. What does that tell you about the hash functions real signatures need?