Today we’re looking at a specific type of DoS attack; the SYN flood denial of service attack. Although this type of attack can just as equally be performed as a DDoS attack, the examples we’ll use are for a standard single-source denial of service. A SYN-flood attack works by consuming resources on the targets machine to the point where it cannot accept new legitimate ones.
To fully understand how SYN-floods work, we first need to understand how the TCP three-way handshake works.
- First off when a user, Alice, tries to connect to a networked machine she’ll send a SYN request.
- Assuming the destination machine, Bob, is accepting connections, it’ll respond to Alice’s request with a SYN-ACK packet.
- The final part of the handshake occurs when Alice’s machine confirm Bobs packet by sending a ACK packet back. At this point a full-duplex connection is established.
Those are the three parts of the TCP 3-way handshake. I’ve striped out some other information here, such as incrementing sequence numbers, as they don’t contribute usefully to the SYN flood attack.
How does a SYN flood actually work
For Charlie to initiate a SYN flood attack against Bob, she begins the TCP handshake by sending her SYN request. Bob processes and approves the incoming connection, allocates some server resources to Alice’s session and sends back his SYN-ACK response.
What Charlie should do here is respond with a ACK message, but she doesn’t. She just doesn’t respond at all.
Bobs server sits there waiting for a response, after all packets do get delayed for legit reasons.
Charlie then fires off another SYN request; Bob sees this as another request to connect, assigns some more resources to a 2nd session and sends back his SYN-ACK message.
Charlie repeats this process; sending SYN requests and ignoring the SYN-ACK message. All the time Bob is opening and maintaining more and more half-open connections.
Eventually it’ll get to the point where Bobs finite resources have been consumed; he cannot accept new connections until some of Charlie’s requests have timed out or been responded to. At this point the DoS has been successful; Bobs services are no longer available.
Defending against SYN flood
The most commonly implemented solution to SYN flood attacks is filtering at various levels of the network and OSI-7 model. These detected and effectively stop such floods coming from a single source. The problem with this is its very easy for a malicious user to send spoofed IP data in the SYN flood; meaning the target sends their SYN-ACK messages back to arbitrary IPs, not the actual source. As these unsuspecting recipients of the SYN-ACK message know they never send the SYN packet the SYN-ACK is acknowledging, they drop the packet and don’t respond. Without knowledge of the original source IP, the target of the flood is unable to filter out the true culprit.
Recycling Old Transmission Control Blocks
One of the resources that is consumed on the targets machine is memory assigned to something called Transmission Control Blocks (TCBs). These blocks amognst other things, record the users IP and ports and connection state. A possible way to defend against SYN floods is to simply start re-using old half-open connections that are stored in the TCBs.
Caching SYN Data
Instead of recording a full transmission control block for the half open connection, only actually write a TCB for a successful full-duplex connection. Obviously you still have to write the half-open connections somewhere, which will eventually fill up too, but as these are no longer being stored as a TCB they can be compressed and manipulated.
Decrease the SYN-RECEIVED Timeout
After the destination machine receives a SYN request, it’ll attempt to send a SYN-ACK response, as we see above in the TCP three way handshake. When it successfully sends the SYN-ACK response it changes the connection state locally to SYN-RECEIVED. During a SYN flood this is where the connection will stay, stuck in SYN-RECEIVED, awaiting an ACK message back from the client.
On all systems these SYN-RECEIVED connections will eventually timeout; so why not just decrease how long it takes for them to timeout? They’ll timeout quicker and thus free up resources.
The problem with this is two-fold: it wont take much decreasing before you start dropping legitamte connections. Secondly its trivial for the SYN-flooder attacker to ramp up the number of connections its attempt to open, so even if you drop the SYN-RECEIVED connections twice as often, there’ll be further ones to fill their place.
The information I’ve just explained here is covered in a lot more detail in the SYN-flood ‘Common Defense’ section of the RFC-4987 document “TCP SYN Flooding Attacks and Common Mitigations“. It genuinely is worth a quick read (and I really dont say that often about RFC documents)