func (p *processor) decodeAppLayer(pkt gopacket.Packet) error { var moldUdp64Decoder gopacket.Decoder = nasdaq.LayerTypeMoldUDP64 var ittoDecoder gopacket.Decoder = nasdaq.LayerTypeItto //log.Println("decodeAppLayer", pkt) transpLayer := pkt.TransportLayer() appLayer := pkt.ApplicationLayer() if transpLayer == nil || transpLayer.LayerType() != layers.LayerTypeUDP || appLayer == nil { return nil } packetBuilder := pkt.(gopacket.PacketBuilder) if packetBuilder == nil { panic("packet is not packetBuilder") } if appLayer.LayerType() != gopacket.LayerTypePayload { panic("appLayer is not LayerTypePayload") } data := appLayer.LayerContents() if err := moldUdp64Decoder.Decode(data, packetBuilder); err != nil { return err } for _, l := range pkt.Layers() { if mb, ok := l.(*nasdaq.MoldUDP64MessageBlockChained); ok { ittoDecoder.Decode(mb.Payload, packetBuilder) } } return nil }
//if it is the output stream from local machine func outputStream(packet gopacket.Packet, Srcaddr *metrics.Address, Destaddr *metrics.Address) { ishttp, httpcontent := detectHttp(packet) if httpcontent != nil { if glog.V(1) { //glog.Info("the content of packet sent:", string(httpcontent)) } } if ishttp { sendtime := time.Now() //iphandler := packet.Layer(layers.LayerTypeIPv4) reqdetail := string(packet.ApplicationLayer().LayerContents()) httpinstance := &metrics.HttpTransaction{ Srcip: Srcaddr.IP, Srcport: Srcaddr.PORT, Destip: Destaddr.IP, Destport: Destaddr.PORT, Timesend: sendtime, Packetdetail: metrics.Packetdetail{Requestdetail: reqdetail, Responddetail: ""}, } //put the httpinstance into a list if glog.V(1) { glog.Infof("store the instance:%v\n", httpinstance) } httpinstancelist.PushBack(httpinstance) if glog.V(2) { glog.Infof("the length of the list :", httpinstancelist.Len()) } } }
// HandlePacketTmp used in development to display package data func (krb *krbAuth) HandlePacketTmp(packet gopacket.Packet) { app := packet.ApplicationLayer() if app == nil { return } udp := packet.TransportLayer().(*layers.UDP) if udp.DstPort == 88 { msgType := app.Payload()[17:18] if msgType[0] == 10 { // AS-REQ type = 10 var n kdcReq _, err := asn1.UnmarshalWithParams(app.Payload(), &n, asReqParam) if err != nil { fmt.Println("Error in asn.1 parse") fmt.Println(err) } else { fmt.Println("-------------------------------") fmt.Printf("PnDataType: %v\n", n.PnData[0].PnDataType) //fmt.Println(hex.Dump(n.Pdata[0].PdataValue)) var encData encryptedData asn1.Unmarshal(n.PnData[0].PnDataValue, &encData) fmt.Printf("Etype: %v\n", encData.Etype) fmt.Printf("Kvno: %v\n", encData.Kvno) //fmt.Println(hex.Dump(encData.Cipher)) //fmt.Println(len(encData.Cipher)) fmt.Printf("Cname: %v\n", n.ReqBody.Cname) fmt.Printf("Sname %v\n", n.ReqBody.Sname) fmt.Printf("Realm: %v\n", n.ReqBody.Realm) } } } }
func handlePacket(packet gopacket.Packet) { // Get the TCP layer from this packet tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer != nil { // Get actual TCP data from this layer tcp, _ := tcpLayer.(*layers.TCP) fmt.Printf("From: src port %6d\tTo: dst port %6d\t", tcp.SrcPort, tcp.DstPort) fmt.Printf("Ack: %12v\t", tcp.Ack) } // Iterate over all layers, printing out each layer type for _, layer := range packet.Layers() { layerType := layer.LayerType() fmt.Printf("%8v %5v", layerType, len(layer.LayerPayload())) } applicationLayer := packet.ApplicationLayer() if applicationLayer != nil { fmt.Println("Application layer/Payload found.") //fmt.Printf("%s\n", applicationLayer.Payload()) } fmt.Println("") }
func parseForSip(packet gopacket.Packet) *sipparser.SipMsg { ipLayer := packet.Layer(layers.LayerTypeIPv4) appLayer := packet.ApplicationLayer() fmt.Println("PAYLOAD: " + string(appLayer.Payload()) + " - END.") if ipLayer != nil && appLayer != nil && strings.Contains(string(appLayer.Payload()), "SIP") { return sipparser.ParseMsg(string(appLayer.Payload())) } return nil }
func SendPacket(packet gopacket.Packet, connectionWaitGroup *sync.WaitGroup, mongodHost string, mongodPort string) { // If packet contains a mongo message if packet.ApplicationLayer() != nil { payload := packet.ApplicationLayer().Payload() delta := GetPacketTime(packet).Sub(packetMinTimestamp) // Get timestamp's delta from first packet // Get mongo wire protocol payload mongoPacket := MongoPacket{ payload: payload, delta: delta, } transportLayer := packet.TransportLayer() networkLayer := packet.NetworkLayer() var srcIp string var srcPort string if networkLayer.LayerType() == layers.LayerTypeIPv4 { ip4header := networkLayer.LayerContents() // Convert binary to IP string srcIp = strconv.Itoa(int(ip4header[12])) + "." + strconv.Itoa(int(ip4header[13])) + "." + strconv.Itoa(int(ip4header[14])) + "." + strconv.Itoa(int(ip4header[15])) } if transportLayer.LayerType() == layers.LayerTypeTCP { tcpHeader := transportLayer.LayerContents() // Hack to be able to use convert what should be a uint16 to string tcpHeaderSrcPort := []byte{0, 0, tcpHeader[0], tcpHeader[1]} srcPort = strconv.Itoa(int(binary.BigEndian.Uint32(tcpHeaderSrcPort))) } src := srcIp + ":" + srcPort if mConnection, ok := mapHostConnection[src]; ok { mConnection.Send(mongoPacket) } else { connectionWaitGroup.Add(1) mConnection := NewMongoConnection(mongodHost, mongodPort, 100) mapHostConnection[src] = mConnection go mConnection.ExecuteConnection(connectionWaitGroup) mConnection.Send(mongoPacket) } } }
//detect the http packet return the info func detectHttp(packet gopacket.Packet) (bool, []byte) { applicationLayer := packet.ApplicationLayer() if applicationLayer != nil { if strings.Contains(string(applicationLayer.Payload()), "HTTP") { if glog.V(1) { glog.Info("HTTP found!") } return true, applicationLayer.LayerContents() } else { return false, nil } } else { return false, nil } }
func printPacketInfo(packet gopacket.Packet) { applicationLayer := packet.ApplicationLayer() if applicationLayer != nil { buff := []byte(applicationLayer.Payload()) p := rfc3164.NewParser(buff) err := p.Parse() if err != nil { fmt.Println("Error decoding Payload:", err) } fmt.Printf("%s", p.Dump()["content"]) } if err := packet.ErrorLayer(); err != nil { fmt.Println("Error decoding some part of the packet:", err) } }
// HandlePacket extract the krb5 AS-Requests func (krb *krbAuth) HandlePacket(packet gopacket.Packet) { app := packet.ApplicationLayer() if app == nil { return } udp := packet.TransportLayer().(*layers.UDP) if udp.DstPort == 88 { var n kdcReq _, err := asn1.UnmarshalWithParams(app.Payload(), &n, asReqParam) if err != nil { return } if n.MsgType == asRequestType { krb.addKdcReq(n) } } }
func (this *Sniff) handlePacket(packet gopacket.Packet) { ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer == nil { return } ip, _ := ipLayer.(*layers.IPv4) tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer == nil { return } tcp, _ := tcpLayer.(*layers.TCP) applicationLayer := packet.ApplicationLayer() if applicationLayer == nil { return } this.Ui.Info(fmt.Sprintf("%s:%s -> %s:%s %dB", ip.SrcIP, tcp.SrcPort, ip.DstIP, tcp.DstPort, len(applicationLayer.Payload()))) this.Ui.Output(fmt.Sprintf("%s", string(applicationLayer.Payload()))) }
// HandlePacket assemble the correct challenge with the response func (nt *ntlm) HandlePacket(packet gopacket.Packet) { app := packet.ApplicationLayer() if app == nil { return } nlen := len(app.Payload()) values := strings.Split(string(app.Payload()[:nlen]), "\r\n") for _, s := range values { if isNtlm(s) { baseStrings := strings.Split(s, " ") if len(baseStrings) != 3 { return } tcp := packet.TransportLayer().(*layers.TCP) if isChallenge(s) { nt.addServerResponse(tcp.Ack, baseStrings[2]) } else if isResponse(s) { nt.addClientResponse(tcp.Seq, baseStrings[2]) } } } }
// Extract the ftp login reposnses and requests func (ftp *ftpLogin) HandlePacket(packet gopacket.Packet) { app := packet.ApplicationLayer() if app == nil { return } n := len(app.Payload()) values := strings.Split(string(app.Payload()[:n]), "\r\n") for _, s := range values { if isFtp(s) { tcp := packet.TransportLayer().(*layers.TCP) if isUser(s) { ftp.user(tcp.Ack, strings.Split(s, " ")[1]) ftp.destination(tcp.Ack, destAndPort{ Destination: util.GetDstIP(packet), Port: tcp.DstPort, }) } else if isServer(s) { ftp.server(tcp.Seq, tcp.Ack) } else if isPass(s) { ftp.pass(tcp.Seq, strings.Split(s, " ")[1]) } } } }
func printPacketInfo(packet gopacket.Packet) { // Let's see if the packet is an ethernet packet ethernetLayer := packet.Layer(layers.LayerTypeEthernet) if ethernetLayer != nil { fmt.Println("Ethernet layer detected.") ethernetPacket, _ := ethernetLayer.(*layers.Ethernet) fmt.Println("Source MAC: ", ethernetPacket.SrcMAC) fmt.Println("Destination MAC: ", ethernetPacket.DstMAC) // Ethernet type is typically IPv4 but could be ARP or other fmt.Println("Ethernet type: ", ethernetPacket.EthernetType) fmt.Println() } // Let's see if the packet is IP (even though the ether type told us) ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer != nil { fmt.Println("IPv4 layer detected.") ip, _ := ipLayer.(*layers.IPv4) // IP layer variables: // Version (Either 4 or 6) // IHL (IP Header Length in 32-bit words) // TOS, Length, Id, Flags, FragOffset, TTL, Protocol (TCP?), // Checksum, SrcIP, DstIP fmt.Printf("From %s to %s\n", ip.SrcIP, ip.DstIP) fmt.Println("Protocol: ", ip.Protocol) fmt.Println() } // Let's see if the packet is TCP tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer != nil { fmt.Println("TCP layer detected.") tcp, _ := tcpLayer.(*layers.TCP) // TCP layer variables: // SrcPort, DstPort, Seq, Ack, DataOffset, Window, Checksum, Urgent // Bool flags: FIN, SYN, RST, PSH, ACK, URG, ECE, CWR, NS fmt.Printf("From port %d to %d\n", tcp.SrcPort, tcp.DstPort) fmt.Println("Sequence number: ", tcp.Seq) fmt.Println() } // Iterate over all layers, printing out each layer type fmt.Println("All packet layers:") for _, layer := range packet.Layers() { fmt.Println("- ", layer.LayerType()) } // When iterating through packet.Layers() above, // if it lists Payload layer then that is the same as // this applicationLayer. applicationLayer contains the payload applicationLayer := packet.ApplicationLayer() if applicationLayer != nil { fmt.Println("Application layer/Payload found.") fmt.Printf("%s\n", applicationLayer.Payload()) // Search for a string inside the payload if strings.Contains(string(applicationLayer.Payload()), "HTTP") { fmt.Println("HTTP found!") } } // Check for errors if err := packet.ErrorLayer(); err != nil { fmt.Println("Error decoding some part of the packet:", err) } }
func gatherPacketLayersInfo(event common.MapStr, packet gopacket.Packet) { // see https://godoc.org/github.com/google/gopacket#hdr-Pointers_To_Known_Layers // Pointers To Known Layers: // During decoding, certain layers are stored in the packet as well-known layer types. // For example, IPv4 and IPv6 are both considered NetworkLayer layers, // while TCP and UDP are both TransportLayer layers. // We support 4 layers, corresponding to the 4 layers of the TCP/IP layering scheme // (roughly anagalous to layers 2, 3, 4, and 7 of the OSI model). // To access these, you can use the: // packet.LinkLayer, // packet.NetworkLayer, // packet.TransportLayer, and // packet.ApplicationLayer functions. // Each of these functions returns a corresponding interface (gopacket.{Link,Network,Transport,Application}Layer). // The first three provide methods for getting src/dst addresses for that particular layer, // while the final layer provides a Payload function to get payload data. // use "packet.Dump()" as a fail-safe to capture all available layers for a packet, // just in case we encounter something unexpected in the unified2 file or we // have neglected to handle a particular layer explicitly event["packet_dump"] = packet.Dump() // "packet.Dump()" is very verbose, i.e. a large amount of text, but that's ok // capture the name of the layers found var packet_layers []string for _, layer := range packet.Layers() { packet_layers = append(packet_layers, fmt.Sprintf("%v", layer.LayerType())) } event["packet_layers"] = packet_layers // Ethernet layer? ethernetLayer := packet.Layer(layers.LayerTypeEthernet) if ethernetLayer != nil { ethernetPacket, _ := ethernetLayer.(*layers.Ethernet) event["ethernet_src_mac"] = fmt.Sprintf("%v", ethernetPacket.SrcMAC) event["ethernet_dst_mac"] = fmt.Sprintf("%v", ethernetPacket.DstMAC) // ethernet type is typically IPv4 but could be ARP or other event["ethernet_type"] = fmt.Sprintf("%v", ethernetPacket.EthernetType) // Length is only set if a length field exists within this header. Ethernet // headers follow two different standards, one that uses an EthernetType, the // other which defines a length the follows with a LLC header (802.3). If the // former is the case, we set EthernetType and Length stays 0. In the latter // case, we set Length and EthernetType = EthernetTypeLLC. event["ethernet_length"] = fmt.Sprintf("%v", ethernetPacket.Length) } // IPv4 layer? ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer != nil { ip, _ := ipLayer.(*layers.IPv4) event["ip_version"] = ip.Version event["ip_ihl"] = ip.IHL event["ip_tos"] = ip.TOS event["ip_length"] = ip.Length event["ip_id"] = ip.Id event["ip_flags"] = ip.Flags event["ip_fragoffset"] = ip.FragOffset event["ip_ttl"] = ip.TTL event["ip_protocol"] = ip.Protocol event["ip_checksum"] = ip.Checksum event["ip_src_ip"] = ip.SrcIP event["ip_dst_ip"] = ip.DstIP event["ip_options"] = ip.Options // maybe? fmt.Sprintf("%v", ip.Options) event["ip_padding"] = ip.Padding } // IPv6 layer? ip6Layer := packet.Layer(layers.LayerTypeIPv6) if ip6Layer != nil { ip6, _ := ip6Layer.(*layers.IPv6) event["ip6_version"] = ip6.Version event["ip6_trafficclass"] = ip6.TrafficClass event["ip6_flowlabel"] = ip6.FlowLabel event["ip6_length"] = ip6.Length event["ip6_nextheader"] = ip6.NextHeader event["ip6_hoplimit"] = ip6.HopLimit event["ip6_src_ip"] = ip6.SrcIP event["ip6_dst_ip"] = ip6.DstIP event["ip6_hopbyhop"] = ip6.HopByHop } // see: gopacket/layers folder ... what layers are needed for Snort/Suricata alerts? // ICMPv4 layer? // ICMPv6 layer? // ARP layer? // UDP layer? udpLayer := packet.Layer(layers.LayerTypeUDP) if udpLayer != nil { udp, _ := udpLayer.(*layers.UDP) event["udp_src_port"] = udp.SrcPort event["udp_dst_port"] = udp.DstPort event["udp_length"] = udp.Length event["udp_checksum"] = udp.Checksum } // TCP layer? tcpLayer := packet.Layer(layers.LayerTypeTCP) if tcpLayer != nil { tcp, _ := tcpLayer.(*layers.TCP) event["tcp_src_port"] = tcp.SrcPort event["tcp_dst_port"] = tcp.DstPort event["tcp_seq"] = tcp.Seq event["tcp_ack"] = tcp.Ack event["tcp_data_offset"] = tcp.DataOffset event["tcp_fin"] = tcp.FIN event["tcp_syn"] = tcp.SYN event["tcp_rst"] = tcp.RST event["tcp_psh"] = tcp.PSH event["tcp_ack"] = tcp.ACK event["tcp_urg"] = tcp.URG event["tcp_ece"] = tcp.ECE event["tcp_cwr"] = tcp.CWR event["tcp_ns"] = tcp.NS event["tcp_window"] = tcp.Window event["tcp_checksum"] = tcp.Checksum event["tcp_urgent"] = tcp.Urgent event["tcp_options"] = tcp.Options // maybe? fmt.Sprintf("%v", tcp.Options) event["tcp_padding"] = tcp.Padding } // note: the Payload layer is the same as this applicationLayer // also, we can get payloads for all packets regardless of their underlying data type: // application layer? (aka packet payload) applicationLayer := packet.ApplicationLayer() if applicationLayer != nil { event["packet_payload"] = fmt.Sprintf("%s", applicationLayer.Payload()) } // errors? if err := packet.ErrorLayer(); err != nil { event["packet_error"] = fmt.Sprintf("Packet decoding error: %v", err) } }