有没有办法使用 python scapy 修改 .pcap 文件中的字符串而不产生错误?

问题描述 投票:0回答:1

我正在 python 中试验 scapy 并捕获了一个测试 pcap,其中仅包含通过 HTTP 的文件传输。文件内容是明文。

我正在尝试从根本上更改服务器字符串:

HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.11.8

对于另一位,我们可以说:

HTTP/1.0 200 OK
Server: A custom one

问题是,经过此更改后,数据包的大小发生了变化,因此许多 TCP 数据包被标记为重传,HTTP 数据包的内容显示字节丢失等。

有没有办法修改字符串 - 以及相应的大小字段 - 以便 pcap 保持没有错误?

附注我尝试更改以太网层的帧长度和捕获长度字段,但仍然出现错误。

我暂时的演示脚本是:

from scapy.all import *

def replace_user_agent(packets):
    i = 0
    for packet in packets:
        i+=1
        if packet.haslayer(Raw):
            raw = packet[Raw].load
            if b"SimpleHTTP/0.6 Python/3.11.8" in raw:
                raw = raw.replace(b"SimpleHTTP/0.6 Python/3.11.8", b"A custom one"+ b" " * (len("SimpleHTTP/0.6 Python/3.11.8") - len("A custom one"))) # cover the missing length with spaces
                packet[Raw].load = raw

                # Recalculate length fields and checksums
                if packet.haslayer(IP):
                    del packet[IP].len  # Recalculate IP length
                    del packet[IP].chksum  # Recalculate IP checksum
                if packet.haslayer(TCP):
                    del packet[TCP].chksum  # Recalculate TCP checksum
                elif packet.haslayer(UDP):
                    del packet[UDP].len  # Recalculate UDP length
                    del packet[UDP].chksum  # Recalculate UDP checksum


    return packets

if __name__ == "__main__":
    input_pcap = "input.pcap"
    output_pcap = "output.pcap"

    packets = rdpcap(input_pcap)
    modified_packets = replace_user_agent(packets)
    wrpcap(output_pcap, modified_packets)

这个脚本实现了我想要实现的目标,但没有实现我想要实现的目标。它基本上用我的较短的自定义字符串替换了服务器字符串,并且对于丢失的字节,它只使用空格。

python scapy pcap
1个回答
0
投票

根据需要向修改后的数据包添加填充可消除警告/错误

from scapy.all import *
from scapy.utils import rdpcap
from scapy.layers.inet import TCP
from scapy.layers.http import *

def parse_pkts(pkts, write=True):
    for pkt in pkts:
        if Raw in pkt and pkt[Ether][TCP].sport == 8000 and 'Server: ' in pkt[Raw].fields['load'].decode('ascii'):
            #print(pkt.show())
            needle = "netcat.local"
            new_needle= 'XXXX'
            payload = pkt[Raw].fields['load'].decode('ascii').replace(needle, "XXXX")
            print(pkt[Raw].fields['load'], len(pkt))
            pkt[Raw].load = payload.encode('ascii') #fields['load']
            
            pad = "\x00"*(len(pkt) - len(payload))
            pkt = pkt/Padding(pad)

            print(pkt[Raw].fields['load'], len(pkt))
        if write:
            wrpcap(f'{dstdir}/test-scapy-mangled.pcap', pkt, append=True)
    
dstdir = '/home/lmc/projects/forensics'
pkts=rdpcap(f"{dstdir}/test-netcat-local.pcapng")

parse_pkts(pkts)

pkts=rdpcap(f'{dstdir}/test-scapy-mangled.pcap')
parse_pkts(pkts, write=False)

输出

b'HTTP/1.1 200 OK\r\nServer: netcat.local\r\nConnection: Close\r\n\r\n\nresponse from parent.example.com:8000\n' 165
b'HTTP/1.1 200 OK\r\nServer: XXXX\r\nConnection: Close\r\n\r\n\nresponse from parent.example.com:8000\n' 223
b'HTTP/1.1 200 OK\r\nServer: XXXX\r\nConnection: Close\r\n\r\n\nresponse from parent.example.com:8000\n\x00\x00\x00\x00\x00\x00\x00\x00' 223
b'HTTP/1.1 200 OK\r\nServer: XXXX\r\nConnection: Close\r\n\r\n\nresponse from parent.example.com:8000\n\x00\x00\x00\x00\x00\x00\x00\x00' 347

tshark
不抱怨

tshark -r /home/lmc/projects/forensics/test-scapy-mangled.pcap
    1   0.000000    127.0.0.1 → 127.0.0.1    TCP 74 36994 → 8000 [SYN] Seq=0 Win=65495 Len=0 MSS=65495 SACK_PERM TSval=3035651634 TSecr=0 WS=128
    2   0.000017    127.0.0.1 → 127.0.0.1    TCP 74 8000 → 36994 [SYN, ACK] Seq=0 Ack=1 Win=65483 Len=0 MSS=65495 SACK_PERM TSval=3035651634 TSecr=3035651634 WS=128
    3   0.000027    127.0.0.1 → 127.0.0.1    TCP 66 36994 → 8000 [ACK] Seq=1 Ack=1 Win=65536 Len=0 TSval=3035651634 TSecr=3035651634
    4   0.000068    127.0.0.1 → 127.0.0.1    HTTP 143 GET / HTTP/1.1 
    5   0.000074    127.0.0.1 → 127.0.0.1    TCP 66 8000 → 36994 [ACK] Seq=1 Ack=78 Win=65408 Len=0 TSval=3035651634 TSecr=3035651634
    6   0.000086    127.0.0.1 → 127.0.0.1    TCP 165 HTTP/1.1 200 OK  [TCP segment of a reassembled PDU]
    7   0.000094    127.0.0.1 → 127.0.0.1    TCP 66 36994 → 8000 [ACK] Seq=78 Ack=100 Win=65536 Len=0 TSval=3035651634 TSecr=3035651634
    8   0.000104    127.0.0.1 → 127.0.0.1    HTTP 66 HTTP/1.1 200 OK 
    9   0.000133    127.0.0.1 → 127.0.0.1    TCP 66 36994 → 8000 [FIN, ACK] Seq=78 Ack=101 Win=65536 Len=0 TSval=3035651634 TSecr=3035651634
   10   0.000140    127.0.0.1 → 127.0.0.1    TCP 66 8000 → 36994 [ACK] Seq=101 Ack=79 Win=65536 Len=0 TSval=3035651634 TSecr=3035651634
如果没有填充,

tshark
会显示警告

HTTP 165 HTTP/1.1 200 OK [Packet size limited during capture]

© www.soinside.com 2019 - 2024. All rights reserved.