Python构造数据包,包含:

TCP三次握手、

传输数据、

四次挥手

实现 随机乱序TCP数据包

from scapy.all import *
from scapy.all import Ether, IP, TCP, UDP, wrpcap
from abc import ABC, abstractmethod
import random
import dpkt
from scapy.all import *

class TcpPacketStrategy(ABC):
    @abstractmethod
    def generate_packets(self, src_ip, dst_ip, src_port, dst_port, seq_num, ack_num, data=None):
        pass


class ThreeWayHandshakeStrategy(TcpPacketStrategy):
    def generate_packets(self, src_ip, dst_ip, src_port, dst_port, seq_num, ack_num, data=None):

        syn = IP(src=src_ip, dst=dst_ip) / TCP(sport=src_port, dport=dst_port, flags='S', seq=seq_num)
        syn_ack = IP(src=dst_ip, dst=src_ip) / TCP(sport=dst_port, dport=src_port, flags='SA', seq=1000,ack=syn.seq + 1)
        ack = IP(src=src_ip, dst=dst_ip) / TCP(sport=src_port, dport=dst_port, flags='A', seq=syn.seq + 1,ack=syn_ack.seq + 1)
        return [syn, syn_ack, ack]


class DataTransferStrategy(TcpPacketStrategy):
    def generate_packets(self, src_ip, dst_ip, src_port, dst_port, seq_num, ack_num, data_list=None):
        packets = []
        for data in data_list:
            packet = IP(src=src_ip, dst=dst_ip) / TCP(sport=src_port, dport=dst_port, flags='PA', seq=seq_num,ack=ack_num) / Raw(load=data)
            packets.append(packet)
            seq_num += len(data)  # 假设数据长度即为字节数
        return packets


class FourWayTeardownStrategy(TcpPacketStrategy):
    def generate_packets(self, src_ip, dst_ip, src_port, dst_port, seq_num, ack_num, data=None):
        # 客户端发送 FIN
        fin = IP(src=src_ip, dst=dst_ip) / TCP(sport=src_port, dport=dst_port, flags='FA', seq=seq_num, ack=ack_num)
        # 服务器收到 FIN 后发送 ACK
        ack1 = IP(src=dst_ip, dst=src_ip) / TCP(sport=dst_port, dport=src_port, flags='A', seq=ack_num, ack=fin.seq + 1)
        # 服务器发送 FIN
        fin2 = IP(src=dst_ip, dst=src_ip) / TCP(sport=dst_port, dport=src_port, flags='FA', seq=ack_num,ack=fin.seq + 1)
        # 客户端发送 ACK 确认
        ack2 = IP(src=src_ip, dst=dst_ip) / TCP(sport=src_port, dport=dst_port, flags='A', seq=fin.seq + 1,ack=fin2.seq + 1)
        return [fin, ack1, fin2, ack2]


class TcpPcapGenerator:
    def __init__(self, strategy: TcpPacketStrategy):
        self._strategy = strategy

    def set_strategy(self, strategy: TcpPacketStrategy):
        self._strategy = strategy

    def generate(self, src_ip, dst_ip, src_port, dst_port, seq_num, ack_num, data=None):
        return self._strategy.generate_packets(src_ip, dst_ip, src_port, dst_port, seq_num, ack_num, data)


class WriteTcpPcap:
    def writeTcpPcap(self,array):
        src_ip = array[0]
        dst_ip = array[1]
        src_port = array[2]
        dst_port = array[3]
        seq_num = array[4]
        ack_num = array[5]
        data =  array[6]

        src_ip_lastTwoDigits = "".join(array[0].split('.')[-2:])
        dst_ip_lastTwoDigits = "".join(array[1].split('.')[-2:])
        fileName = f'{src_ip_lastTwoDigits}_{dst_ip_lastTwoDigits}_{src_port}_{dst_port}_{seq_num}'
        print(fileName)

        # 生成三次握手数据包
        generator = TcpPcapGenerator(ThreeWayHandshakeStrategy())
        handshake_packets = generator.generate(src_ip, dst_ip, src_port, dst_port, seq_num, ack_num)

        # 计算初始序列号和确认号
        seq_num += 1
        ack_num = 1001

        # 生成数据传输数据包
        generator.set_strategy(DataTransferStrategy())
        data_packets = generator.generate(src_ip, dst_ip, src_port, dst_port, seq_num, ack_num,data)

        # 更新序列号和确认号
        seqAndLen = []
        for packet in data_packets:
            seqAndLen.append(seq_num)        # 表示:Sequence Number (raw), 而非:Sequence Number
            seq_num += len(packet[Raw].load)


        # 生成四次挥手数据包
        generator.set_strategy(FourWayTeardownStrategy())
        teardown_packets = generator.generate(src_ip, dst_ip, src_port, dst_port, seq_num, ack_num)

        # 合并所有数据包
        all_packets = handshake_packets + data_packets + teardown_packets

        # 写入到PCAP文件
        wrpcap(f'{fileName}.pcap', all_packets)
        print(f"PCAP file generated: {fileName}.pcap")
        print(f"seqAndLen : length:{len(seqAndLen)}, value:{seqAndLen}")


class RandomPcap:
    def randomPcap(self, file, seed, index):
        pass


class SeedRandomPcap(RandomPcap):
    def randomPcap(self, file,seed, index):
        packets =  rdpcap(file)

        packet_indices = index

        random.seed(seed)              # 随机种子
        random.shuffle(packet_indices) # 打乱列表后值固定[8, 3, 6, 14, 11, 15, 2, 12, 0, 1, 13, 10, 16, 9, 5, 4, 7]

        print(packet_indices)

        selected_packets = [packets[i] for i in packet_indices]

        for i, packet in enumerate(selected_packets, start=1):
            print(f"Packet {i}: {packet.summary()}")

        # 如果你想要将截取的报文写入新的pcap文件
        shuffledName = file.split('.')[0]

        # 使用 join() 函数拼接字符串列表
        result = ''.join([str(num) for num in packet_indices])

        wrpcap(f'{shuffledName}_{result}.pcap', selected_packets)

class SeedNoneRandomPcap(RandomPcap):
    def randomPcap(self, file,seed, index):
        packets =  rdpcap(file)

        packet_indices = index

        random.seed(seed)              # 随机种子
        random.shuffle(packet_indices) # 打乱列表后值不固定

        print(packet_indices)

        selected_packets = [packets[i] for i in packet_indices]

        for i, packet in enumerate(selected_packets, start=1):
            print(f"Packet {i}: {packet.summary()}")

        # 如果你想要将截取的报文写入新的pcap文件
        shuffledName = file.split('.')[0]

        # 使用 join() 函数拼接字符串列表
        result = ''.join([str(num) for num in packet_indices])

        wrpcap(f'{shuffledName}_{result}.pcap', selected_packets)

class ExtractRandomPcap(RandomPcap):
    def randomPcap(self, file,seed, index):
        packets =  rdpcap(file)

        packet_indices = index

        selected_packets = [packets[i] for i in packet_indices]

        for i, packet in enumerate(selected_packets, start=1):
            print(f"Packet {i}: {packet.summary()}")

        # 如果你想要将截取的报文写入新的pcap文件
        shuffledName = file.split('.')[0]

        # 使用 join() 函数拼接字符串列表
        result = ''.join([str(num) for num in index])

        wrpcap(f'{shuffledName}_{result}.pcap', selected_packets)


# 使用示例
if __name__ == "__main__":

    array = [ "192.168.1.2","192.168.1.1", 12345,80,1000,0,["Data1", "Data12", "Data123", 'Data1234', "Data12345",'Data123456','Data1234567','Data12345678','Data123456789','Data1234567890']]
    WriteTcpPcap().writeTcpPcap(array)

    array = [ "192.168.2.2","192.168.1.1", 12345,80,1000,0,["Data1", "Data12", "Data123", 'Data1234', "Data12345",'Data123456','Data1234567','Data12345678','Data123456789','Data1234567890']]
    WriteTcpPcap().writeTcpPcap(array)

    array = [ "192.168.1.2","192.168.1.1", 12345,81,1000,0,["Data1", "Data12", "Data123", 'Data1234', "Data12345",'Data123456','Data1234567','Data12345678','Data123456789','Data1234567890']]
    WriteTcpPcap().writeTcpPcap(array)

    array = [ "192.168.2.2","192.168.1.1", 12345,81,1000,0,["Data1", "Data12", "Data123", 'Data1234', "Data12345",'Data123456','Data1234567','Data12345678','Data123456789','Data1234567890']]
    WriteTcpPcap().writeTcpPcap(array)

    filePcap = '12_11_12345_80_1000.pcap'

    SeedRandomPcap().randomPcap(filePcap, 3, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])
    SeedNoneRandomPcap().randomPcap(filePcap, None, [3, 4, 5, 6, 7, 8, 9, 10, 11, 12])

    ExtractRandomPcap().randomPcap(filePcap, 0, [3]) # 0,1,2 三次握手, 3第1个数据包
    ExtractRandomPcap().randomPcap(filePcap, 0, [12])# 12最后一个数据包
    ExtractRandomPcap().randomPcap(filePcap, 0, [4])
    ExtractRandomPcap().randomPcap(filePcap, 0, [5, 6, 7])
    ExtractRandomPcap().randomPcap(filePcap, 0, [4, 6, 10])
    ExtractRandomPcap().randomPcap(filePcap, 0, [3,9,6,7,4])




点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部