因为我有的只是pyload里面的字符串数据。没有协议头的部分,所以只能自己创建协议头的数据。
主要使用的就是go的gopacket和gopcap包。下面直接上代码
package mainimport ("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 NumberAck: 0,Window: 16384,ACK: false,SYN: true,}requestTCP.SetNetworkLayerForChecksum(requestIP)// 保存请求数据包的 Sequence Number 和 Acknowledgment NumberrequestSeq := requestTCP.SeqrequestAck := 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 NumberAck: requestSeq + uint32(len(requestData)), // 使用请求数据包的 Sequence Number 加上请求数据长度 作为响应数据包的 Acknowledgment NumberWindow: 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请求数据1requestPayload := []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响应数据1responsePayload := []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请求数据2requestPayload = []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响应数据2responsePayload = []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)
}