当前位置:   article > 正文

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

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
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/172210
推荐阅读
相关标签
  

闽ICP备14008679号