Simple Active Attack Against TCP Laurent Joncheray Merit Network, Inc. 4251 Plymouth Road, Suite C Ann Arbor, MI 48105, USA Phone: +1 (313) 936 2065 Fax: +1 (313) 747 3185 E-mail: lpj@merit.edu Abstract This paper describes an active attack against the Transport Control Protocol (TCP) which allows a cracker to redirect the TCP stream through his machine thereby permitting him to bypass the protection offered by such a system as a one-time password [skey] or ticketing authentication [kerberos]. The TCP connection is vulnerable to anyone with a TCP packet sniffer and generator located on the path followed by the connection. Some schemes to detect this attack are presented as well as some methods of prevention and some interesting details of the TCP protocol behaviors. 1. Introduction Passive attacks using sniffers are becoming more and more frequent on the Internet. The attacker obtains a user id and password that allows him to logon as that user. In order to prevent such attacks people have been using identification schemes such as one-time password [skey] or ticketing identification [kerberos]. Though they prevent password sniffing on an unsecure network these methods are still vulnerable to an active attack as long as they neither encrypt nor sign the data stream. [Kerberos also provides an encrypted TCP stream option.] Still many people are complacent believing that active attacks are very difficult and hence a lesser risk. The following paper describes an extremely simple active attack which has been successfully used to break into Unix hosts and which can be done with the same resources as for a passive sniffing attack. [The attacks have been performed with a test software and the users were aware of the attack. Although we do not have any knowledge of such an attack being used on the Internet, it may be possible.] Some uncommon behaviors of the TCP protocol are also presented as well as some real examples and statistical studies of the attack's impact on the network. Finally some detection and prevention schemes are explained. In order to help any reader unfamiliar with the subtleties of the TCP protocol the article starts with a short description of TCP. The reader can also refers to another attack by R. Morris presented in [morris85]. Though the following attack is related to Morris' one, it is more widely usable on any TCP connection. In section 7 we present and compare this attack with the present one. The presentation of the attack will be divided into three parts: the ``Established State'' which is the state where the session is open and data is exchanged; the set up (or opening) of such a session; and finally some real examples. 2. Established State 2.1 The TCP protocol This section offers a short description of the TCP protocol. For more details the reader can refer to [rfc793]. TCP provides a full duplex reliable stream connection between two end points. A connection is uniquely defined by the quadruple (IP address of sender, TCP port number of the sender, IP address of the receiver, TCP port number of the receiver). Every byte that is sent by a host is marked with a sequence number (32 bits integer) and is acknowledged by the receiver using this sequence number. The sequence number for the first byte sent is computed during the connection opening. It changes for any new connection based on rules designed to avoid reuse of the same sequence number for two different sessions of a TCP connection. We shall assume in this document that one point of the connection acts as a server (for instance a telnet server) and the other as the client. The following terms will be used: SVR_SEQ: sequence number of the next byte to be sent by the server; SVR_ACK: next byte to be received by the server (the sequence number of the last byte received plus one); SVR_WIND: server's receive window; CLT_SEQ: sequence number of the next byte to be sent by the client; CLT_ACK: next byte to be received by the client; CLT_WIND: client's receive window; At the beginning when no data has been exchanged we have SVR_SEQ = CLT_ACK and CLT_SEQ = SVR_ACK. These equations are also true when the connection is in a 'quiet' state (no data being sent on each side). They are not true during transitory states when data is sent. The more general equations are: CLT_ACK <= SVR_SEQ <= CLT_ACK + CLT_WIND SVR_ACK <= CLT_SEQ <= SVR_ACK + SVR_WIND The TCP packet header fields are: Source Port: The source port number; Destination Port: The destination port number; Sequence number: The sequence number of the first byte in this packet; Acknowledgment Number: The expected sequence number of the next byte to be received; Data Offset: Offset of the data in the packet; Control Bits: URG: Urgent Pointer; ACK: Acknowledgment; PSH: Push Function; RST: Reset the connection; SYN: Synchronize sequence numbers; FIN: No more data from sender; Window: Window size of the sender; Checksum: TCP checksum of the header and data; Urgent Pointer: TCP urgent pointer; Options: TCP options; - SEG_SEQ will refer to the packet sequence number (as seen in the header). - SEG_ACK will refer to the packet acknowledgment number. - SEG_FLAG will refer to the control bits. On a typical packet sent by the client (no retransmission) SEG_SEQ is set to CLT_SEQ, SEG_ACK to CLT_ACK. TCP uses a ``three-way handshake'' to establish a new connection. If we suppose that the client initiates the connection to the server and that no data is exchanged, the normal packet exchange is (C.f. Figure 1): - The connection on the client side is on the CLOSED state. The one on the server side is on the LISTEN state. - The client first sends its initial sequence number and sets the SYN bit: SEG_SEQ = CLT_SEQ_0, SEG_FLAG = SYN Its state is now SYN-SENT - On receipt of this packet the server acknowledges the client sequence number, sends its own initial sequence number and sets the SYN bit: SEG_SEQ = SVR_SEQ_0, SEQ_ACK = CLT_SEQ_0+1, SEG_FLAG = SYN and set SVR_ACK=CLT_SEQ_0+1 Its state is now SYN-RECEIVED - On receipt of this packet the client acknowledges the server sequence number: SEG_SEQ = CLT_SEQ_0+1, SEQ_ACK = SVR_SEQ_0+1 and sets CLT_ACK=SVR_SEQ_0+1 Its state is now ESTABLISHED - On receipt of this packet the server enters the ESTABLISHED state. We now have: CLT_SEQ = CLT_SEQ_0+1 CLT_ACK = SVR_SEQ_0+1 SVR_SEQ = SVR_SEQ_0+1 SVR_ACK = CLT_SEQ_0+1 Server Client LISTEN CLOSED <- SYN, CLT_SEQ_0 LISTEN SYN-SENT SYN, -> SVR_SEQ_0, CLT_SEQ_0+1 SYN-RECEIVED ESTABLISHED SVR_SEQ = CLT_SEQ_0 + 1 CLT_ACK = SVR_SEQ_0 + 1 <- ACK, CLT_SEQ_0 + 1 SVR_SEQ_0+1 ESTABLISHED SVR_SEQ = SVR_SEQ_0 + 1 SVR_ACK = CLT_SEQ_0 + 1 figure 1: Example of a connection opening Closing a connection can be done by using the FIN or the RST flag. If the RST flag of a packet is set the receiving host enters the CLOSED state and frees any resource associated with this instance of the connection. The packet is not acknowledged. Any new incoming packet for that connection will be dropped. If the FIN flag of a packet is set the receiving host enters the CLOSE-WAIT state and starts the process of gracefully closing the connection. The detail of that procces is beyond the scope of this document. The reader can refer to [rfc793] for further details. In the preceding example we specifically avoided any unusual cases such as out-of-band packets, retransmission, loss of packet, concurrent opening, etc... These can be ignored in this simple study of the attack. When in ESTABLISHED state, a packet is acceptable if its sequence number falls within the expected segment [SVR_ACK, SVR_ACK + SVR_WIND] (for the server) or [CLT_ACK, CLT_ACK + CLT_WIND] (for the client). If the sequence number is beyond those limits the packet is dropped and a acknowledged packet will be sent using the expected sequence number. For example if SEG_SEQ = 200, SVR_ACK = 100, SVR_WIND = 50 Then SEG_SEQ > SVR_ACK + SVR_WIND. The server forms a ACK packet with SEG_SEQ = SVR_SEQ SEG_ACK = SVR_ACK which is what the server expects to see in the packet. 2.2 A desynchronized state The term ``desynchronized state'' will refer to the connection when both sides are in the ESTABLISHED state, no data is being sent (stable state), and SVR_SEQ != CLT_ACK CLT_SEQ != SVR_ACK This state is stable as long as no data is sent. If some data is sent two cases can occur: - If CLT_...
Iskraa