因为我有的只是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)
}