Anatomy of a SYN-ACK Attack
In recent weeks, a series of DDoS attacks were directed at multiple financial institutions. The attacks utilized a seldom seen reflection vector known as TCP SYN-ACK reflection. SYN-ACK reflection isn't new, but it's rarely observed due mostly to its lack of popularity among attackers and impact on the victim. The observed attacks sparked conversations both publicly and privately amongst several organizations, including Akamai. In this write-up, we're going to discuss this attack type, dig into TCP a bit, and cover some observations and associated concerns.
Transmission Control Protocol/Internet Protocol (TCP/IP) is a linchpin technology for modern computer networking. It is how (a large majority of the time) your computer often requests and receives information across a network and the Internet. It comes complete with error checking, retransmission of missing/corrupt data, and several other important features that quite literally make the Internet as we know it reliable and functional. However, to understand how it is being abused, we must first understand how it functions.
For the sake of brevity, we won't go into the full TCP/IP connection process. We will only focus on the initial TCP three-way handshake process as that is all that is relevant to the subject of this write-up.
Hosts on a network that want to exchange data using TCP must first negotiate a connection. This is where the TCP three-way handshake comes into play. The handshake process allows both hosts to acknowledge successful sending and receiving of network communications, as well as set up their respective session in anticipation of the exchange of application data.
In Figure 1, we see a Client establishing a TCP connection to a Server. The first step is for the Client to send a Synchronization or SYN packet. This packet has two primary roles, the first is to test the ability to reach the remote resource. If this packet is successfully routed, it also tells the Server that a remote Client wants to begin the connection negotiation process for data exchange. The Server responds by issuing a Synchronization and Acknowledgment, or SYN-ACK, packet directed back at the Client that is initiating the connection. The final part of the three-way handshake is for the client to respond to the SYN-ACK with a final Acknowledgement, or ACK packet. Once this handshake is complete, the connection is ready to be used by the application for the bi-directional transmission of data.Fig. 1) TCP three-way handshake
The most common method for transporting TCP communications is over Internet Protocol or IP. This means that the TCP packets are communicated between the client and server using IP datagrams, addressed using IP addresses for each of the devices.
Attackers weaponize this handshake process by spoofing the SYN packets' source IP addresses. This spoofing causes the Server to send the SYN-ACK packet to the victim IP, which the server believes requested the session initialization, acting as a reflector.
Fig. 2) SYN-ACK reflection |
In Figure 2, you can see a very simple visualization of this attack. However, this doesn't show what a real attack scenario looks like. The reality is that TCP was designed to operate on unreliable networks, meaning that a single spoofed SYN can trigger a server to send multiple SYN-ACKs in rapid succession if it does not receive the final ACK of the handshake. The number of SYN-ACKs to send and how quickly to send them is a configurable metric, so it's hard to estimate exactly how many SYN-ACKs a targeted victim may receive in relation to the volume of spoofed SYN packets that were sent by the attackers.
SYN-ACK attacks aren't your typical reflection attacks. One of the primary attractions of UDP-based reflection attacks is their amplification factor, or the size of the packet that arrives at the victim versus the size of the packet that an attacker must send. In many cases, the amplification factor is many times that of the original request. In the case of CLDAP reflection, for instance, the resulting packet is around 50-70x larger than the packet the attacker must send to trigger the reflection. Amplification attacks are often considered volumetric, typically with the goal of saturating the network links used by the targeted servers and applications.
In the case of SYN-ACK reflections, the size of the packet delivered to the victim is nearly the same size as the packet sent by the attacker. We say "nearly the same size" because it is possible, and very likely, that while the attacker sends a minimum length SYN packet some routers on the network between the attacker and the victim may also modify the TCP packet to add additional link information, like the Maximum Segment Size (MSS) TCP option, increasing the absolute size of the traffic observed by the victim. This option accounts for an additional 4 bytes per packet when compared to what the attacker sent.
20:56:32.296905 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 40)
x.x.x.x.34567 > y.y.y.y.443: Flags [SPU], cksum 0xfa7c (correct), seq 1000, win 8192, urg 0, length 0
20:56:32.315637 IP (tos 0x0, ttl 124, id 4894, offset 0, flags [none], proto TCP (6), length 44)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0x6e18 (correct), seq 3609252029, ack 1001, win 60720,
options [mss 1380], length 0
Fig. 3) SYN-ACK 4 byte amplification
This doesn't mean that this attack isn't a threat. During several coordinated attacks against Akamai customers, multiple instances of high packet per second (PPS) floods using reflected SYN-ACK traffic were observed. While low bandwidth traffic is less likely to saturate links, the high PPS can cause problems for networking gear attempting to process and route the deluge of SYN-ACKS rushing across networks.
SYN-ACK attackers are reliant on the TCP configurations of their reflectors and how they handle their TCP connections. This means that attackers are limited in what they can reflect to the victim. Researchers at Akamai spent time testing against several TCP enabled services exposed on machines across the Internet to see what combination of TCP flags & options might result in the most impactful attack scenarios. We'll cover some attack scenarios, how they differ, and how attackers may leverage SYN-ACK attacks in the future.
TCP Options and padded SYN-ACKS
Attackers cannot control the contents of a SYN-ACK packet. While we've seen padded SYN floods for years, the idea of a padded SYN-ACK isn't something we expect. In the real-world, when SYN-ACK attacks were launched, packets that arrived at the victims' networks had a predictable length of 44 bytes. As previously discussed, this informs us that the attackers were most likely pushing out optionless SYN packets of 40 bytes, with the MSS options most likely being set by on path networking gear in transit. This results in a small amplification factor, but we wanted to test how large we could get SYN-ACKs from real servers.
Testing was conducted using different variations of TCP options. The goal of testing was to be able to identify the options that could reliably be used and result in a larger SYN-ACK response from randomly chosen servers around the Internet. The options that could be used by an attacker resulting in larger SYN-ACKs are Maximum Segment Size (MSS), Timestamp (TS) , Selective ACK (SAckOK), Window Scale (WScale), & TCP Fast Open (TFO) cookies.
Simply by using valid options, an attacker could consume roughly 62% more bandwidth than with a minimal SYN packet (72 bytes vs. 44 bytes). Utilizing these options, headers diminish the amplification ratio (10% amplification becomes 6-7%); however, it is still possible to achieve amplification by simply omitting the MSS option, as it will be set in transit regardless of the attacker sending it or not.
20:51:46.333671 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 68)
x.x.x.x.34567 > y.y.y.y.443: Flags [SPU], cksum 0x1212 (correct), seq 1000, win 8192, urg 0, options
[tfo cookie 1d2a458f00f1e38a,TS val 0 ecr 0,sackOK,wscale 0,eol], length 0
20:51:46.351665 IP (tos 0x0, ttl 124, id 51260, offset 0, flags [none], proto TCP (6), length 72)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0x1f6c (correct), seq 3436032873, ack 1001, win
60192, options [mss 1380,sackOK,TS val 1541046001 ecr 0,nop,wscale 8,tfo cookie 6d84c401c27d0655,nop,nop], length 0
Fig. 4) SYN-ACK padding with TFO
During testing, it was possible to leverage the TS, SAckOK, WSCale, & TFO TCP options (and NOP padding) to issue a 68 byte SYN packet that resulted in a 72 byte SYN-ACK response that was delivered to the victim, as seen in figure 4. If a host doesn't support TFO, an attacker can still push a 56 byte SYN packet which results in a 60 byte SYN-ACK being routed to the victim network as seen below in figure 5.
21:12:24.647377 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 56)
x.x.x.x.34567 > y.y.y.y.443: Flags [SPU], cksum 0xab5d (correct), seq 1000, win 8192, urg 0, options
[TS val 0 ecr 0,sackOK,wscale 0,eol], length 0
21:12:24.665340 IP (tos 0x0, ttl 124, id 46598, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0xfec2 (correct), seq 1309850370, ack 1001, win 60192,
options [mss 1380,sackOK,TS val 1542284314 ecr 0,nop,wscale 8], length 0
Fig. 5) SYN-ACK padding minus TFO
SYN-ACK Amplification
A tiny amount of amplification is possible using SYN-ACK attacks, but it's possible to increase this amplification factor by targeting IP space that is allocated but unoccupied (meaning the IP is routable but no machine is currently deployed and/or handling network traffic). This scenario allows attackers to fully leverage TCP retransmission efforts, which in turn increases amplification factors and bandwidth consumption.
When a normal machine receives an out-of-state SYN-ACK from a reflector, it will respond with a RST packet as shown below in Figure 6. This RST packet will be received by the reflector, and the TCP session on the reflector will be killed.
21:33:15.173204 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 40)
x.x.x.x.34568 > y.y.y.y.443: Flags [SPU], cksum 0xfa7b (correct), seq 1000, win 8192, urg 0, length 0
21:33:15.191517 IP (tos 0x0, ttl 124, id 46635, offset 0, flags [none], proto TCP (6), length 44)
y.y.y.y.443 > x.x.x.x.34568: Flags [S.], cksum 0xb751 (correct), seq 1209013908, ack 1001, win
60720, options [mss 1380], length 0
21:33:15.191558 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
x.x.x.x.34568 > y.y.y.y.443: Flags [R], cksum 0x1aa1 (correct), seq 1001, win 0, length 0
Fig. 6) out of state SYN-ACK triggers a RST response
If this SYN-ACK packet is destined for an IP address that is allocated but unoccupied, the SYN-ACK will be routed (impacting the networking gear along the way) but never reach a real machine that would issue a RST. This lack of RST packet will cause the reflector to assume failed delivery of the SYN-ACK and begin retransmission attempts.
In testing, the number of retransmission attempts is typically between 5 and 7 SYN-ACK packets sent to the victim for each SYN sent. If we assume an attacker sends a 40 byte SYN, we can expect 5-7 44 byte SYN-ACKs to traverse the victims network. In a worst case scenario of 7 packets received, this results in a 40 byte request generating 308 bytes of packets arriving at the victim's borders, an amplification factor of 770%. Using TCP options headers to generate larger SYN-ACKs, an attacker could push those numbers to 56 bytes, resulting in 420 bytes of reflected traffic, an amplification factor of 750%.
21:12:24.647377 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 56)
x.x.x.x.34567 > y.y.y.y.443: Flags [SPU], cksum 0xab5d (correct), seq 1000, win 8192, urg 0, options [TS val 0 ecr 0,sackOK,wscale 0,eol], length 0
21:12:24.665340 IP (tos 0x0, ttl 124, id 46598, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0xfec2 (correct), seq 1309850370, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1542284314 ecr 0,nop,wscale 8], length 0
21:12:24.965713 IP (tos 0x0, ttl 124, id 46784, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0xfd96 (correct), seq 1309850370, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1542284614 ecr 0,nop,wscale 8], length 0
21:12:26.965689 IP (tos 0x0, ttl 124, id 47738, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0xf5c6 (correct), seq 1309850370, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1542286614 ecr 0,nop,wscale 8], length 0
21:12:30.965750 IP (tos 0x0, ttl 124, id 49898, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0xe626 (correct), seq 1309850370, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1542290614 ecr 0,nop,wscale 8], length 0
21:12:38.965701 IP (tos 0x0, ttl 124, id 53757, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0xc6e6 (correct), seq 1309850370, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1542298614 ecr 0,nop,wscale 8], length 0
21:12:54.965710 IP (tos 0x0, ttl 124, id 61887, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0x8866 (correct), seq 1309850370, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1542314614 ecr 0,nop,wscale 8], length 0
Fig. 7) SYN results in 6 SYN-ACKS
TFO, padding, and amplification
TCP Fast Open (TFO) is being discussed in more detail here to cover some interesting edge cases observed in testing. Using TFO cookies, it is possible to trigger larger responses (an additional 12 bytes per SYN-ACK); however, due to oversights in the TFO implementation, these measures can alter amplification factors and, under different scenarios, the TFO enabled attacks may be more desirable.
Attackers attempting to leverage TFO enabled reflectors may only find doing so fruitful in certain circumstances. These circumstances would be cases where there is no IP space that isn't being handled by a live machine, if an attacker must direct reflected SYN-ACK packets at real machines that will respond with RST packets, TCP retransmission amplification is essentially moot as the reflector will stop sending SYN-ACKs upon receiving the RST response from the victim's machines.
To make this proposition even less desirable, TFO enabled hosts will not include the 12 byte header option for the TFO cookie in additional SYN-ACK packets beyond the first packet issued. What this means in short is that amplification in this scenario isn't a series of 72 byte packets hitting the victim. In real world testing, it was observed that the first SYN-ACK will be 72 bytes, but the following 5-6 retransmission attempts will omit this TCP option and result in a 60 byte packet. In this case, a 72 byte packet results in a 432 byte reflection; essentially, the only benefit is the 12 additional bytes of the very first packet versus a reflection minus the TFO cookie option.
20:51:46.333671 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 68)
x.x.x.x.34567 > y.y.y.y.443: Flags [SPU], cksum 0x1212 (correct), seq 1000, win 8192, urg 0, options [tfo cookie 1d2a458f00f1e38a,TS val 0 ecr 0,sackOK,wscale 0,eol], length 0
20:51:46.351665 IP (tos 0x0, ttl 124, id 51260, offset 0, flags [none], proto TCP (6), length 72)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0x1f6c (correct), seq 3436032873, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1541046001 ecr 0,nop,wscale 8,tfo cookie 6d84c401c27d0655,nop,nop], length 0
20:51:46.651887 IP (tos 0x0, ttl 124, id 51447, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0x6bb0 (correct), seq 3436032873, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1541046301 ecr 0,nop,wscale 8], length 0
20:51:48.651862 IP (tos 0x0, ttl 124, id 52323, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0x63e0 (correct), seq 3436032873, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1541048301 ecr 0,nop,wscale 8], length 0
20:51:52.651854 IP (tos 0x0, ttl 124, id 54181, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0x5440 (correct), seq 3436032873, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1541052301 ecr 0,nop,wscale 8], length 0
20:52:00.651876 IP (tos 0x0, ttl 124, id 58527, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0x3500 (correct), seq 3436032873, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1541060301 ecr 0,nop,wscale 8], length 0
20:52:16.651862 IP (tos 0x0, ttl 124, id 2147, offset 0, flags [none], proto TCP (6), length 60)
y.y.y.y.443 > x.x.x.x.34567: Flags [S.], cksum 0xf67f (correct), seq 3436032873, ack 1001, win 60192, options [mss 1380,sackOK,TS val 1541076301 ecr 0,nop,wscale 8], length 0
Fig. 8) TFO cookie omission after first response
TFO-enabled hosts reset their handshake cookie measures upon receiving a RST from the victim machine(s) being targeted. What this means is that an attacker targeting real machines using TFO enabled reflectors could reliably cause a series of 72 byte SYN-ACK packets to arrive at the victims end-points.
The amplification factor is only 4 bytes, assuming a 68 byte request from the attacker results in a 72 byte SYN-ACK arriving at the victim followed by a RST packet from the victim to the reflector. If this happens continuously, then the TCP sessions being initiated on the reflector via the attacker will always result in a SYN-ACK packet that includes the additional bytes that are the TFO cookie option.
20:54:41.611605 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 68)
x.x.x.x.34568 > y.y.y.y.443: Flags [SPU], cksum 0x8762 (correct), seq 1000, win 8192, urg 0, options [tfo cookie 0d41245e04e69b5e,TS val 0 ecr 0,sackOK,wscale 0,eol], length 0
20:54:41.629518 IP (tos 0x0, ttl 124, id 14354, offset 0, flags [none], proto TCP (6), length 72)
y.y.y.y.443 > x.x.x.x.34568: Flags [S.], cksum 0x6ade (correct), seq 3714341928, ack 1001, win 60192, options [mss 1380,sackOK,TS val 2388608931 ecr 0,nop,wscale 8,tfo cookie 6d84c401c27d0655,nop,nop], length 0
20:54:41.629548 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
x.x.x.x.34568 > y.y.y.y.443: Flags [R], cksum 0x1aa1 (correct), seq 1001, win 0, length 0
20:54:42.664171 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 68)
x.x.x.x.34568 > y.y.y.y.443: Flags [SPU], cksum 0xc1bd (correct), seq 1000, win 8192, urg 0, options [tfo cookie 021ec8480148cbd9,TS val 0 ecr 0,sackOK,wscale 0,eol], length 0
20:54:42.682391 IP (tos 0x0, ttl 124, id 15171, offset 0, flags [none], proto TCP (6), length 72)
y.y.y.y.443 > x.x.x.x.34568: Flags [S.], cksum 0x6d0a (correct), seq 3730789605, ack 1001, win 60192, options [mss 1380,sackOK,TS val 2388609983 ecr 0,nop,wscale 8,tfo cookie 6d84c401c27d0655,nop,nop], length 0
20:54:42.682440 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
x.x.x.x.34568 > y.y.y.y.443: Flags [R], cksum 0x1aa1 (correct), seq 1001, win 0, length 0
20:54:43.781512 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto TCP (6), length 68)
x.x.x.x.34568 > y.y.y.y.443: Flags [SPU], cksum 0x7dde (correct), seq 1000, win 8192, urg 0, options [tfo cookie 18a4102f05a3acf1,TS val 0 ecr 0,sackOK,wscale 0,eol], length 0
20:54:43.800464 IP (tos 0x0, ttl 124, id 15726, offset 0, flags [none], proto TCP (6), length 72)
y.y.y.y.443 > x.x.x.x.34568: Flags [S.], cksum 0xf5fe (correct), seq 3748251272, ack 1001, win 60192, options [mss 1380,sackOK,TS val 2388611101 ecr 0,nop,wscale 8,tfo cookie 6d84c401c27d0655,nop,nop], length 0
20:54:43.800534 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
x.x.x.x.34568 > y.y.y.y.443: Flags [R], cksum 0x1aa1 (correct), seq 1001, win 0, length 0
Fig. 9) TFO cookie inclusion after RST
Mitigating a SYN-ACK reflection can be tricky and must be done carefully. It is very easy to over mitigate this type of attack and cause self-inflicted damage to real clients and TCP sessions across production networks. These impacted sessions would translate into connectivity issues, degraded performance, and blocking legitimate hosts/users across your networks. These over-mitigation measures may have longer and more impactful effects than the attack itself.
In many cases, over mitigation of TCP impacting attacks can also have unexpected results for the victims. During SYN floods, for example, it is common that as real services begin to have connectivity issues, a secondary attack wave appears to swell up across the network. In such cases, the "second wave" is anything but and is typically a result of real clients/users attempting to establish legitimate connections unsuccessfully; this translates to a swell of higher than normal SYN packets as those impacted clients continue to attempt retransmission of unacknowledge SYN packets.
Over mitigation of a SYN-ACK attack could likely cause issues and similar results, especially if mitigation is happening at a point in the network where real clients are making legitimate outbound requests.
As with most spoofing attacks the real fix isn't something within any single organizations control. To really address this and other problems associated with spoofing capabilities we need to look to the IETF and network operators. IETF has published BCP38, which outlines how network operators can identify and prevent the routing of spoofed traffic. At the end of the day, it is something that network operators must implement and enforce if we really ever hope to see these types of spoofed/reflected attacks disappear, or at least become significantly more difficult to orchestrate.
Reflected SYN-ACK attacks aren't something new; they're actually something as old as TCP itself. Their lack of popularity has more to do with other UDP-based reflected attacks being far more worrisome and impactful and generally a better toolset for attackers. They aren't a side effect of a flawed implementation, they're not an exploit, they're a symptom of IP spoofing across the Internet still being possible nearly 20 years after the proposed solution for network owners and operators was drafted and finalized.
That said, old attacks can still be painful, and reflected SYN-ACKs are no exception. Organizations should consider looking into their mitigation capabilities and options as networking gear may struggle to handle high PPS floods of traffic across borders and networks.
It's important to stress the real possibility of over-mitigation for attacks of this nature and to ensure attempts to fight these types of attacks don't result in self imposed outages... a task that is far easier said than done.