Full article

Linux Issue with TCP ACK (Part 1)

A flaw in the Linux kernel[1] used since late 2012 allows adversaries to inject malicious traffic, without MITM. In a Wednesday presentation at the USENIX Security Symposium researchers showed that this flaw lies in the Transmission Control Protocol (TCP) used by Linux since late 2012. In their research paper - Off-Path TCP Exploits: Global Rate Limit Considered Dangerous, the researchers document possible use cases, and attack scenarios on how this global limit be exploited to perform connection drop and/or injection attacks.

With so much buzz in the world, I will attempt to cover some network 101201 basics on SYN, ACK and their associated numbers in this 3 part series, and try to tell you what-this-fuzz all about. So, if you are network-guru, this article is not for you.

Understanding TCP Flags

TCP or Transmission Control Protocol is a stream based protocol, which means in-order to identify the packet sequence it has to have a way to generate some index numbers. In the world of millions of packets between a client server interaction, it is achieved by SEQ and ACK numbers. The examples below are using command line (tshark or tcpdump), but the same can be attempted with tools like Wireshark and display filters[2]. Take a look on the layers,

TCP is below the application layer, and therefore any issue with it will inherently affect Application Layer protocols - HTTP/ TLS.

Okay, now to initiate a successful connection, there should be a 3 way handshake between client A and server B. It means that client socket (src.IP:srcport) should ask server socket (dst.IP:dstport) to acknowledge it's request. The other important field in this communication is tcp.len which is the length of TCP segment.

  • A →syn→ B
  • B →syn-ack→ A
  • A →ack→ B

Total Bytes on Wire = ETH Header + IP Header (ip.hdr_len) + TCP Header (tcp.hdr_len) + TCP Segment (tcp.len)

In a normal TCP conversation, seq(n)=random or seq(n)=ack(n-1) AND ack(n)=seq(n-1)+1 or ack(n)=seq(n-1)+tcp.len. By default, wireshark/ tshark or tcpdump show relative seq/ack numbers for easier tracking and UI, but to see the absolute long seq/ack numbers, we have to specifically use the following command lines,

  • tshark -o tcp.relative_sequence_numbers:FALSE
  • tcpdump -S (-S switch enables absolute numbers)
  • Wireshark GUI > Preferences > Protocols > TCP > Un-check "relative sequence numbers" box.
  • View default wireshark/tshark configurations: tshark -G currentpref

Lets capture a normal traffic with cybersins.com using tshark,

$ telnet cybersins.com 80
$ sudo tshark -o tcp.relative_sequence_numbers:FALSE -i 7 -T fields -e ip.src -e ip.dst -e tcp.seq -e tcp.ack -e tcp.len

By nslookup the IP for cybersins.com are: or therefore host filter is restricted to these IPs only. Now, do the math and see how seq/ack numbers are behaving in the image.

Hopefully this was a quick overview on how the syn/ack packets behave & numbers computed/ tracked. Watch-out for part 2 to understand Challenge ACK & need for RFC 5961.

Cheers & be kind.

  1. The flaw is equally shared with RFC 5961 and it's implementation in Linux. ↩︎

  2. A guide on Wireshark Filters ↩︎