How TCP Reset Attack Works

A TCP reset attack is performed using a single data packet of no more than a few bytes in size. The TCP segment replaced by spoofing, created and transmitted by the attacker, tricks the two victims to end the TCP connection, interrupting the connection between them, which could be critical.


This attack had consequences in the real world. Fears of its use were caused by the introduction of changes to the TCP protocol itself. The attack is believed to be an essential component of the Great Chinese Firewall (the Golden Shield), which is used by the Chinese government to censor the Internet outside of China. Despite her impressive background, understanding the mechanisms behind this attack does not necessarily require in-depth knowledge of TCP. Of course, an understanding of its subtleties can teach you a lot about the features of implementing the TCP protocol, and, as we will soon see, you can even carry out this attack against yourself using only one laptop.

In this post we:

  • Learn the basics of TCP
  • Learn how the attack works.
  • Let's conduct an attack against ourselves with a simple Python script.

Before we begin to analyze the mechanics of attack, let's first see how it is used in the real world.

How is TCP reset attack used in the Great Firewall?


Great Firewall (GFW) is a set of systems and techniques used by the Chinese government to censor the Internet for internal Chinese users. GFW actively blocks and breaks connections with servers inside and outside the country, and also passively monitors Internet traffic of prohibited content.

To prevent users from even connecting to banned servers, GFW uses techniques such as DNS pollution and IP blocking(both of them cost separate articles). However, sometimes the GFW firewall needs to be allowed to make a connection, but then break it in the middle. For example, this is necessary if you want to perform a slow, pending analysis of the connection, for example, its correlation with other actions. Or it is used if the firewall needs to analyze the data exchanged during the connection process, and then use this information to decide whether to continue or block it. For example, traffic to a news website may be allowed, but videos containing prohibited keywords will be censored.

For this, GFW needs tools capable of interrupting already established connections. One such tool is a TCP reset attack.

How does a TCP reset attack work?


In a TCP reset attack, the attacker breaks the connection between the two victims, sending one or both fake messages telling them to immediately disconnect. These messages are called TCP reset segments . In normal operation without the participation of an attacker, computers send TCP drop segments when they receive unexpected TCP traffic and want the sender to stop sending it.

The TCP reset attack maliciously exploits this mechanism, tricking victims into ending TCP connections prematurely, sending them fake reset segments. If the false reset segment is made correctly, the recipient will take it for the real segment and close the connection for its part, interrupting further transmission of information on this connection. To continue the data exchange, victims may try to create a new TCP connection, but the attacker may have the opportunity to reset this new connection. Fortunately, since an attacker needs time to build and send a fake packet, dropping attacks are really effective only against long-term connections. Short term connections. for example, used to transfer small web pages, usually have time to fulfill their mission by the timewhen the attacker will be able to reset them.

Sending fake TCP segments is in some sense an easy process, because neither TCP nor IP have any of their own ways of verifying the identity of the sender. There is an IP extension called IPSec that provides authentication, but it is not so widely used. Internet service providers must refuse to transmit IP packets that come from an obviously false IP address, but it is alleged that this check is very mediocre. All that the recipient can do is take the source IP address and port inside the packet or segment at face value and, if possible, use higher-level protocols, such as TLS , to identify the sender . However, since TCP dump packets are part of the TCP protocol itself, they cannot be verified using these high-level protocols.

Despite the simplicity of sending fake segments, making a fake segment and executing a successful TCP reset attack can still be a daunting task. To understand why this happens, we need to understand the operation of the TCP protocol.

How TCP works


The purpose of the TCP protocol is to send the recipient an exact copy of the data block. For example, if my server sends HTML via TCP to your computer, then the TCP stack of your computer (the part of its operating system that processes TCP) should output my HTML in exactly the same form and order in which my server sent it.


However, my HTML is not transmitted over the Internet in such a perfectly ordered manner. It is divided into many small fragments (called TCP segments ), each of which is individually transmitted over the Internet and recreated in the transferred order by the TCP stack of your computer. This restored output is called a TCP stream . Each TCP segment is transmitted in its own IP packet , however, to understand the attack, we do not need to know any details about IP.


Converting segments to a stream requires care because the Internet is unreliable. TCP segments may be lost. They can come out of order, sent twice, get damaged and experience many other misadventures. Therefore, the purpose of the TCP protocol is to ensure reliable data transmission over an unreliable network. TCP performs this task, requiring both sides of the connection to maintain close contact between each other and to constantly transmit information about which data blocks were received. This allows senders to understand what data the recipient has not yet received, and re-transmit the data that was lost.

To understand how the process works, we need to understand how senders and receivers use TCP sequence numbers for marking and tracking data transmitted over TCP.

TCP sequence numbers


Each byte transmitted over a TCP connection has a sequence number assigned to it by the sender. Receiving machines use serial numbers to move the received data into the original order.


When two machines negotiate a TCP connection, each machine sends another random starting sequence number . This is the sequence number that the machine will assign to the first byte it sends. Each subsequent byte is assigned the sequence number of the previous byte plus 1. TCP segments contain TCP headers , which are metadata attached to the beginning of the segment. The sequence number of the first byte in the segment body is included in the TCP header of this segment.

It should be noted that TCP connections are bidirectional, that is, data can be transmitted in both directions, and each machine in a TCP connection acts both as a sender and a receiver. Because of this, each machine must assign and process its own independent set of sequence numbers.

Confirmation of receipt of data


When a machine receives a TCP segment, it tells the sender of the segment that it was received. The recipient does this by sending a segment ACK(short for “acknowledge”), containing the sequence number of the next byte that he expects to receive from the sender. The sender uses this information to understand that the receiver has successfully received all other bytes up to this number.

A segment is ACKindicated by the presence of a flag ACKand the corresponding confirmation number in the TCP header of the segment. There are only 6 flags in the TCP protocol, including (as we will see shortly) a flag RST(short for “reset” - “reset”), indicating the reset segment.


Note: TCP also allows the use of selective ACKs , which are transmitted when the receiver has received some, but not all, segments in the range of numbers. For example, "I received bytes 1000-3000 and 4000-5000, but not 3001-3999." For simplicity, I will not consider selective ACKs in our discussion of TCP reset attacks.

If the sender transmits data but does not receiveACKfor them during a certain time interval, he assumes that the data has been lost and resends it, giving them the same serial numbers. This means that if the receiver accepts the same bytes twice, then it trivially uses sequence numbers to get rid of duplicates without breaking the stream. The recipient can accept duplicate data because the original segment was received later, after it was sent again, or because the original segment was successfully received, but the corresponding one was ACKlost on the way to the sender.


While such duplicate data is rare enough, the excessive waste of resources caused by it does not lead to problems. If all the data sooner or later reaches the recipient, and the corresponding data ACKreach the sender, then the TCP connection does its job.

Choosing a serial number for a fake segment


When creating a false segment, the RSTattacker needs to give him a serial number. The recipients are quite happy that you need to accept segments with inconsistent serial numbers and independently connect them in the right order. However, their capabilities are limited. If the recipient receives a segment with a sequence number that is “too” out of order, then it discards such a segment.

Therefore, for a successful TCP reset attack, a plausible sequence number is required. But what is considered such a number? For most segments (although, as we will see later, not for RST), the answer is determined by the size of the TCP window .

TCP window size


Imagine an ancient computer of the early 1990s, connected to a modern gigabit fiber-optic network. An ultrafast network can transfer data to this elderly computer at an amazing rate, faster than the machine can process it. This will bother us, because the TCP segment cannot be considered received until the receiver can process it.


Computers have a TCP buffer in which new arriving data awaits processing while the computer is working on data arriving before it. However, this buffer has a limited size. If the recipient is unable to cope with the amount of data transmitted to him by the network, then the buffer will overflow. When the buffer is full, the recipient has no choice but to get rid of the redundant data. The recipient does not send ACKfor discarded data, so the sender has to resend them when there is free space in the recipient's buffer. It does not matter how fast the network can transmit data if the recipient does not have time to cope with them.

Imagine an overly zealous friend who sends you a whole stream of letters to your mail faster than you can read it. There is a certain buffer space inside your mailbox, but after it is full all non-placed letters will fall to the ground, where foxes and other creatures will eat them. A friend will have to resend the letters he has eaten, but for now you will have time to receive his previous messages. Sending too many letters or data volume that the recipient is unable to process is a waste of energy and transmission channel.

“Too much” - how much data is it? How does the sender understand when to send more data, and when is it worth the wait? This is where the TCP window size comes in handy.. The size of the recipient's window is the maximum number of unacknowledged bytes that the sender can transfer to him at any time. Suppose the recipient reports that its window size is 100,000 (we will soon find out how it passes this value), so the sender sends 100,000 bytes. Suppose that by the time the sender transmitted a hundred thousandth byte, the receiver sent the segments ACKfor the first 10,000 of these bytes. This means that 90,000 bytes have not yet been confirmed. Since the window size is 100,000, the sender can transfer another 10,000 bytes before he has to wait for new ones ACK. If after sending these 10,000 additional bytes furtherACKif it was not received, then the sender will run into its limit of 100,000 unconfirmed bytes. Consequently, the sender will have to wait and stop sending data (except for the retransmission of data that he considers lost) until he receives new ones ACK.


Each side of the TCP connection notifies the other of the size of its window during the handshake process that is performed when the connection is opened. In addition, window sizes can be dynamically changed during the connection process. A computer with a large TCP buffer can announce a large window size to maximize throughput. This allows the machine that communicates with it to continuously transmit data over a TCP connection without pausing or waiting for confirmation. A computer with a small TCP buffer may be forced to report a small window size. Sometimes senders completely fill the window and are forced to wait until some of the segments are confirmed. Bandwidth suffers because of this, but it is necessary that TCP buffers do not overflow.


The size of the TCP window is a strict limit on the amount of transmitted unconfirmed data. We can use it to calculate the maximum possible sequence number (which in the equation below I designated as max_seq_no), which the sender can send at the current time:

max_seq_no = max_acked_seq_no + window_size

max_acked_seq_no- This is the maximum sequence number for which the recipient has sent ACK. This is the maximum sequence number that the sender knows that the recipient has exactly received. Since the sender can only transmit window_sizeunconfirmed bytes, the maximum sequence number that it can send is max_acked_seq_no + window_size.

Because of this, the TCP specification states that the recipient should ignore any data it receives that has serial numbers outside the valid window. For example, if the recipient has confirmed all bytes up to 15,000, and its window size is 30,000, then it will receive any data with a serial number in the range from 15,000 to (15,000 + 30,000 = 45,000). Moreover, the recipient completely ignores data with serial numbers outside this interval. If the segment contains data, some of which are within this window, and some outside it, then the data inside the window will be accepted and confirmed, but the data outside it will be discarded. Note that we still ignore the possibility of the selective onesACK that were briefly touched on at the beginning of the post.

In the case of most TCP segments, this rule gives us an interval of acceptable sequence numbers. However, as mentioned earlier, the RSTrestrictions imposed on segments are even stricter than the restrictions on ordinary data transmission segments. As we will soon see, this was done to complicate the conduct of a variant of a TCP reset attack called a “blind TCP reset attack” .

Acceptable Sequence Numbers for RST Segments


Regular segments are accepted if their sequence number is between the next expected sequence number and this number plus the window size. However, packets RSTare only received when their sequence number is exactly equal to the next expected sequence number. Let us return to the previous example, in which the recipient sent the confirmation number 15,000. For the packet to RSTbe received, its sequence number must be exactly 15,000. If the recipient receives a segment RSTwith a sequence number not equal to 15,000, then he will not accept it.


If the sequence number is outside the interval, then the receiver completely ignores it. However, if it is within the window of the expected sequence numbers, the receiver sends a “challenge ACK” (“ACK call”). This is a segment that tells the sender that the segment RSThas an invalid sequence number. He also tells the sender the sequence number that the recipient expects. The sender can use this information from the ACKcall to recreate and resend his RST.

Until 2010, TCP did not impose these additional segment restrictions RST. Segments were RSTaccepted or rejected in accordance with the same rules as any others. However, this too simplified the blind blind TCP reset attacks .

Blind TCP attacks


If the attacker has the ability to intercept the traffic exchanged between his victims, he can read the serial and confirmation numbers of the TCP packets of the victims. He can use this information to select which serial numbers to give to his fake segments RST. However, if the attacker cannot intercept the traffic of the victims, he will not know which sequence numbers to insert. But he can still transfer any number of segments RSTwith any number of different serial numbers, hoping that one of them turns out to be correct. Such an attack is called a blind TCP reset attack.

As we have already said, in the initial version of the TCP protocol, the attacker only had to pick up the serial numberRSTwithin the receiver's TCP window. An article titled “Slipping in the Window” showed that this made the blind attacks too easy, since for an almost guaranteed success, an attacker just had to send tens of thousands of segments. To counter this, the rule that forced the recipient to accept the segment RSTwas replaced with the more stringent criterion described above. Thanks to the new rules for carrying out TCP reset attacks, millions of segments need to be sent blindly, which makes them practically unrealizable. See RFC-5963 for details .

Perform a TCP reset attack against ourselves


Note: I tested this process on OSX, but received a few comments that it does not work properly on Linux.

Now we know everything about executing a TCP reset attack. The attacker must:

  • Watch network traffic ( “sniff” it) between two victims
  • Sniff the TCP segment with the flag enabled ACKand read its confirmed number
  • Make a false TCP segment with the flag turned on RSTand a sequence number equal to the confirmed number of the intercepted segment (note that this implies a slow transmission, otherwise the selected sequence number will quickly become outdated. (To increase the chances of success, you can transfer several segments RSTwith a large interval of sequence numbers .)
  • Send fake segments to one or both victims, hoping this will break their TCP connection

To practice, let's conduct a TCP attack on ourselves on the same computer, communicating with ourselves through localhost. For this we need:

  1. Configure TCP connection between two terminal windows
  2. Write an attack program that will deal with traffic sniffing
  3. Modify the program so that it produces and sends fake segments RST.

Let's get started.

1. Establishing a TCP connection between two terminal windows


We will configure the TCP connection using the tool netcat, which by default is available on many operating systems. Any other TCP client will do . In the first terminal window, we will execute the following command:

nc -nvl 8000

This command starts a TCP server listening on a port on our local machine 8000. In the second terminal window, execute the following command:

nc 127.0.0.1 8000

This command attempts to create a TCP connection to the machine by the IP address of 127.0.0.1the port 8000. Now, between the two windows of the terminal, a TCP connection should be established. Try to enter something in one window - the data will have to be transmitted over the TCP connection and appear in another window.


2. Traffic sniffing


We will write an attack program that performs traffic sniffing using the scapypopular Python network library. This program uses scapy to read data transferred between two windows of the terminal, although it is not part of the connection.

The program code is posted in my repository on GitHub . The program sniffs the connection traffic and displays it on the terminal. The main core of the code is the method call snifffrom the library scapylocated at the end of the file:

t = sniff(
        iface='lo0',
        lfilter=is_packet_tcp_client_to_server(localhost_ip, localhost_server_port, localhost_ip),
        prn=log_packet,
        count=50)

This piece of code tells us scapyto sniff packets on the interface lo0and capture details of all packets as part of our TCP connection. The call has the following parameters:

  • iface- orders scapyto listen to the network interface lo0, or localhost
  • lfilter — , scapy , IP- localhost . , , lo0. , .
  • prn — , scapy , lfilter. . , RST.
  • count — , scapy .

To test this program, configure the TCP connection from step 1. Clone my GitHub repository, follow the configuration instructions, and run the program in the third window of the terminal. Enter some text into one of the terminals of the TCP connection. You should see that the program will begin to record information about the connection segments.

3. Sending fake packages RST


We have established a connection, and the program can sniff all TCP segments passing through it. The only thing left for us is to modify the program so that it performs a TCP reset attack by transmitting fake segments RST. To do this, we will change the function prn(see the list of parameters above), called scapyfor packages that meet the requirements of the function lfilter. In the modified version of the function, instead of simply fixing the corresponding package, we study it, extract the necessary parameters, and use these parameters to build and send the segment RST.

Suppose we intercepted a segment going from (src_ip, src_port)k (dst_ip, dst_port). He has a flag set ACKand the confirmation number is 100,000. To manufacture and send a segment, we:

  • IP- , . , . , .
  • RST , , RST
  • , ,
  • send scapy — .

To modify our previous program as needed, uncomment this line and comment out the line above it.

Now we are ready for a full-scale attack. Configure the TCP connection in accordance with step 1. Run the attack program from step 2 in the third window of the terminal. Then enter some text in one of the terminals of the TCP connection. In the terminal where you entered the text, the TCP connection will suddenly and mysteriously break. The attack is done!


Further work


  1. Continue experimenting with the attack tool. Track what happens if you add or subtract 1 from the sequence number of the package RST. Make sure that it must be exactly equal to the value of the ackintercepted packet.
  2. Wireshark lo0 . TCP-, RST. ip.src == 127.0.0.1 && ip.dst == 127.0.0.1 && tcp.port == 8000 .
  3. , . RST, RST , . , RST, .


The TCP reset attack is both deep and simple at the same time. Good luck with your experiments and let me know if you have questions or comments.

All Articles