// 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 (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 }
// IsUdpPacket returns true if the packet is of UDP type func IsUdpPacket(packet gopacket.Packet) bool { if packet == nil { return false } if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeUDP { return false } return true }
func main() { flag.Usage = usage flag.Parse() pcapfile, err := openPcap() if err != nil { glog.Fatalf("%v", err) } bpf := strings.Join(flag.Args(), " ") if err = pcapfile.SetBPFFilter(bpf); err != nil { glog.Fatalf("unable to set BPF: %v", err) } // "Pass this stream factory to an tcpassembly.StreamPool , // start up an tcpassembly.Assembler, and you're good to go!" done := make(chan struct{}) results := make(chan string) go printResults(done, results) wg := &sync.WaitGroup{} rtmp := &rtmpStreamWrapper{wg, results} pool := tcpassembly.NewStreamPool(rtmp) asm := tcpassembly.NewAssembler(pool) asm.MaxBufferedPagesTotal = 4096 // limit gopacket memory allocation source := gopacket.NewPacketSource(pcapfile, pcapfile.LinkType()) var pkt gopacket.Packet for { pkt, err = source.NextPacket() if pkt == nil || err != nil { break } if tcp := pkt.Layer(layers.LayerTypeTCP); tcp != nil { asm.AssembleWithTimestamp( pkt.TransportLayer().TransportFlow(), tcp.(*layers.TCP), pkt.Metadata().Timestamp) } } if err != nil && !errIsEOF(err) { glog.Errorf("packet: %v", err) if err = pcapfile.Error(); err != nil { glog.Errorf("pcap: %v", err) } } asm.FlushAll() // abort any in progress tcp connections wg.Wait() // tcp streams have finished processing close(results) // no more results will be generated by tcp streams <-done // printResults has finished }
func (p *processor) getFlow(pkt gopacket.Packet) gopacket.Flow { mu := moldudp64Layer(pkt) //p.flowBufSrc.Reset() //p.flowBufSrc.Write(pkt.NetworkLayer().NetworkFlow().Src().Raw()) //p.flowBufSrc.Write(pkt.TransportLayer().TransportFlow().Src().Raw()) //p.flowBufSrc.Write(mu.Flow().Src().Raw()) p.flowBufDst.Reset() p.flowBufDst.Write(pkt.NetworkLayer().NetworkFlow().Dst().Raw()) p.flowBufDst.Write(pkt.TransportLayer().TransportFlow().Dst().Raw()) p.flowBufDst.Write(mu.Flow().Dst().Raw()) return gopacket.NewFlow(packet.EndpointCombinedSession, p.flowBufSrc.Bytes(), p.flowBufDst.Bytes()) }
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) } } }
func (b *Benchmark) decodePacket(pkt gopacket.Packet) (key *FiveTuple, payload []byte) { ipv4, ok := pkt.NetworkLayer().(*layers.IPv4) if !ok { return // Ignore packets that aren't IPv4 } if ipv4.FragOffset != 0 || (ipv4.Flags&layers.IPv4MoreFragments) != 0 { return // Ignore fragmented packets. } var stream FiveTuple stream.protocol = ipv4.Protocol stream.srcAddr = ipv4.SrcIP stream.dstAddr = ipv4.DstIP switch t := pkt.TransportLayer().(type) { case *layers.TCP: stream.srcPort = uint16(t.SrcPort) stream.dstPort = uint16(t.DstPort) return &stream, t.Payload case *layers.UDP: stream.srcPort = uint16(t.SrcPort) stream.dstPort = uint16(t.DstPort) return &stream, t.Payload } return }
// 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) } } }
// 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]) } } } }
// Handle reads the pcap file into assembled packets for the streamHandler func (p *PacketHandler) Handle(streamHandler StreamHandler, numToHandle int) error { count := int64(0) start := time.Now() if p.Verbose && numToHandle > 0 { userInfoLogger.Logvf(Always, "Processing", numToHandle, "packets") } source := gopacket.NewPacketSource(p.pcap, p.pcap.LinkType()) streamPool := NewStreamPool(streamHandler) assembler := NewAssembler(streamPool) defer func() { if userInfoLogger.isInVerbosity(DebugLow) { userInfoLogger.Logv(DebugLow, "flushing assembler.") userInfoLogger.Logvf(DebugLow, "num flushed/closed: %v", assembler.FlushAll()) userInfoLogger.Logv(DebugLow, "closing stream handler.") } else { assembler.FlushAll() } streamHandler.Close() }() defer func() { if userInfoLogger.isInVerbosity(DebugLow) { userInfoLogger.Logvf(DebugLow, "Dropped %v packets out of %v", p.numDropped, count) runTime := float64(time.Now().Sub(start)) / float64(time.Second) userInfoLogger.Logvf(DebugLow, "Processed %v packets per second", float64(count-p.numDropped)/runTime) } }() ticker := time.Tick(time.Second * 1) var pkt gopacket.Packet var pktCount uint for { select { case pkt = <-source.Packets(): pktCount++ if pkt == nil { // end of pcap file userInfoLogger.Logv(DebugLow, "Reached end of stream") return nil } if tcpLayer := pkt.Layer(layers.LayerTypeTCP); tcpLayer != nil { userInfoLogger.Logv(DebugHigh, "Assembling TCP layer") assembler.AssembleWithTimestamp( pkt.TransportLayer().TransportFlow(), tcpLayer.(*layers.TCP), pkt.Metadata().Timestamp) // TODO: use time.Now() here when running in realtime mode } if count == 0 { if firstSeener, ok := streamHandler.(SetFirstSeener); ok { firstSeener.SetFirstSeen(pkt.Metadata().Timestamp) } } count++ if numToHandle > 0 && count >= int64(numToHandle) { userInfoLogger.Logv(DebugLow, "Count exceeds requested packets, returning.") break } select { case <-ticker: bookkeep(pktCount, pkt, assembler) default: } case <-ticker: bookkeep(pktCount, pkt, assembler) case <-p.stop: return nil } } }