---[ Phrack Magazine Volume 8, Issue 53 July 8, 1998, article 06 of 15 -------------------------[ T/TCP vulnerabilities --------[ route|daemon9----[ Introduction and Impetus T/TCP is TCP for Transactions. It is a backward compatible extension for TCP to facilitate faster and more efficient client/server transactions. T/TCP is not in wide deployment but it is in use (see appendix A) and it is supported by a handful of OS kernels including: FreeBSD, BSDi, Linux, and SunOS. This article will document the T/TCP protocol in light detail, and then cover some weaknesses and vulnerabilities. ----[ Background and primer TCP is a protocol designed for reliability at the expense of expediency (readers unfamiliar with the TCP protocol are directed to the ancient-but- still-relevant: http://www.infonexus.com/~daemon9/Misc/TCPIP-primer.txt). Whenever an application is deemed to require reliability, it is usually built on top of TCP. This lack of speed is considered a necessary evil. Short lived client/server interactions desiring more speed (short in terms of time vs. amount of data flow) are typically built on top of UDP to preserve quick response times. One exception to this rule, of course, is http. The architects of http decided to use the reliable TCP transport for ephemeral connections (indeed a poorly designed protocol). T/TCP is a small set of extensions to make a faster, more efficient TCP. It is designed to be a completely backward compatible set of extensions to speed up TCP connections. T/TCP achieves its speed increase from two major enhancements over TCP: TAO and TIME_WAIT state truncation. TAO is TCP Accelerated Open, which introduces new extended options to bypass the 3-way handshake entirely. Using TAO, a given T/TCP connection can approximate a UDP connection in terms of speed, while still maintaining the reliability of a TCP connection. In most single data packet exchanges (such is the case with transactional-oriented connections like http) the packet count is reduced by a third. The second speed up is TIME_WAIT state truncation. TIME_WAIT state truncation allows a T/TCP client to shorten the TIME_WAIT state by up to a factor of 20. This can allow a client to make more efficient use of network socket primitives and system memory. ----[ T/TCP TAO TCP accelerated open is how T/TCP bypasses the 3-way handshake. Before we discuss TAO, we need to understand why TCP employs a 3-way handshake. According to RFC 793, the principal reason for the exchange is the prevention of old duplicate connection initiations wandering into current connections and causing confusion. With this in mind, in order to obviate the need for the 3-way handshake, there needs to be a mechanism for the receiver of a SYN to guarantee that that SYN is in fact new. This is accomplished with a new extended TCP header option, the connection count (CC). The CC (referred as tcp_ccgen when on a host) is a simple monotonic variable that a T/TCP host keeps and increments for every TCP connection created on that host. Anytime a client host supporting T/TCP wishes to make a T/TCP connection to a server, it includes (in it's TAO packet) a CC (or CCnew) header option. If the server supports T/TCP, it will cache that client's included CC value and respond with a CCecho option (CC values are cached by T/TCP hosts on a per host basis). If the TAO test succeeds, the 3-way handshake is bypassed, otherwise the hosts fall back to the older process. The first time a client host supporting T/TCP and a server host supporting T/TCP make a connection no CC state exists for that client on that server. Because of this fact, the 3-way handshake must be done. However, also at that time, the per host CC cache for that client host is initialized, and all subsequent connections can use TAO. The TAO test on the server simply checks to make sure the client's CC is greater then the last received CC from that client. Consider figure 1 below: Client Server T ----------------------------------------------------------------------- i 0 --TAO+data--(CC = 2)--> ClientCC = 1 m 1 2 > 1; TAO test succeeds e 2 accept data ---> (to application) [ fig 1 ] Initially (0) the client sends a TAO encapsulated SYN to the server, with a CC of 2. Since the CC value on the server for this client is 1 (indicating they have had previous T/TCP-based communication) the TAO test succeeds (1). Since the TAO test was successful, the server can pass the data to application layer immediately (2). If the client's CC had not been greater than the server's cached value, the TAO test would have failed and forced the 3-way handshake. ----[ T/TCP TIME_WAIT truncation Before we can see why it is ok to shorten the TIME_WAIT state, we need to cover exactly what it is and why it exists. Normally, when a client performs an active close on a TCP connection, it must hold onto state information for twice the maximum segment lifetime (2MSL) which is usually between 60 - 240 seconds (during this time, the socket pair that describes the connection cannot be reused). It is thought that any packet from this connection would be expired (due to IP TTL constraints) from the network. TCP must be consistent with its behavior across all contingencies and the TIME_WAIT state guarantees this consistency during the last phase of connection closedown. It keeps old network segments from wandering into a connection and causing problems and it helps implement the 4-way closedown procedure. For example, if a wandering packet happens to be a retransmission of the servers FIN (presumably due to the clients ACK being lost), the client must be sure to retransmit the final ACK, rather then a RST (which it would do if it had torn down all the state). T/TCP allows for the truncation of the TIME_WAIT state. If a T/TCP connection only lasts for MSL seconds or less (which is usually the case with transactional-oriented connections) the TIME_WAIT state is truncated to as little as 12 seconds (8 times the retranmission timeout - RTO). This is allowable from a protocol standpoint because of two things: CC number protection against old duplicates and the fact that the 4-way closedown procedure packet loss scenario (see above) can be handled by waiting for the RTO (multiplied by a constant) as opposed to waiting for a whole 2MSL. As long as the connection didn't last any longer then MSL, the CC number in the next connection will prevent old packets with an older CC number from being accepted. This will protect connections from old wandering packets (if the connection did last longer, it is possible for the CC values to wrap and potentially be erroneously delivered to a new incarnation of a connection). ----[ Dominance of TAO It is easy for an attacker to ensure the success or failure of the TAO test. There are two methods. The first relies on the second oldest hacking tool in the book. The second is more of a brutish technique, but is just as effective. --[ Packet sniffing If we are on the local network with one of the hosts, we can snoop the current CC value in use for a particular connection. Since the tcp_ccgen is incremented monotonically we can precisely spoof the next expected value by incrementing the snooped number. Not only will this ensure the success of our TAO test, but it will ensure the failure of the next TAO test for the client we are spoofing. --[ The numbers game The other method of TAO dominance is a bit rougher, but works almost as well. The CC is an unsigned 32-bit number (ranging in value from 0 - 4,294,967,295). Under all observed implementations, the tcp_ccgen is initialized to 1. If an attacker needs to ensure the success of a TAO connection, but is not in a position where s/he can sniff on a local network, they should simply choose a large value for the spoofed CC. The chances that one given T/TCP host will burn through even half the tcp_ccgen space with another given host is highly unlikely. Simple statistics tells us that the larger the chosen tcp_ccgen is, the greater the odds that the TAO test will succeed. When in doubt, aim high. ----[ T/TCP and SYN flooding TCP SYN flooding hasn't changed much under TCP for Transactions. The actual attack is the same; a series of TCP SYNs spoofed from unreachable IP addresses. However, there are 2 major considerations to keep in mind when the target host supports T/TCP: 1) SYN cookie invalidation: A host supporting T/TCP cannot, at the same time, implement SYN cookies. TCP SYN cookies are a SYN flood defense technique that works by sending a secure cookie as the sequence number in the second packet of the 3-way handshake, then discarding all state for that connection. Any TCP options sent would be lost. If the final ACK comes in, only then will the host create the kernel socket data structures. TAO obviously cannot be used with SYN cookies. 2) Failed TAO processing result in queued data: If the TAO test fails, any data included with that packet will be queued pending the completion of the connection processing (the 3-way handshake). During a SYN flood, this can make the attack more severe as memory buffers fill up holding this data. In this case, the attacker would want to ensure the failure of the TAO test for each spoofed packet. In a previous Phrack Magazine article, the author erroneously reported that T/TCP would help to alleviate SYN flood vulnerability. This obviously incorrect statement was made before copious T/TCP research was done and is hereby rescinded. My bad. ----[ T/TCP and trust relationships An old attack with a new twist. The attack paradigm is still the same, (readers unfamiliar with trust relationship exploitation are directed to P48-14) this time, however, it is easier to wage. Under T/TCP, there is no need to attempt to predict TCP sequence numbers. Previously, this attack required the attacker to predict the return sequence number in order to complete the connection establishment processing and move the connection into the established state. With T/TCP, a packet's data will be accepted by the application as soon as the TAO test succeeds. All the attacker needs to do is ensure that the TAO test will succeed. Consider the figure below. Attacker Server Trusted ----------------------------------------------------------------------- 0 -spoofed-TAO-> 1 TAO test succeeds T 2 data to application i 3 ---TAO-response-> m 4 no open socket e 5 <------RST------- 6 tears down connection [ fig 2 ] The attacker first sends a spoofed connection request TAO packet to the server. The data portion of this packet presumably contains the tried and true non-interactive backdooring command `echo + + > .rhosts`. At (1) the TAO test succeeds and the data is accepted (2) and passed to application (where it is processed). The server then sends its T/TCP response to the trusted host (3). The trusted host, of course, has no open socket (4) for this connection, and responds with the expected RST segment (5). This RST will teardown the attacker's spoofed connection (6) on the server. If everything went according to plan, and the process executing the command in question didn't take too long to run, the attacker may now log directly into the server. To deal with (5) the attacker can, of course, wage some sort of denial of service attack on the trusted host to keep it from responding to the unwarranted connection. ----[ T/TCP and duplicate message delivery Ignoring all the other weaknesses of the protocol, there is one major flaw that causes the T/TCP to degrade and behave decidedly NONTCP-like, therefore breaking the protocol entirely. The problem is within the TAO mechanism. Certain conditions can cause T/TCP to deliver duplicate data to the application layer. Consider the timeline in figure 3 below: Client Server ----------------------------------------------------------------------- 0 --TAO-(data)---> 1 TAO test succeeds T 2 accept data ---> (to application) i 3 *crash* (reboot) m 4 timeout (resends) --TAO-(data)---> e 5 TAO test fails (data is queued) 6 established <-SYN-ACK(SYN)-- fallback to 3WHS 7 --ACK(SYN)-----> established (data --> application) [ fig 3 ] At time 0 the client sends its TAO encapsulated data to the server (for this example, consider that both hosts have had recent communication, and the server has defined CC values for the client). The TAO test succeeds (1) and the server passes the data to the application layer for processing (2). Before the server can send its response however (presumably an ACK) it crashes (3). The client receives no acknowledgement from the server, so it times out and resends its packet (4). After the server reboots it receives this retransmission, this time, however, the TAO test fails and the server queues the data (5). The TAO test failed and forced a 3-way handshake (6) because the servers CC cache was invalidated when it rebooted. After completing the 3-way handshake and establishing a connection, the server then passes the queued data to the application layer, for a second time. The server cannot tell that it has already accepted this data because it maintains no state after a reboot. This violates the basic premise of T/TCP that it must remain completely backward compatible with TCP. ----[ In closing T/TCP is a good idea that just wasn't implemented properly. TCP was not designed to support a connectionless-like paradigm while still maintaining reliability and security (TCP wasn't even designed with security in mind at all). T/TCP brings out too many problems and discrete bugs in TCP to be anything more then a novelty. ----[ Appendix A: Internet hosts supporting RFC 1644 This information is ganked from Richard Steven's T/TCP homepage (http://www.kohala.com/~rstevens/ttcp.html). It is not verfied to be correct. - www.ansp.br - www.elite.net - www.iqm.unicamp.br - www.neosoft.com - www.sbq.org.br - www.uidaho.edu - www.yahoo.com ----[ Appendix B: Bibliography 1) Braden, R. T. 1994 "T/TCP - TCP Extensions for Transactions...", 38 p 2) Braden, R. T. 1992 "Extending TCP for Transactions - Concepts...", 38 p 3) Stevens, W. Richard. 1996 "TCP Illustrated volume III", 328 p 4) Smith, Mark. 1996, "Formal verification of Communication...", 15 p ----[ EOF