Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

The Internet is an invaluable invention that directly contributes to the rise of computer systems fueling the modern world’s globalization, for the better or worse. Conceptually quite simple, its primary goal is to move bytes of data from one location to another. However, even this simplest goal can turn to an immense challenge at scale, where parts of the Internet are operated, built and then evolve from different entities that have to set a common language to understand each other.

Protocols are this common language. There exist many protocols carrying responsibility for various tasks altogether contributing to the simple intuitive idea to move bytes from one location to another. Examples are ARP, DHCP, BGP, IS-IS, OSPF, TCP, UDP, HTTP, etc. These protocols are defined by a standard body through RFCs (Request For Comments) at the IETF (Internet Engineering Task Force) and IRTF (Internet Research Task Force). Anyone can participate to the discussions as they happen through public mailing list channels, and public events. Not so simple eventually.

To add to the complexity, some protocols are deeply flawed but remain used due to the difficulty to altogether upgrade and replace a given massively deployed protocol. Moreover, the concept itself of ‘flaw’ evolves in time. Years ago, computer security was not as critical as today, and Privacy was not even part of computer security. This has lead to various existing protocols that completely lack any security and privacy considerations, and attempts to solve these problems by adding new protocols to encapsulate the culprits and solve their deficiencies, sometimes themselves containing flaws that are understood much later and then painfully addressed. The good news, however, is that the higher the protocol lives in the stack abstraction, the easier it becomes to address any unforeseen issue.

What is the stack abstraction? You may already have heard of it as the OSI conceptual model (Open Systems Interconnection) which refers to a comprehensive description the design of the Internet through layers.

OSI LayerProtocol Data Unit (PDU)Function
7. ApplicationDataHigh-level protocols for resource sharing or remote file access (e.g., HTTP).
6. PresentationDataData translation, character encoding, compression, encryption/decryption.
5. SessionDataManaging communication sessions between two nodes.
4. TransportSegmentReliable data transmission, segmentation, acknowledgment, multiplexing.
3. NetworkPacket, DatagramAddressing, routing, and traffic control in multi-node networks.
2. Data LinkFrameData frame transmission between directly connected nodes.
1. PhysicalBit, SymbolRaw bit stream transmission over physical media.

In this model, protocols belong to a given layer and software implementing these protocols may have an interface to make their service available to the upper layer if required. For this class, we will be interested mostly by some protocols in layers 3 to 7. We won’t however cover all of them in details. So, there is a system level interface that defines how the various software implementing these protocols interact. The system interface may be close to the OSI conceptual model, but not necessarily exactly the same. I.e., it is possible that a software on layer 7 directly touches specific aspects of layer 4. Usually it is not the case, but when this happens, there are performance consideration motivating breaking the layer of abstractions.

However, on the wire, the format for transmitting the information looks closer to the OSI independently of the system stack abstraction, but reversed. Here’s an example:

→ First bit transmitted
┌─────────────────────────────────────────┐
│ Link Layer Header                       │  Layer 2
│   (e.g., MAC addresses, frame control)  │
├─────────────────────────────────────────┤
│ Network Layer Header (IP)               │  Layer 3
│   (e.g., source/dest IP addresses)      │
├─────────────────────────────────────────┤
│ Transport Layer Header                  │  Layer 4
│   (e.g., TCP ports, sequence numbers)   │
├─────────────────────────────────────────┤
│ Application Data                        │
│   (structure varies by application)     │  Layer 7
│   ...                                   │
│   ...                                   │
└─────────────────────────────────────────┘

During transfer, it is usual/expected that equipment of a given layer modifies some field(s) within the same layer. E.g., Switch or Router software on layer 3 would typically change some value(s) within the layer 3 header as intended by the protocol, without (hopefully) touching anything else. But sometimes, layer N equipments may find interesting to read/modify information on layer N+1. This is the case in routers for example, where some of them may use information from the Transport layer header to adapt their behavior, such as the size of their internal buffers used to store the data to route. This is understandable but a bad practice that has lead to a significant problem in the Internet, called ossification. Essentially, higher layers that are expected to be easier to evolve become dependent of the lower layer’s lifecycle, which is much longer, preventing their evolution, i.e., ossifying. This is the reason why deploying a new transport protocol, including new secure solutions, is difficult, and sometimes close to impossible. You would probably have a better chance to build a house on the moon than designing and implementing something else than TCP or UDP and making it work over IP on the global Internet. It should be possible in theory. In practice, it does not work due to ossification.

Threat model

From the Internet user’s perspective, we consider attackers location and capabilities. By the location, we mean:

  • The attacker is on-path of the traffic
  • The attacker is off-path of the traffic

By capabilities we mean:

  • The attacker can read packets
  • The attacker can modify packets
  • The attacker can inject packets

A threat model is a combination of location and capabilities that should make sense for the problem studied. For example, we may consider a on-path attacker who can inject packets. Facing such an attacker, protocols and systems should be resilient. On the other hand, an off-path attack who can only read packets may have little interest.

Security issue(s)

Following a given threat model, an attacker may attempt to attack a networking system covered by a given protocol or set of protocols. The goal of the attacker may vary, but could be one of the following:

  • Breach of confidentiality: the attacker can read content
  • Breach of authenticity: the attacker can usurp someone else’s identity.
  • Breach of availability: the attacker can deface a service, or use vulnerabilities within a given protocol to help themselves with this task.
  • Breach of Privacy: the attacker can arbitrarily interfere with user’s activities over the network.

Ideally, the Internet should be designed such that these security problems are prevented. In practice, well, many Internet protocols didn’t consider these threats in their design. We are still recovering from past mistakes adding backward-compatible layers of new protocols to address existing vulnerabilities.

Layers 2-3

IP

IP for Internet Protocol is the basic protocol for addressing over the Internet. IPv4 is the most commonly IP packet format on the Internet, slowly being phased out by IPv6. IPv4 is a 32-bits address representation that we usually display in human-readable form, for example 138.48.5.222 the IPv4 address of unamur.be where each number is a 8-bits integer. Here’s its packet header structure:


 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL  |Type of Service|          Total Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Identification        |Flags|      Fragment Offset    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Time to Live |    Protocol   |         Header Checksum       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Address                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Destination Address                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options (if IHL > 5)                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Data (Payload)                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

IPv4 by default does not contain any information that supports a Internet user to prove that it indeed owns the address contained in a packet sent by that user. This lack of authentication within the IP layer has lead to many issues on the Internet and are still a problem today. Indeed, an attacker can forge the Source Address field and put anything relevant to its attack goal, usually dependent on the above layers transport and application. For example, the tool rlogin predates SSH and was used in the past to remotely connect to another machine. The security model of rlogin was simple: a user was able to connect if it owns an IP which is whitelisted by the rlogin server. Of course, if the attacker is on-path of a rlogin session and can read packets, it can learn about authorized IPs and then send appropriate forged packets to connect.

These kinds of problems motivated stronger, more complex protocols and implementations to guarantee that only authorized users can connect. SSH uses cryptography and authentication based on digital signatures to address IP’s lack of authentication.

There are also other subtle problems with IPv4. For example the identification field is used to reassemble fragmented IP packets. All packets carrying the same identification value could then be reassembled into a single packet for processing at the recipient. However, the choice of identification value may leak information about the implementation since it is implementation dependant, and thus breach Privacy as an attacker can exploit this information for various nefarious information collection, such as guessing how many machines are behind a given NAT gateway, which ones are currently responding, which ones are not. A nefarious employer could use this vulnerability to check when your teleworking habits: when you turn on your computer, and when your turn it off.

In general, a field value that is implementation dependant is a bad design practice for Privacy.

IPv6 is a simplistic, more clever evolution of IPv4, which gives more space to addresses (128-bits instead of 32-bits) and remove some fields:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| Traffic Class |           Flow Label                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Payload Length        |  Next Header  |   Hop Limit   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                         Source Address                        +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                      Destination Address                      +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
.                                                               .
.                       Payload (Data)                         .
.                                                               .
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The Flow Label is a particular 20-bits value chosen to map all packets to a given flow, usually chosen at random by the layer-4 implementation. This value may as well be used to fight on layer-3 any off-path injection of forged packet to a given destination; i.e., if it does not belong to an existing Flow Label, then the packet could be dropped by the layer-3 equipment. An off-path attacker would have to guess a 20-bits value to successfully forge an IP packet. Of course, an on-path attacker would not be annoyed by such a defense.

IPv6 has no checksum to verify header integrity. This task is left to the above layer’s checksum also checking for data integrity, such as TCP checksum. One benefit of this is purely for routing performance. Any layer-3 equipment which is lowering the Hop Limit value as the packet passing by does not have to recompute the checksum. Note that these checksums are not to guarantee message integrity from a security standpoint. It is merely a tool to detect wire errors.

IPSec

Since IP was designed with no security requirements, IPSec was meant to solve its issues as a layer-3 protocol providing header and payload authentication as well as payload encryption. IPSec was originally developed by the US. Naval Research Laboratory in the 90ies alongside IPv6, and was meant to be deployed at the same time as IPv6.

In particular, IPSec authenticates all IPv6 fields that are not explicitly designed to be mutable by the IPv6 protocol and extension, so all but: Flow Label, Hop Limit, ECN extension (Explicit Congestion Notification) and the Traffic Class field. Everything else is authenticated and would cause a hard error if it changes on the path. It brings security against on-path attacks who modify packets but makes interaction with middleboxes such as NAT more complex, since these boxes are designed to modify non-mutable information such as IP addresses on-path. This is a perfect example where adding security prevents existing network material to properly function, and further require changing the architecture of the internet itself, to some extend.

Most IPSec deployment today are for VPNs (Virtual Private Networks) and do not enforce source address verification due to the fact that the client is likely behind a NAT changing its source address, invalidating the packet integrity. The communication is still encrypted, but VPNs provider do not resist forged packets as a consequence, limiting IPSec’s benefits.

Out of curiosity, you may read how to configure an IPSec route on ArchLinux. Although, it might not be your best option today if you mean to setup an IP-link VPN.

ARP

ARP stands for Address Resolution Protocol to bridge layer 2 using MAC addresses with layer 3 using IPv4 addresses. ARP is a simple protocol with no security considerations to bridge IP and MACs on a local network. Assume Alice has IP 192.168.1.3 and wants to send a message to Bob and Alice knows that Bob’s IP is 192.168.1.2. To send the message on the wire, Alice needs Bob’s MAC address. Thus, Alice will do the following:

  1. Broadcast a query “What is the MAC address of 192.168.1.2” over the local network (e.g., over the broadcast address 192.168.1.255) to every computer in the local network. This query fits into a single ARP packet.

  2. Bob’s computer at 192.168.1.2 gets the broadcast message and responds saying “I am 192.168.2.1, and my MAC address is 1B:AD:CA:FE:00:00”. Importantly, every other computer on the local network is not answering the query. The answer fits into a single ARP packet.

  3. Alice gets a mapping Bob 192.168.1.2 = 1B:AD:CA:FE:00:00.

These packets are carried at the data link layer (layer 2) with an EtherType 0x0806 to identify the ARP frames. On the wire, you’ll find an Ethernet Header and a payload encapsulating the ARP packet. The content of the Ethernet Payload is as follows:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Hardware Type (16)    |       Protocol Type (16)      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  HW Len (8)  |  Proto Len (8) |       Operation Code (16)     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Sender Hardware Address (48)              |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Sender Protocol Address (32)              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Target Hardware Address (48)              |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Target Protocol Address (32)              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Hardware Type indicates 0x0001 for Ethernet. Protocol Type indicate the protocol being resolved by the ARP query (0x0800 for ipv4). Operation Code defines whether it is a request or a response (1 or 2 in binary) and the remaining should be self-explicit. Therefore, an ARP packet for Alice’s query would look like this:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            0x0001             |             0x0800            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     0x06      |       0x04    |             0x0001            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Alice MAC addr                         |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Alice IPv4 addr                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        0x000000000000                         |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Bob IPv4 addr                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

There is however a subtlety for the Target Hardware Address during the request. This is the value we’re looking for, so in practice this field is ignored while existing nonetheless. It is filed with zeroes.

And Bob’s response looks as follow:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            0x0001             |             0x0800            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     0x06      |       0x04    |             0x0001            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        BoB MAC addr                           |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Bob IPv4 addr                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Alice MAC addr                         |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Alice IPv4 addr                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Containing all the information needed for Alice’s mapping.

From a security standpoint, against an on-path/off-path attacker with packet injection capability, the problem should be relatively straightforward: Alice will trust the first response! This response may be spoofed by the adversary. There are two cases:

  • On-path attacker with packet modification capability. The attacker may wait for Bob’s response and modify it as it wants, indicating another MAC address, making Alice’s message intended to Bob sent to someone else on the local network.

  • Off-path attacker with packet injection capability. The attacker is racing against Bob’s response. The first to arrive to Alice wins.

A few possibilities to defend:

  1. Monitoring any suspicious activity. Software tools like arpwatch generates logs of suspicious events and can automatically follow-up with emails and notifications to the network sysadmin.

  2. Using a hardware switch that caches MAC addresses. Both on-path and off-path attackers would get their fake ARP packet dropped if their victim successfully got its MAC cached on the switch beforehand. This would essentially depends on the security of the mechanism used when a computer first joins a local network.

IP assignment with DHCP

DHCP stands for Dynamic Host Configuration Protocol, it is a client-server protocol between a new computer joining a local network and acting as a client, and a router distributing IP addresses over the local network and acting as a DHCP server among its other tasks.

The protocol design is similar to ARP in terms of security. It is a trust on first use policy composed of two round trips:

+---------+                     +---------+
| Client  |                     | Server  |
+---------+                     +---------+
     |                               |
     |        DHCP DISCOVER          |
     |------------------------------>| (Broadcast)
     |                               |
     |        DHCP OFFER             |
     |<------------------------------| (Unicast or Broadcast)
     |                               |
     |        DHCP REQUEST           |
     |------------------------------>| (Broadcast)
     |                               |
     |        DHCP ACK               |
     |<------------------------------| (Unicast or Broadcast)
     |                               |

The client does not know first where is the DHCP server. So it uses the broadcast address of the client’s configured subnet. If there is a DHCP server listening on the subnet’s broadcast address, it will send an offer with IP addresses and suggested configuration settings. The Client then broadcast again its choice (as a request), and the DHCP server eventually confirms with an acknowledgment.

The attack scenarios are similar to the ARP case. An off-path attacker could for example offer its own address as a gateway to the victim and act itself as a router, promoting itself to an on-path attacker. The attacker could then see every DNS request and spy over the victim’s Internet usage.

Defenses against these sort of problems typically rely on fixing DHCP by offering secure transport protocols that resist on-path attackers, also sometimes (historically) called man-in-the-middle. TLS/TCP and QUIC are example of secure transports that would prevent these mischiefs to some extend; although, note that it is not really fully solving the problem, since the adversary is still seeing everything, but encrypted. If Privacy is what we care about, there is still a lot of information that the adversary can gain. But these considerations are out of scope of this class.

BGP (and BGP hijacking)

The Internet interconnect local networks. These interconnections are configured on Border Routers using the Border Gateway Protocol (BGP). Details of BGP are complex and out of scope but the basics are relatively straightforward. A few important definitions and notes:

  • ASs (Autonomous Systems) are identified by a unique ID called ASN (Autonomous System Numbers). An AS is a local network managed by a given organisation. Conceptually, an AS is mixing Governance requirements with computer system requirements in protocols. That is, AS numbers are used inside BGP messages to exchange information, and also within the outside world to get information about the entity running the local network. You can retrieve public information from an AS with the whois database; e.g., hit whois AS42 in your terminal to get to know some details about the entity running AS 42.

  • eBGP stands for external BGP sessions. eBGP sessions exist between BGP routers of different ASes to exchange information about reachable IPs.

  • iBGP for internal BGP sessions. An AS may contain many BGP routers interconnecting the AS to other ASes at many places. To distribute knowledge received from external sessions through eBGP, iBGP is used in between these routers. To route the packets inside the AS and connect those BGP routers, the AS may be using what we call IGP for Interior Gateway Protocols (e.g., OSPF, IS-IS) to route the iBGP messages. The reason for not using iBGP everywhere stems from the fact that these protocols’ state machines are inherently different: BGP react on new routes or removal of routes from the outside world. IGP protocols check liveness and react to events within the AS itself. Making them different layers may also contribute to network robustness from configuration errors (e.g., bad route propagations), and scalability (local changes should not breach out of the local domain; one way to ensure this is having different set of protocols and implementations).

BGP was designed in the 80ies, and we are now using its forth iteration published in RFC4271 focusing on route aggregation to limit the size of routing tables on BGP routers, which had become a problem. BGP routers connect to each of their neighbours using the TCP transport protocol, and exchange specific BGP eBGP connections are usually directly manually configured router-to-router wired connections exchanging BGP messages over TCP on port 179. Routes learned from a given eBGP peer are re-advertised to the local iBGP and other eBGP peers. Routes learned from iBGP peers are only re-advertised on eBGP neighbors. Given this policy, we need a full mesh of iBGP sessions internally within a given AS to have correct route propagation.

An AS may receive route information towards a given subnets from different peer ASes, and has to make a choice to route the packets in either direction. Both direction are expected to be valid; BGP announcements are based on trust. BGP runs a path selection algorithm to locally make a decision when multiple possibilities are available. This selection algorithm is partially opaque and depends on local AS configured preferences that are not public knowledge. However, default configurations prioritize shortest path and most-specific subnet announcement. I.e., if some destination is routable through a /24 IPv4 prefix on neighboring ASes, and if these ASes suddenly receive a /16 announcement towards the IP range including the /24 subnetwork, then this route will be preferred and the previous one forgotten. It is all good as long as the /16 announcement is honest. However, it could also be malicious, or the result of a configuration mistake on a peer AS, diverting the traffic into an Internet black hole or ‘hijacking’ the path towards the destination (hijacking is only possible in a specific case).

So, each AS announce through eBGP IP prefix that originates from them. In turn, other ASes receiving these announcements re-advertise them internally and externally. A BGP path selection run by each Border Router decides the direction for a given IP if there are many possibilities. A direction towards some destination can be hijacked iff:

  1. An AS, say AS_X announces a prefix that does not originate from it to a selected BGP peer.

  2. The path selection prioritizes the announcement over the original one due to a shortest route.

Every ASes which prioritized the route towards AS_X are effectively ‘hijacked’. It can be a part of the Internet, but not all of it (by design), since AS_X has to forward traffic to a peer and a portion of the Internet that is not impacted by the malicious announcement for the redirection to succeed. The graph of the Internet can be built from public BGP data, and we can “easily” evaluate how to do this from a given AS to another.

Announcing a most specific IP prefix towards a destination that we do not own would however propagate to the whole Internet and result in a traffic black hole at the announcer is incapable of redirecting towards the legitimate owner.

How can we defend this?

  • Filtering rules (but impacts configuration flexibility).
  • BGP monitoring and manual reconfiguration after-the-fact.
  • RPKI (Resource Public Key Infrastructure) to distribute keys and certificate to each AS to sign/verify route origin announcements with a BGP extension (BGPSec, RFC8205) and handle origin transfer. We’ll discuss PKIs (Public Key Infrastructures) below.
  • S-BGP, for curious minds.

Layers 4-7

TCP/IP Security

TCP is a reliable ordered connection-based protocol with a stream-based interface. I.e., using TCP, we first establish a connection and then read/write into a single stream.

Minimal simplistic example using blocking IO:

use std::io::{Read, Write};
use std::net::TcpStream;

fn main() {
    // Connect to server
    let mut stream = TcpStream::connect("127.0.0.1:8080").expect("Connect error");
    println!("Connected to server!");

    // Send message
    stream.write_all(b"Hello from client").expect("Write IO error");

    // Read response
    let mut buffer = [0; 65536];
    let size = stream.read(&mut buffer).expect("Read IO error");
    let response = String::from_utf8_lossy(&buffer[..size]);
    println!("Server response: {}", response);
}

Server code:

use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};

fn handle_client(mut stream: TcpStream) {
    let mut buffer = [0; 65536];

    // Read data from client
    match stream.read(&mut buffer) {
        Ok(size) => {
            let received = String::from_utf8_lossy(&buffer[..size]);
            println!("Received: {}", received);

            // Send response back
            stream.write_all(b"Hello from server").unwrap();
        }
        Err(e) => println!("Failed to read from client: {}", e),
    }
}

fn main() {
    let listener = TcpListener::bind("127.0.0.1:8080").expect("Bind error");
    println!("Server listening on 127.0.0.1:8080");

    // Accept connections
    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                handle_client(stream);
            }
            Err(e) => {
                println!("Connection failed: {}", e);
            }
        }
    }
}

This will perfectly work over the network as long as lower layers ARP, DHCP, BGP, IP perform their role as intended. TCP will send data alongside a TCP header:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  DO   | RSV |      FLAGS      |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             Data                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

So, part of the information provided by the code above is directly written within the TCP headers, such as the ports. Other fields are handled by the TCP implementation itself and are required for TCP’s correct assurance of ordered and reliable stream. Is there any security problem with this approach? Plenty!

  • Probing: the range of IPv4 is only [0..2^32-1] IPs, and ports are reserved for known applications and services. It is relatively fast and simple to probe the whole internet with a common 1 Gbps uplink, for example to discover unmaintained services.

    1 Gbps = 125 MB/s link. Assuming 40 minimum packet size (IP header 20 bytes + minimal TCP header 20 bytes), to scan the whole internet on a single port, we need sending 2^32 packets of 40 bytes at most.

    => 125 MB/s = 3125000 packet/s of 40 bytes

    => We can send 2^32 packets in 2^32 / 3125000 seconds = ~23 minutes.

    Tools exist to scan the Internet, and should be used with care and with ethical guidance.

  • TCP Syn flooding usually with source spoofing. With a 1 Gbps uplink, one can send 3125000 TCP/IP Syn packet with random source address towards a victim, which has to try completing 3125000 TCP three-way handshakes every second; i.e., processing SYN packets, generating SYN+ACKS. This is CPU costly.

  • TCP Connection hijacking. Hijacking an existing connection and injecting packet is trivial for an on-path attacker. For an off-path attacker, the attacker has to guess the Sequence number to inject packets with the right sequence (assuming the attacker knows who’s communicating, i.e., what are the IPs and ports). In turns out that guessing a 32-bits integer was simplified against many implementations of TCP due to poor choice of initial sequence number (not truly random, predictable). Details of these attacks are complex but are to be found in the academic literature, for curious minds

  • TCP Connection RST. Again, trivial on-path, but is also possible off-path is the sequence number can be guessed right. Many attempts are also possible.

TLS/TCP and QUIC

TLS/TCP and QUIC are the two most common secure transport protocols on today’s usage of the Internet. QUIC has been recently standardized as RFC9000, and works as a fully-fledged reliable and secure transport protocol above UDP. QUIC is using TLS 1.3’s cryptographic handshake to derive a secure symmetric key, and the same symmetric cryptography algorithm for encryption and decryption than TLS 1.3. From a security standpoint, both QUIC and TLS 1.3 try to solve the same security problem, namely the confidentially and authenticity of data over an insecure network.

So these protocols have typically two phases. The handshake phase establishing a secure session, and the session phase where the key material is available and data can be securely exchanged.

The handshake phase uses asymmetric cryptography to negotiate a symmetric key while being resilient to an on-path attacker. To obtain this guarantee, we perform a Diffie-Helmann key exchange (which would be studied in INFOM119), and the server signs its own session key material using a long-term private key whose public counterpart is sent within a certificate, itself signed by an authority. The client knows about this authority and can verify the certificate, as well as the session key material. If both are ok, then the client is guaranteed to talk to the correct server.

Here’s a sequence diagram of TLS1.3 handshake phase:

+-----------+                                     +-----------+
|  Client   |                                     |  Server   |
+-----------+                                     +-----------+
      |                                                 |
      | 1. ClientHello                                  |
      |   - Key Share (ClientKeyShare)                  |
      |   - Cipher Suites                               |
      |   - SNI (optional)                              |
      |------------------------------------------------>|
      |                                                 |
      | 2. ServerHello                                  |
      |   - Key Share (ServerKeyShare)                  |
      |   - Selected Cipher Suite                       |
      |                                                 |
      | 3. EncryptedExtensions                          |
      |   - Additional parameters (e.g., ALPN)          |
      |                                                 |
      | 4. Certificate*                                 |
      |   - Server's certificate chain                  |
      |                                                 |
      | 5. CertificateVerify*                           |
      |   - Proof of private key ownership              |
      |   (Signed over handshake hash)                  |
      |                                                 |
      | 6. Finished                                     |
      |   - HMAC over all handshake messages            |
      |<------------------------------------------------|
      |                                                 |
      | 7. Finished                                     |
      |   - Client's HMAC verification                  |
      |------------------------------------------------>|
      |                                                 |
      | 8. Application Data (Encrypted)                 |
      |<===============================================>|

The 5. point is the signature over the session key material (in fact, a signature over a hash of all the information seen up to 5., including the session key material). In 6. HMAC can be seen as a symmetric signature using a symmetric key (i.e., the key derived after 2.). This again will be covered in INFOM119.

Once the handshake is done in 8., client and server exchange Application Data into TLS 1.3 records. They have the following format:

+----------------+-----------------+-----------------+---------------------
|Content Type (8)|    0x0303 (16)  |    Length (16)  | Encrypted Payload (max 131072)
+----------------+-----------------+-----------------+---------------------

Note that the Encrypted Payload always contains 1 byte at the end of the real Content Type; The Content Type in the header is a placeholder type of value 0x17 after handshake (and 0x16 during handshake). The real one is part of the encryption to prevent ossification after handshake.

QUIC’s format is slightly more complex than TLS. TLS is supposed to work atop any reliable stream abstraction, such that we could technically swap TCP to any other protocol giving the same properties. QUIC however, is a standalone protocol offering a secure multi-stream reliable and ordered abstraction atop UDP. Its wire format is fully encrypted with a specific encryption for the QUIC header, and a specific encryption for the QUIC payload mixing Application data with QUIC control logic. More details on the QUIC protocol is available for curious minds.

Certificates & PKI

Assume Bob is talking to Alice’s service, e.g., in the case of the Web (but not only!) as sending an HTTP GET request to retrieve content. To send the GET request securely, Bob first wants a secure channel, and hence would be using a secure transport protocol such as TLS/TCP or QUIC.

Secure transports such as TLS and QUIC exchange key material; but the authenticity of the key material (i.e., am I really talking to Alice?) depends on a trusted third-party issuing a certificate for Alice’s service. All this relationship design is called a Public key Infrastructure (PKI). Some public keys in the case of the PKI for the web would be called Root keys, and would be written down in Browsers. These Root keys belongs to CAs (Certificate Authorities). There are plenty of them.

Certificate Authorities are able to issue a signature over a certificate that attests Alice is running a service such as alicewebsite.com. This is called a certificate chain. Then, this certificate is being delivered in the secure transport handshake, with a signature using the certificate’s related private key.

Note that usually Root authorities do not issue certificate directly themselves for web services, but they issue a certificate for Certificate Authorities that could then issue certificates for services, forming a chain of certificates.

What is typically contained within a certificate? We can have a look at the one of our university unamur.be:

$ echo | openssl s_client -showcerts -servername unamur.be -connect unamur.be:443 2>/dev/null | openssl x509 -inform pem -noout -text

These commands will connect to unamur.be, perform the TLS handshake and print the certificate received from unamur.be. We get:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            60:db:93:95:e9:eb:63:0e:a7:de:e8:a2:f6:d5:31:13
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = NL, O = GEANT Vereniging, CN = GEANT OV ECC CA 4
        Validity
            Not Before: Dec 19 00:00:00 2024 GMT
            Not After : Dec 19 23:59:59 2025 GMT
        Subject: C = BE, ST = Namur, O = Universit\C3\A9 de Namur, CN = www.unamur.be
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:4a:06:bd:3b:0d:91:00:2a:67:24:7b:d3:7d:32:
                    38:cc:6c:fa:f1:40:11:7f:eb:2f:8d:f2:97:70:65:
                    03:79:39:3d:44:71:8b:fb:43:ec:bd:8b:5d:f9:4e:
                    c9:b2:58:86:79:14:89:cc:4b:40:8b:02:bb:c1:b1:
                    1d:9e:7f:f8:f8
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Authority Key Identifier: 
                ED:B4:A0:33:6A:1B:08:91:B6:BD:FA:41:92:BD:9A:AB:AB:63:F4:53
            X509v3 Subject Key Identifier: 
                39:4B:5D:4F:52:2E:F8:57:FC:53:E4:0F:F8:A9:BC:EE:73:F5:86:EE
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Certificate Policies: 
                Policy: 1.3.6.1.4.1.6449.1.2.2.79
                  CPS: https://sectigo.com/CPS
                Policy: 2.23.140.1.2.2
            X509v3 CRL Distribution Points: 
                Full Name:
                  URI:http://GEANT.crl.sectigo.com/GEANTOVECCCA4.crl
            Authority Information Access: 
                CA Issuers - URI:http://GEANT.crt.sectigo.com/GEANTOVECCCA4.crt
                OCSP - URI:http://GEANT.ocsp.sectigo.com
            CT Precertificate SCTs: 
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : DD:DC:CA:34:95:D7:E1:16:05:E7:95:32:FA:C7:9F:F8:
                                3D:1C:50:DF:DB:00:3A:14:12:76:0A:2C:AC:BB:C8:2A
                    Timestamp : Dec 19 12:43:46.308 2024 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:46:02:21:00:9F:52:5D:3D:89:72:D5:A5:67:39:D4:
                                4E:6B:DF:98:C7:BB:EB:3A:86:7C:5C:CE:22:EE:04:5E:
                                F7:C3:44:6A:8E:02:21:00:F7:13:C8:1E:57:13:61:BA:
                                CD:73:FB:26:CF:FD:68:42:33:27:20:6E:69:5A:A9:72:
                                C9:F7:AB:20:0A:45:6A:15
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : CC:FB:0F:6A:85:71:09:65:FE:95:9B:53:CE:E9:B2:7C:
                                22:E9:85:5C:0D:97:8D:B6:A9:7E:54:C0:FE:4C:0D:B0
                    Timestamp : Dec 19 12:43:46.570 2024 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:44:02:20:06:40:A8:8A:FF:33:13:44:80:2E:C7:F4:
                                77:B7:05:F0:D3:9F:17:EA:51:D6:C6:06:71:BB:C3:C1:
                                85:6E:1D:BD:02:20:1B:E3:71:F3:67:1D:C6:4D:F5:F1:
                                88:F1:D0:5F:7C:DB:0F:09:1C:D2:E0:C9:ED:E5:B1:3E:
                                D1:89:96:A9:6B:62
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : 12:F1:4E:34:BD:53:72:4C:84:06:19:C3:8F:3F:7A:13:
                                F8:E7:B5:62:87:88:9C:6D:30:05:84:EB:E5:86:26:3A
                    Timestamp : Dec 19 12:43:46.276 2024 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:44:02:20:4C:C7:D3:76:3A:92:E3:23:58:E4:F5:EC:
                                28:FD:B3:C5:DC:BF:01:7F:FD:72:75:BD:D1:C1:06:C6:
                                E8:0B:E0:A1:02:20:01:AE:D6:F9:6C:0E:0C:F2:A8:13:
                                7E:6F:A3:FB:1D:67:7F:22:24:9C:11:10:3B:24:AE:7E:
                                AC:B6:DE:4D:90:7B
.            X509v3 Subject Alternative Name: 
                DNS:www.unamur.be, DNS:unamur.be
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:45:02:20:33:be:21:9e:e6:89:14:84:4a:bd:f6:4f:dc:96:
        9c:d0:ba:da:87:a7:4a:68:dd:fe:33:76:d6:32:5e:a6:b0:c4:
        02:21:00:94:1f:b2:94:5f:3f:c6:b5:00:4c:bd:8d:e0:41:29:
        9d:7a:a2:b6:73:14:5c:29:d4:c6:c3:fb:f3:f4:bd:5b:f0

Some of the fields of interest:

  • Issuer, the entity that signed this certificate.
  • Subject, what this certificate is for.
  • Subject Public Key Info containing the public key for this certificate. Note that the comments about the size of the public key indicated as 256-bits refers to the security level of the key algorithm used. In this case, we have an elliptic curve cryptosystem with 256-bits security (P-256 NIST curve), which translates to two 256-bits elements, totaling 512-bits for the key size itself.

Obtaining a certificate

It used to be a difficult process where people would physically go to an issuer and get a signed certificate valid for N years for a given Subject, proving to the certificate authority that we own the Subject.

Today, this process still remains for highly secure certificate and some CA. For common websites, we may also use a CA implementing the ACME protocol, and interact with their ACME server to prove ownership of a given domain and then obtain a certificate. It works as follow:

Participant Client                   Participant ACME Server
    |                                          |
    |--(1) POST /new-nonce ------------------->|  Get fresh nonce
    |<--(2) 200 OK (Nonce) --------------------|  Return nonce
    |                                          |
    |--(3) POST /new-acct -------------------->|  Create account (public key registration)
    |<--(4) 201 Created (Account ID) ----------|  Return account details
    |                                          |
    |--(5) POST /new-order ------------------->|  Request certificate for domain(s)
    |<--(6) 201 Created (Order, Authz URLs) ---|  Return order with challenges
    |                                          |
    |--(7) POST /authz/{id} --------------- -->|  Select challenge
    |<--(8) 200 OK (Challenge details) --------|  Return challenge
    |                                          |
    |--(9) Serve /.well-known/acme-challenge/  |  Client hosts challenge on their domain
    |   (Token + key-auth)                     |
    |                                          |
    |--(10) POST /challenge/{id} ------------->|  Notify server to verify
    |<--(11) 200 OK (Status: pending) ---------|  Acknowledge
    |                                          |
    |  (ACME Server verifies HTTP challenge)   |  ACME Server acts as a client sending a GET
    |                                          |  request to the claimed domain
    |  GET /.well-known/acme-challenge/{token} |
    |                                          |
    |<--(12) POST /order/{id} (Validated) -----|  Challenge success
    |                                          |
    |--(13) POST /finalize ------------------->|  Submit CSR (Certificate Signing Request)
    |<--(14) 200 OK (Certificate URL) ---------|  Return certificate URL
    |                                          |
    |--(15) GET /cert/{id} ------------------->|  Download certificate
    |<--(16) 200 OK (Certificate) -------------|  Return signed certificate
    |                                          |

And that’s enough to prove ownership. I.e., if the ACME Server of the CA can reach your domain and observe the secret value that was given during the original client request, it can conclude that the client really own the claimed domain, and would then comply to issue a certificate (i.e., signing a new certificate with the claimed domain). Note that all the interactions between the client and the ACME server are through a secure channel (HTTPS). Only the challenge verification towards the claimed domain is performed over HTTP, since there is no certificate yet.

The challenge verification is insecure if the attacker in on-path and can respond on behalf of the true domain. In the wild, this already happened in the past to steal cryptocurrencies. I.e., a group of hackers performed a BGP hijack against a cryptocurrency website to become “on-path”, and then requested a certificate to an ACME compliant CA. Eventually, with the certificate, the hacker can pretend to be the given domain – they just need some DNS resolver to point to their IP, and again, there are different ways to poison DNS entries.

Eventually, even with all these mechanisms, it is still possible for motivated adversaries to pretend to be someone else. PKIs are difficult to design and maintain. There exist also certificate extensions, such as Certificate Transparency (that you can see within the UNamur certificate extensions) to monitor and detect unexpected issuance of certificates. Then it is possible for a security sysadmin to react quickly and ask the CA and revoke the malicious certificate existing against their domain.

Revocation

Sometimes, revoking a certificate is necessary. There exist different methods:

  1. CRL (Certificate Revocation List). Simple as it sounds, each CA populates a list of revoked certificate that cannot longer be trusted. Browsers download them and check any certificate during secure connections.

    These lists may however grow quite large, and be intense to download and maintain.

  2. OCSP for Online Certificate Status Protocol is a simple client-server protocol. When a browser receives a certificate, it can asks to the CA’s OCSP server whether the certificate is still ok. It is a simple, trivial to implement protocol, but it has two major drawbacks.

    a) Performance. Browser have to wait for the OCSP response before going on with any request to the domain the user is asking.
    b) Privacy. Suddenly CAs know what Websites each user are visiting from all the OCSP requests.

    Both are equally terrible. OCSP should not be used this way.

  3. OCSP stapling. It solves the two problems of the above naive usage of OCSP. The idea is to let the domain owner and the CA bear the cost of proving that the certificate has not been revoked recently. To do this, the domain owner can query the OCSP server and ask a signature over a timestamp validating the certificate in very short period, and attach (staple) the signature to a certificate extension.