index.md (9809B)
1 +++ 2 title = "Lecture 3: TCP" 3 +++ 4 5 # Lecture 3: TCP 6 7 TCP seq/ack numbers: 8 - sequence: specify position of segment data in communication stream (i.e. if number is 13423, means payload contains data from byte 13423 to byte <length>) 9 - acknowledgment: specify position of next byte expected from comms partner 10 11 TCP windows: 12 - used for flow control 13 - segment only accepted if sequence number is inside window that starts with current ack number (ack number < seq number < ack number + window size) 14 - window size changes dynamically to adjust amount of info sent by sender 15 16 TCP flags: used to manage establishment and shutdown of connection 17 - SYN: request for sync of syn/ack numbers (to set up connection) 18 - ACK: states ack number is valid 19 - FIN: request to shutdown one stream 20 - RST: request to reset virtual circuit 21 22 ## Connection setup (3-way handshake) 23 1. Server listening on port receives connection request from client 24 - segment is marked with SYN flag 25 - segment contains random initial seq number s𝑐 26 2. server answers with segment marked with SYN and ACK flags, containing 27 - initial random seq number s𝑠 28 - s𝑐+1 as acknowledgment number 29 3. client sends segment with 30 - ACK flag set 31 - sequence number s𝑐+1 and acknowledgment num s𝑠+1 32 33 ![Three-way handshake](f470bb253e8b4e9184e3553dca4e5e43.png) 34 35 What's the initial sequence number? 36 - TCP standard (RFC 793) specifies that seq number increments every 4 μs 37 - BSD used number incremented b 64k every half second and every time a connection is established 38 39 ## Connection shutdown 40 FIN: 41 1. One partner sends segment with FIN flag 42 2. Other partner answers with ACK segment 43 3. No more data will be sent from partner that sent FIN, only acks received data. 44 4. Connection closed when acking partner shuts down stream. 45 46 RST: just send a packet with the RST flag. 47 48 ## Spoofing 49 attack to impersonate another host when establishing TCP connection 50 51 Node A trusts node B (e.g. whitelist login from a specific IP). 52 So, node C wants to impersonate node B wrt A when opening TCP connection. 53 54 1. C kills B (denial of service, crashing...) so that B doesn't send RST segments 55 2. C sends TCP SYN to A in spoofed IP packet, using B's address as source IP and s𝑐 as seq number. 56 3. A replies with SYN/ACK segment to B with s𝑠 as seq number; B ignores the segment because it's too gone 57 4. C doesn't receive the segment, but has to send ACK with s𝑠+1 as acknowledgment number 58 - C eavesdrops SYN/ACK segment 59 - or C guesses the right number 60 61 ![TCP spoofing diagram](21511972416148b08947007ad47a3965.png) 62 63 ## Hijacking 64 ### Joncheray-style 65 Takes control of existing TCP connection. 66 Attacker uses spoofed TCP segments to 67 - insert data in streams 68 - reset existing connection (denial of service) 69 70 The correct seq/ack numbers must be used: 71 - can eavesdrop client-server traffic 72 - can guess right seq/ack numbers 73 74 1. Assume attacker can sniff traffic (see all packets between C and S) 75 2. Attacker waits until connection is quiet (all transmitted data have been acknowledged by both endpoints) 76 3. Attacker sends injected data with correct ack𝑐, seq𝑐 77 4. ACK storm ensues: 78 - receiver of injected data sends ack to apparent sender 79 - apparent sender replies with ack with "expected" seq number 80 - receiver considers it out-of-sync, sends ack with "expected" seq number 81 5. ACK storm continues until a message is lost. Any subsequent attempt to communicate will lead to ACK storm. 82 - we can use ARP poisoning to send ACKS to non-existing hardware address 83 - send RST packets to both parties 84 - ACK storms can be blocked by attacker using ACK packets with right numbers 85 6. If packets are desynchronised so much that they're out-of-window, they are automatically dropped by the parties. But attacker can relay and modify the data. 86 87 You can also get desynchronisation by: 88 - waiting for SYN/ACK from S to C 89 - then sending RST to S and open new connection immediately with same port etc. (but different client seq number) 90 - S sends SYN/ACK with A acknowledges, and S now in established state 91 92 ### New attacks - off-path 93 #### Challenge ACK rate limit 94 TCP side channel vulnerability in Linux 3.6+, because RFC 5961 changed the SYN receiving scheme and Linux implemented it to the letter. 95 A challenge ACK packet is sent in an established connection in these cases: 96 - SYN packet with correct <srcIP, dstIP, srcPort, dstPort> (any seq num) 97 - RST packet with correct <srcIP, dstIP, srcPort, dstPort> (in-window seq num) 98 - Data packet with correct <srcIP, dstIP, srcPort, dstPort> (in-window seq num, old ack num that's in challenge window) 99 <!-- data is more complicated, might need to take notes on this: ![39bed64eecbb3a9ee445d99e707dfea5.png](62ecbd0a8d0f4c728cfe66fcbd6b030f.png) --> 100 101 Vulnerability: recommended to rate limit the challenge ACK packets, Linux did this 102 - `sysctl_tcp_challenge_ack_limit`: global limit (default 100) of all challenge ACK per sec, across all connections 103 - fixed in Linux 4.7. can fix by adding random noise to the channel (rate limit) or eliminate it 104 105 Given any two hosts on the internet, a blind attacker can infer: 106 - existence of communication 107 - sequence number 108 - ACK number 109 110 Can be used towards attacks of 111 - TCP connection termination 112 - Malicious data injection 113 114 Threat model: 115 - arbitrary pair client & server 116 - blind off-path attacker (no eavesdropping) 117 - assumption: attacker can send spoofed packets with victim's IP address 118 119 Attack: 120 1. Send spoofed packets with guessed values (like source port) to trigger challenge ACKs. 121 - If the guess is right, the legit client gets a challenge ACK, and we get one less challenge ACK. 122 - If it's wrong, we get all challenge ACKS back. 123 2. Repeat step 1 for either: 124 - SEQ number: spoofed RST packet and 100 legit RST packets 125 - ACK number: spoofed Data packet and 100 legit RST packets 126 127 Time cost is additive, can be done in one minute. 128 Optimise using binary search for ports: send spoofed packet for all ports in first half range, narrow down search space by half and go to next round. 129 130 ACK throttling time synchronisation is important: 131 - challenge ACK count resets each second 132 - so all spoofed and legit packets must be in same 1-second interval at server 133 134 Synchronisation method: 135 - split 1 second into 200 time slots 136 - send 200 RST packets in one second, one in each slot 137 - receive max 200 challenge acks back (100 in first second, 100 in second second) 138 - adjust until you get exactly 100 challenge acks back 139 140 ![Attack diagram](4217be92e89e453e9df657e8e472a9d3.png) 141 142 #### IP identifier (IPID) 143 Still uses challenge acks. 144 Instead of shared limit on challenge acks, use IPID as shared counter. 145 146 Linux > 4.18, two ways to select IPID counter: per socket, or hash-based (shared) 147 148 Attack: 149 1. detect victim clients: 150 - force server's IPID assignment from per-socket to hash-based 151 - DF flag in packet can be cleared with ICMP packet 152 - pretend to be a router, send forged ICMP "fragmentation needed" message to victim server 153 - embed ICMP echo reply data in the forged message 154 - server will clear DF flag of next packets sent to client whose IP address is in embedded echo reply 155 ![Forged ICMP message embedded in echo reply](937f86dc85164555ab04c8b036c386b1.png) 156 - through hash collisions, detect victims with same IPID counter as attacker. 157 - one of 2048 hash counter is selected based on source IP, dest IP, protocol number, and random value 158 - if hash(TCP packets sent to victim) == hash(packets sent to attacker), server uses same IPID counter 159 ![Detecting victims through hash collisions](501ae3d4695e4f028e5a784eb2925f14.png) 160 - hash-based IPID counter doesn't increase linearly, the increment is a random value based on system ticks, so that must be restricted 161 2. detect TCP connections and source port: 162 - continuously send ICMP echo requests, observe IPID values of server's reply 163 - then send SYN/ACK with guessed source IP/port. 164 - if correct: challenge ack and jump in counter 165 - if incorrect: RST packet to real client with IPID 0, so no jump in counter 166 3. infer seq and ack numbers: 167 1. Infer acceptable seq numbers (in server's receive window) 168 - continuously send ICMP request packets to server, observe IPID values of replies 169 - send spoofed RST packet with guessed seq number 170 - if correct: challenge ACK, so increase in counter (IPID) 171 - if incorrect: not in server window, so discarded and no counter increase 172 2. Locate challenge ack window 173 - when receiving data packet, 3 options: 174 - ACK number in challenge ACK window: challenge ACK 175 - ACK number in acceptable ACK range 176 - invalid ACK number 177 - continuously send ICMP request packets to server, observe IPID values of replies 178 - send spoofed ACK packet with guessed ACK number to server 179 - if ACK in challenge ACK window, challenge ACK packet sent & jump in counter 180 - otherwise, no jump 181 3. Detect lower boundary of server's receive window 182 - forge multiple ACKs with constant ACK number that's in challenge ACK window, and seq number set to <acceptable_sequence_number-i> 183 - at start, server will send challenge ACKS one per 500ms 184 - once <acceptable_sequence_number-i> reaches lower boundary, server starts sending duplicate ACKs without rate limit 185 4. Detect acceptable ack numbers 186 - send multiple probing ACKs and observe IPID counter 187 - forged probing ACK packets have seq num seq_acceptable, ack num is set to <ack_challenge-i> 188 - challenge ACKS triggered until <ack_challenge-i> reaches lower bound of challenge ACK window 189 - acceptable ack range inferred by adding 2*2³⁰ to detected boundary