Involving knowledge
1. The essence of handshake and wave
In fact, I think waving and shaking hands are completely confusing concepts. The change of serial number and verification number completely depends on whether you are the data sender or receiver.
The data here only refers to the data carried in the application layer http, excluding TCP and IP packet headers.
Knowledge point 1
Assuming that you are sending data, the following possibilities are common to you:
1. The initial syn packet. For this packet, it carries 1 byte of length data
2. ack packet, check packet, reply to the other party after receiving the message to calculate that the received packet does not carry data
3,psh_ack packet, push data packet, specially carry data, and confirm that the data received last time is correct
4,fin_psh_ack packet is used to transmit push data for the last time and confirm that the data received last time is correct (Note: it is the data received last time, not the last packet, so the tcp protocol is flexible here). This is the data it carries plus one byte of data
Summary: the packets sent with syn and fin are counted as one byte of data, while ack packets are not counted as data. psh packets need to calculate the length of the data they carry
Knowledge point 2
For the sender (yourself), your serial number will increase as much as you send data, and the verification number will not change
For the receiver (yourself), your verification number will increase as much as you receive the data, and the serial number will remain unchanged
Therefore, when dealing with the verification number and serial number, only think from your own point of view, such as setting global variables, sending thread and receiving thread to modify their serial number and verification number, and pay attention to controlling the execution order of the two threads during implementation.
2 other knowledge
2.py threading module
Thread events are mainly used to control the execution order between two threads.
There is an event class Event() in threading. After generating a global instance object, you can use the wait() method to block the current thread and let the CPU execute another thread. When the set() method of the object appears in another thread, it will switch to the wait() method just blocked for execution
3.scapy parsing data package
The packet pkt constructed or sniff() is layered, SEQ = pkt [TCP] Seq means to take the serial number in the data packet; data = pkt[TCP].payload means to take the load of the packet, that is, the http data of the application layer
4. flags in the packet
There are several types of packets, whose value depends on the type of packet, such as psh_ack takes "PA" as its value
code
In a previous post about scapy, I used its own sr() to send and receive data. I didn't know how to parse the contents of the data packet returned by the sr() method, so I thought of opening another thread with sniff()
from scapy.all import * from threading import * from random import * dport = 80 dst = "192.168.1.1" sport = randrange(10241,22535) seq=0 ack=0 ###############Convenient construction of packet module function######### def createpkt(flags,data=""): global seq,ack #####Introducing global variables############ return IP(dst = dst)/TCP(dport=dport,sport=sport,seq=seq,ack=ack,flags=flags)/data #################Processing received packets#################### def a_handle(pkt): pass def sa_handle(pkt): global ack ack = pkt[TCP].seq+1 def pa_handle(pkt): global ack ack += len(pkt[TCP].payload) def fpa_handle(pkt): global ack ack += len(pkt[TCP].payload)+1 ################Which processing method to choose################## def handleflag(pkt): flags=pkt[TCP].flags print(flags) if flags == "A": a_handle(pkt) elif flags == "SA": sa_handle(pkt) event1.set() elif flags == "PA": pa_handle(pkt) elif flags == "FPA": fpa_handle(pkt) #####Send fin_psh_ack bag, start waving event2.set() ####Jump to even2 Wait() execution elif flags == "R": print("jianting error") #############Listening thread entry################### def sniffdata(): sniff(filter = "src host 192.168.1.1 and tcp port 80",prn = handleflag,iface = 'Ethernet0') ##############Set two thread events############ event1 = Event() event2 = Event() Thread(target=sniffdata).start() ######Start listening thread syn = createpkt(flags="S") ######Get the first package seq += 1 ####Before the thread receives the modification of the sequence number, the callback processes the data send(syn) event1.wait() ####Set blocking and wait for the callback function of the listening thread to process the received data packet - modify it to the correct confirmation number for the next contract send(createpkt(flags="A")) #### ack packet serial number and confirmation number are not modified and can be directly contracted data = "GET / HTTP/1.0/ \r\n\r\n" psh_ack = createpkt(flags="PA",data=data) seq += len(data) ###Construct data, calculate how many serial numbers you increase, and then contract and block send(psh_ack) event2.wait() send(createpkt(flags="A")) ###Wave ack to confirm fin_ack = createpkt(flags = "FA") seq += 1 send(fin_ack) ###Send wave ####There is also a packet, the waving ack confirmation packet of the target aircraft
Implementation environment
168.80, target machine, http 1.1
Native 192.168.1.16, python environment, successfully installed scapy
wireshark grab
It's not perfect. I don't know why I sent me two fin packets when waving, but it doesn't matter. It's logical.
If you have any harvest, pay more attention to me. Alas, there is no fan. It's too poor.
Statement: it is only used for technology sharing. If it is used for illegal activities, it has nothing to do with me.
In addition: reprint please indicate the source, creation is not easy, thank you
ps: I'm timid and afraid of being invited to tea by the police uncle. If there is anything wrong, please write to me personally and I will delete this post immediately