简体   繁体   English

如何使用 Scapy 生成序列号为“first:last”的数据包?

[英]How to generate packet having sequence number as `first:last` with Scapy?

I am trying to generate pcap file from a tcpdump output, how can I generate those packets having sequence number as first:last ?我正在尝试从 tcpdump output 生成 pcap 文件,如何生成序列号为first:last的那些数据包?

Here is what my tcpdump input looks like:这是我的 tcpdump 输入的样子:

tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes 1509471560.944080 MAC1 > MAC2, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 23237, offset 0, flags [DF], proto TCP (6), length 60) IP1.port > IP2.port: Flags [S], cksum 0x6d2f (incorrect -> 0x0b4a), seq 1127096708, win 65535, options [mss 1460,sackOK,TS val 817985 ecr 0,nop,wscale 6], length 0 1509471561.042855 MAC2 > MAC1, ethertype IPv4 (0x0800), length 58: (tos 0x0, ttl 64, id 3107, offset 0, flags [none], proto TCP (6), length 44) IP2.port > IP1.port: Flags [S.], cksum 0x85d8 (correct), seq 449984001, ack 1127096709, win 65535, options [mss 1460], length 0 1509471561.044008 MAC1 > MAC2, ethertype IPv4 (0x0800), length 54: (tos 0x0, ttl 64, id 23238, offset 0, flags [DF], proto TCP (6), length 40) IP1.port > IP2.port: Flags [.], cksum 0x6d1b (incorrect -> 0x9d95), seq 1, ack 1, win 65535, length 0 1509471561.046607 MAC1 > MAC2, ethertype IPv4 (0x0800), length 191: (tos 0x0, ttl 64, id 23239, offset 0, flags [DF], proto TCP (6), length 177) IP1.port > IP2.port: Flags [P.], cksum 0x6da4 (incorrect -> 0x98df), seq 1:138, ack 1, win 65535, length 137 1509471914.089046 MAC1 > MAC2, ethertype IPv4 (0x0800), length 82: (tos 0x0, ttl 64, id 54304, offset 0, flags [DF], proto UDP (17), length 68)

Following is the code I have prepared to process the TCP packets:以下是我准备处理 TCP 数据包的代码:

from scapy.all import *
import secrets

def generatePcapfromText(inputtxt,output):
    with open (inputtxt,encoding='cp850') as input:
        framenum=0
        for line in input:
            if line[0].isdigit(): # line one
                framenum += 1
                frametime=float(line[:16])

                srcmac= line[18:34]
                dstmac= line[38:54]
                ethertype = int(line[line.find('(')+1:line.find(')')], 16)
                frameLen=int(line[line.find('length')+7:line.find(': (')])
                frameTos=int(line[line.find('tos')+4:line.find(', ttl')],16)
                frameTtl=int(line[line.find('ttl')+4:line.find(', id')])
                frameId=int(line[line.find('id')+3:line.find(', offset')])
                frameOffset=line[line.find('offset')+7:line.find(', flags')]
                frameFlags=line[line.find('[')+1:line.find(']')]
                protocol = line[line.find('proto')+6:line.rfind('(')-1]
                ipLen = int(line[line.rfind('length')+6:line.rfind(')')])

                if frameFlags == "none":
                    frameFlags = ""

                ether = Ether(dst=dstmac, src=srcmac, type=ethertype) 

            elif len(line)>5:
                if line[5].isdigit(): # line two
                    srcinfo = line[4:line.find ( '>' )]
                    dstinfo = line[line.find ( '>' ) + 2:line.find ( ':' )]
                    ipsrc = srcinfo[:srcinfo.rfind ( '.' )]
                    ipdst = dstinfo[:dstinfo.rfind ( '.' )]
                    srcport = int(srcinfo[srcinfo.rfind ( '.' ) + 1:])
                    dstport = int(dstinfo[dstinfo.rfind ( '.' ) + 1:])

                    ip = ether/IP(src=ipsrc, dst=ipdst, len=frameLen, tos=frameTos, ttl=frameTtl, id=frameId, flags=frameFlags, proto=protocol.lower())

                    if protocol == "TCP":

                        frameFlag = line[line.find ( '[' ) + 1:line.find ( ']' )]
                        frameFlag=frameFlag.replace(".","A")

                        cksum = int(line[line.find ( 'cksum' ) + 6:line.find ( '(' )],16)

                        if ", ack" in line:      
                            seq_n = line[line.find ( ', seq' ) + 6:line.find ( ', ack' )]
                            ack_n = int(line[line.find ( 'ack' ) + 4:line.find ( ', win' )])
                        else:
                            seq_n = line[line.find ( ', seq' ) + 6:line.find ( ', win' )]
                            ack_n = 0

                        if "options" in line:
                            win = int(line[line.find ( 'win' ) + 4:line.find ( ', options' )])
                            options= line[line.find ( 'options' ) + 8:line.find ( ', length' )]
                        else:    
                            win = int(line[line.find ( 'win' ) + 4:line.find ( ', length' )])
                            options="[]"

                        pktlen = int(line[line.find ( ', length' ) + 9:])

                        if ":" in seq_n: 
                            # ???
                        else:   
                            pkt = ip / TCP(sport=srcport, dport=dstport , flags=frameFlag, seq=int(seq_n), ack=ack_n, chksum=cksum, window=win) / secrets.token_hex(pktlen)                  

                    pkt.time = frametime

                    wrpcap(output, pkt, append=True)

As TCP in Scapy need an integer for the sequence number I cannot pass it first:last as the sequence number, so It needs some modification which I am not familiar with as It is my first time working with Scapy.由于TCP中的 TCP 需要一个 integer 作为序列号,所以我不能first:last作为序列号,所以它需要一些我不熟悉的修改,因为这是我第一次使用 Scapy。 I have mark where this modification should be done via #???我已经通过#??? in the code above.在上面的代码中。

For my purpose it is important that the packets have the same timestamp as the tcpdump input, so I have set the packet timestamp via pkt.time=timestamp .出于我的目的,数据包具有与 tcpdump 输入相同的时间戳很重要,因此我通过pkt.time=timestamp设置了数据包时间戳。

PS: You can find history behind this question here . PS:你可以在这里找到这个问题背后的历史。

According to the tcpdump manpage根据 tcpdump 手册页

The notation is first:last which means sequence numbers first up to but not including last表示法是first:last表示sequence numbers first up to but not including last

The first:last notation doesn't actually exist within the packet, therefore Scapy won't understand it.first:last符号实际上并不存在于数据包中,因此 Scapy 不会理解它。 Tcpdump gives you this additional information based on the analysis of the TCP stream (and possible regrouping of the packets) Tcpdump 根据对 TCP stream 的分析为您提供了这些附加信息(以及可能的数据包重组)

You should also note that your sequence numbers are probably relative, which means they don't really mean anything else than the order.您还应该注意,您的序列号可能是相对的,这意味着它们除了顺序之外没有任何其他含义。

Using the first part of the number as a sequence number will probably be enough for your needs:使用数字的第一部分作为序列号可能足以满足您的需求:

seq = int(seq_n.split(":")[0])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM