Как создать пакет с порядковым номером как `first: last` с помощью Scapy? - PullRequest
0 голосов
/ 02 октября 2019

Я пытаюсь сгенерировать файл pcap из вывода tcpdump. Как я могу сгенерировать эти пакеты, имеющие порядковый номер как 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 в Scapy нужно целое число для порядкового номера, я не могу его передать first:last как порядковый номер, поэтому он нуждается в некоторой модификации, с которой я не знаком, так как я впервые работаю со Scapy. У меня есть отметка, где эта модификация должна быть сделана через #??? в приведенном выше коде.

Для моей цели важно, чтобы пакеты имели ту же временную метку, что и вход tcpdump, поэтому я установил временную метку пакета черезpkt.time=timestamp.

PS: историю можно найти за этим вопросом здесь .

1 Ответ

2 голосов
/ 02 октября 2019

Согласно man-странице tcpdump

Обозначение first:last, что означает sequence numbers first up to but not including last

Обозначение first:last фактически не существует в пакетепоэтому Скапи не поймет этого. Tcpdump предоставляет вам эту дополнительную информацию, основанную на анализе потока TCP (и возможной перегруппировке пакетов)

Вы также должны заметить, что ваши порядковые номера, вероятно, являются относительными, что означает, что они на самом деле ничего не значатчем порядок.

Использование первой части номера в качестве порядкового номера, вероятно, будет достаточно для ваших нужд:

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