• golang用字符串数据生成http的pcap文件


    因为我有的只是pyload里面的字符串数据。没有协议头的部分,所以只能自己创建协议头的数据。
    主要使用的就是go的gopacket和gopcap包。下面直接上代码

    package main
    
    import (
    	"bytes"
    	"encoding/base64"
    	"fmt"
    	"log"
    	"math/rand"
    	"time"
    
    	"github.com/google/gopacket"
    	"github.com/google/gopacket/layers"
    	"github.com/google/gopacket/pcapgo"
    )
    
    // writeToPCAP_HTTP 函数用于将HTTP数据包写入到 PCAP 文件中
    func writeToPCAP_HTTP(w *pcapgo.Writer, requestData []byte, responseData []byte) error {
    	// 每个请求随机选择本地端口号
    	srcPort := layers.TCPPort(rand.Intn(16383) + 49152) // 49152 - 65535 是动态/私有端口范围
    	dstPort := layers.TCPPort(80)
    	// 创建以太网帧
    	ethernetLayer := &layers.Ethernet{
    		SrcMAC:       []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    		DstMAC:       []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    		EthernetType: layers.EthernetTypeIPv4,
    	}
    
    	// 创建IP数据包(请求)
    	requestIP := &layers.IPv4{
    		Version:  4,
    		IHL:      5,
    		TTL:      64,
    		Protocol: layers.IPProtocolTCP,
    		SrcIP:    []byte{127, 0, 0, 1},
    		DstIP:    []byte{127, 0, 0, 1},
    	}
    	// 计算IP数据包长度(请求)
    	//requestIP.Length = uint16(len(requestData) + 40) // IP header length (20 bytes) + TCP header length (20 bytes) + request payload length
    
    	// 创建TCP数据包(请求)
    	requestTCP := &layers.TCP{
    		SrcPort: srcPort,
    		DstPort: dstPort,
    		Seq:     rand.Uint32(), // 生成随机的 Sequence Number
    		Ack:     0,
    		Window:  16384,
    		ACK:     false,
    		SYN:     true,
    	}
    	requestTCP.SetNetworkLayerForChecksum(requestIP)
    	// 保存请求数据包的 Sequence Number 和 Acknowledgment Number
    	requestSeq := requestTCP.Seq
    	requestAck := requestTCP.Ack
    
    	// 序列化并写入请求数据包
    	buffer := gopacket.NewSerializeBuffer()
    	//这个是重点!!!!不然你生成的pcap包很可能打不开
    	options := gopacket.SerializeOptions{
    		FixLengths:       true,	// 修复数据包长度
    		ComputeChecksums: true,	// 计算checksum值
    	}
    	if err := gopacket.SerializeLayers(buffer, options, ethernetLayer, requestIP, requestTCP, gopacket.Payload(requestData)); err != nil {
    		return fmt.Errorf("error serializing request packet: %v", err)
    	}
    	if err := w.WritePacket(gopacket.CaptureInfo{
    		Timestamp:     time.Now(),
    		Length:        len(buffer.Bytes()),
    		CaptureLength: len(buffer.Bytes()),
    	}, buffer.Bytes()); err != nil {
    		return fmt.Errorf("error writing request packet: %v", err)
    	}
    
    	// 创建IP数据包(响应)
    	responseIP := &layers.IPv4{
    		Version:  4,
    		IHL:      5,
    		TTL:      64,
    		Protocol: layers.IPProtocolTCP,
    		SrcIP:    []byte{127, 0, 0, 1},
    		DstIP:    []byte{127, 0, 0, 1},
    	}
    	// 计算IP数据包长度(响应)
    	// responseIP.Length = uint16(len(responseData) + 40) // IP header length (20 bytes) + TCP header length (20 bytes) + response payload length
    
    	// 创建TCP数据包(响应)
    	responseTCP := &layers.TCP{
    		SrcPort: dstPort,
    		DstPort: srcPort,
    		Seq:     requestAck,                            // 使用请求数据包的 Acknowledgment Number 作为响应数据包的 Sequence Number
    		Ack:     requestSeq + uint32(len(requestData)), // 使用请求数据包的 Sequence Number 加上请求数据长度 作为响应数据包的 Acknowledgment Number
    		Window:  16384,
    		ACK:     true,
    		SYN:     false,
    	}
    	responseTCP.SetNetworkLayerForChecksum(responseIP)
    	// 序列化并写入响应数据包
    	buffer = gopacket.NewSerializeBuffer()
    	if err := gopacket.SerializeLayers(buffer, options, ethernetLayer, responseIP, responseTCP, gopacket.Payload(responseData)); err != nil {
    		return fmt.Errorf("error serializing response packet: %v", err)
    	}
    	if err := w.WritePacket(gopacket.CaptureInfo{
    		Timestamp:     time.Now(),
    		Length:        len(buffer.Bytes()),
    		CaptureLength: len(buffer.Bytes()),
    	}, buffer.Bytes()); err != nil {
    		return fmt.Errorf("error writing response packet: %v", err)
    	}
    
    	return nil
    }
    
    func main() {
    	// 创建一个字节缓冲区,用于存储 pcap 文件内容
    	var buf bytes.Buffer
    	// 创建一个 pcap writer,并将文件头数据写入到字节缓冲区中
    	w := pcapgo.NewWriter(&buf)
    	w.WriteFileHeader(65536, layers.LinkTypeEthernet)
    
    	// HTTP请求数据1
    	requestPayload := []byte("GET /mehmet.txt HTTP/1.1\r\nHost: 127.0.0.1\r\nUser-Agent: curl/7.55.1\r\nAccept: */*\r\n\r\n")
    
    	// HTTP响应数据1
    	responsePayload := []byte("HTTP/1.1 200 OK\r\nDate: Sun, 15 Oct 2017 21:58:29 GMT\r\nServer: Apache/2.4.27 (Debian)\r\nLast-Modified: Sun, 15 Oct 2017 21:57:37 GMT\r\nETag: \"12-55b9cfa5dd94e\"\r\nAccept-Ranges: bytes\r\nContent-Length: 18\r\nContent-Type: text/plain\r\n\r\nbest hacker ever.\n")
    
    	// 将请求和响应数据写入到 PCAP 文件中
    	if err := writeToPCAP_HTTP(w, requestPayload, responsePayload); err != nil {
    		log.Fatal(err)
    	}
    
    	// HTTP请求数据2
    	requestPayload = []byte("GET /hahhaha.txt HTTP/1.1\r\nHost: 127.0.0.1\r\nUser-Agent: curl/7.55.1\r\nAccept: */*\r\n\r\n")
    
    	// HTTP响应数据2
    	responsePayload = []byte("HTTP/1.1 200 OK\r\nDate: Sun, 15 Oct 2017 21:58:29 GMT\r\nServer: Apache/2.4.27 (Debian)\r\nLast-Modified: Sun, 15 Oct 2017 21:57:37 GMT\r\nETag: \"12-55b9cfa5dd94e\"\r\nAccept-Ranges: bytes\r\nContent-Length: 18\r\nContent-Type: text/plain\r\n\r\n1111 hacker ever.\n")
    	// 将请求和响应数据写入到 PCAP 文件中
    	if err := writeToPCAP_HTTP(w, requestPayload, responsePayload); err != nil {
    		log.Fatal(err)
    	}
    	// 将pcap文件内容以Base64编码输出到控制台
    	encoded := base64.StdEncoding.EncodeToString(buf.Bytes())
    	fmt.Println(encoded)
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
  • 相关阅读:
    Cy7 Tyramide,Tyramide-Cy7,花青素Cy7 酪酰胺,Cy7酪胺
    算法笔记 图论和优先级队列的笔记
    1.10.C++项目:仿muduo库实现并发服务器之Acceptor模块的设计
    敦煌网“星云计划”:助商家开拓新流量和新玩法,测评补单快速提高产品排名和销量
    Windows Server操作系统概述
    来看这份小微风控中的税票数据(含衍生等字段)
    新概念英语(第二册)复习——Lesson 6 - Lesson10
    金x软件有限公司安全测试岗位面试
    【STL】容器 - string的模拟实现
    3.加载天地图
  • 原文地址:https://blog.csdn.net/weixin_42094764/article/details/136366039