繁体   English   中英

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

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

我正在尝试从 tcpdump output 生成 pcap 文件,如何生成序列号为first:last的那些数据包?

这是我的 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)

以下是我准备处理 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)

由于TCP中的 TCP 需要一个 integer 作为序列号,所以我不能first:last作为序列号,所以它需要一些我不熟悉的修改,因为这是我第一次使用 Scapy。 我已经通过#??? 在上面的代码中。

出于我的目的,数据包具有与 tcpdump 输入相同的时间戳很重要,因此我通过pkt.time=timestamp设置了数据包时间戳。

PS:你可以在这里找到这个问题背后的历史。

根据 tcpdump 手册页

表示法是first:last表示sequence numbers first up to but not including last

first:last符号实际上并不存在于数据包中,因此 Scapy 不会理解它。 Tcpdump 根据对 TCP stream 的分析为您提供了这些附加信息(以及可能的数据包重组)

您还应该注意,您的序列号可能是相对的,这意味着它们除了顺序之外没有任何其他含义。

使用数字的第一部分作为序列号可能足以满足您的需求:

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

暂无
暂无

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

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