TCP BUG IN FREEBSD

A recent vulnerability found in the FreeBSD TCP/IP stack caught my eye due to its relative simplicity (both in exploiting it and avoiding it). It references CVE-2004-0230 (yep, 2004) with a slight twist: instead of using RST packets, it uses SYN packets for the same end-result: a connection reset.

Let's say you have an established TCP connection between client A and server B. Once the 3-way handshake is done and data is flowing, we know the following:

  • source port is a random high port allocated at creation, let's say A:50000
  • destination port is B:80
  • state is Established
  • a sequence number (something like 3518508601) has been agreed for each direction
  • other parameters are not relevant

Let's say that the webserver B is running the vulnerable TCP/IP stack. What can happen is that an attacker could cause the connection between A and B to reset by sending a TCP SYN to B that uses the exact same ports (from A:50000 to B:80). Ouch.

Obviously, this involves a wee bit of IP spoofing, but that never stopped anybody. Normally, a check in the TCP/IP implementation would frown at receiving a SYN on an ESTABLISHED connection with a bogus sequence number.

To quote the FreeBSD advisory:

When a segment with the SYN flag for an already existing connection arrives, the TCP stack tears down the connection, bypassing a check that the sequence number in the segment is in the expected window.

The impact here is that an attacker could remotely reset a TCP connection if he knew the source and destination ports (the bug ignores sequence numbers, which are usually randomized to make them hard to guess). In the case of a public web-server, the destination port is easy to find. The harder part is finding out what the source port (could be anything in the high range >1024), but a determined attacker could simply send a SYN packet with every possible source port combination.

Apart from the obvious solution (patch the bug in your TCP stack), most stateful firewalls should detect and block SYN packets sent on established connections.

Of course, a firewall can also think the connection is still active, while it has timed-out on the endpoints, thus preventing those hosts from re-establishing it, but that's a (real and very painful) story for another time.

And, as always, thanks for reading.


comments powered by Disqus