func forgeEthIPTCP(t *testing.T, seed int64) *gopacket.Packet { var options gopacket.SerializeOptions rnd := rand.New(rand.NewSource(seed)) rawBytes := []byte{10, 20, 30} ethernetLayer := &layers.Ethernet{ SrcMAC: net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))}, DstMAC: net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD}, } ipLayer := &layers.IPv4{ SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))}, DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8}, } tcpLayer := &layers.TCP{ SrcPort: layers.TCPPort(byte(rnd.Intn(0x10000))), DstPort: layers.TCPPort(byte(rnd.Intn(0x10000))), } // And create the packet with the layers buffer := gopacket.NewSerializeBuffer() err := gopacket.SerializeLayers(buffer, options, ethernetLayer, ipLayer, tcpLayer, gopacket.Payload(rawBytes), ) if err != nil { t.Fail() } gpacket := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default) return &gpacket }
/* protos must contain a UDP or TCP layer on top of IPv4 */ func forgeTestPacket(t *testing.T, seed int64, protos ...ProtocolType) *gopacket.Packet { rnd := rand.New(rand.NewSource(seed)) rawBytes := []byte{10, 20, 30} var protoStack []gopacket.SerializableLayer for i, proto := range protos { switch proto { case ETH: ethernetLayer := &layers.Ethernet{ SrcMAC: net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))}, DstMAC: net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD}, EthernetType: layers.EthernetTypeIPv4, } protoStack = append(protoStack, ethernetLayer) case IPv4: ipv4Layer := &layers.IPv4{ SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))}, DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8}, } switch protos[i+1] { case TCP: ipv4Layer.Protocol = layers.IPProtocolTCP case UDP: ipv4Layer.Protocol = layers.IPProtocolUDP } protoStack = append(protoStack, ipv4Layer) case TCP: tcpLayer := &layers.TCP{ SrcPort: layers.TCPPort(byte(rnd.Intn(0x10000))), DstPort: layers.TCPPort(byte(rnd.Intn(0x10000))), } protoStack = append(protoStack, tcpLayer) case UDP: udpLayer := &layers.UDP{ SrcPort: layers.UDPPort(byte(rnd.Intn(0x10000))), DstPort: layers.UDPPort(byte(rnd.Intn(0x10000))), } protoStack = append(protoStack, udpLayer) default: t.Log("forgeTestPacket : Unsupported protocol ", proto) } } protoStack = append(protoStack, gopacket.Payload(rawBytes)) buffer := gopacket.NewSerializeBuffer() options := gopacket.SerializeOptions{FixLengths: true} err := gopacket.SerializeLayers(buffer, options, protoStack...) if err != nil { t.Fail() } gpacket := gopacket.NewPacket(buffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default) return &gpacket }
func (fl *FlowLayer) Hash() []byte { if fl == nil { return []byte{} } if fl.Protocol == FlowProtocol_ETHERNET { amac, err := net.ParseMAC(fl.A) if err != nil { panic(err) } bmac, err := net.ParseMAC(fl.B) if err != nil { panic(err) } return HashFromValues(amac, bmac) } if fl.Protocol == FlowProtocol_IPV4 || fl.Protocol == FlowProtocol_IPV6 { aip := net.ParseIP(fl.A) bip := net.ParseIP(fl.B) return HashFromValues(aip, bip) } if fl.Protocol == FlowProtocol_TCPPORT { aTCPPort, err := strconv.ParseUint(fl.A, 10, 16) if err != nil { panic(err) } bTCPPort, err := strconv.ParseUint(fl.B, 10, 16) if err != nil { panic(err) } return HashFromValues(layers.TCPPort(aTCPPort), layers.TCPPort(bTCPPort)) } if fl.Protocol == FlowProtocol_UDPPORT { aUDPPort, err := strconv.ParseUint(fl.A, 10, 16) if err != nil { panic(err) } bUDPPort, err := strconv.ParseUint(fl.B, 10, 16) if err != nil { panic(err) } return HashFromValues(layers.UDPPort(aUDPPort), layers.UDPPort(bUDPPort)) } if fl.Protocol == FlowProtocol_SCTPPORT { aSCTPPort, err := strconv.ParseUint(fl.A, 10, 16) if err != nil { panic(err) } bSCTPPort, err := strconv.ParseUint(fl.B, 10, 16) if err != nil { panic(err) } return HashFromValues(layers.SCTPPort(aSCTPPort), layers.SCTPPort(bSCTPPort)) } return nil }
func main() { // Open device handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout) if err != nil { log.Fatal(err) } defer handle.Close() // Send raw bytes over wire rawBytes := []byte{10, 20, 30} err = handle.WritePacketData(rawBytes) if err != nil { log.Fatal(err) } // Create a properly formed packet, just with // empty details. Should fill out MAC addresses, // IP addresses, etc. buffer = gopacket.NewSerializeBuffer() gopacket.SerializeLayers(buffer, options, &layers.Ethernet{}, &layers.IPv4{}, &layers.TCP{}, gopacket.Payload(rawBytes), ) outgoingPacket := buffer.Bytes() // Send our packet err = handle.WritePacketData(outgoingPacket) if err != nil { log.Fatal(err) } // This time lets fill out some information ipLayer := &layers.IPv4{ SrcIP: net.IP{127, 0, 0, 1}, DstIP: net.IP{8, 8, 8, 8}, } ethernetLayer := &layers.Ethernet{ SrcMAC: net.HardwareAddr{0xFF, 0xAA, 0xFA, 0xAA, 0xFF, 0xAA, 0xFA, 0xAA}, DstMAC: net.HardwareAddr{0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD}, } tcpLayer := &layers.TCP{ SrcPort: layers.TCPPort(4321), DstPort: layers.TCPPort(80), } // And create the packet with the layers buffer = gopacket.NewSerializeBuffer() gopacket.SerializeLayers(buffer, options, ethernetLayer, ipLayer, tcpLayer, gopacket.Payload(rawBytes), ) outgoingPacket = buffer.Bytes() }
func packet(raddr net.IP) []byte { ip := &layers.IPv4{ Version: 0x4, TOS: 0x0, TTL: 0x40, Protocol: layers.IPProtocolTCP, SrcIP: net.ParseIP(os.Args[2]), DstIP: raddr, WithRawINETSocket: true, } rand.Seed(time.Now().UnixNano()) tcp := &layers.TCP{ SrcPort: layers.TCPPort(rand.Uint32()), DstPort: 0x50, Seq: rand.Uint32(), DataOffset: 0x5, SYN: true, Window: 0xaaaa, } tcp.SetNetworkLayerForChecksum(ip) buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{true, true} check(gopacket.SerializeLayers(buf, opts, ip, tcp)) return buf.Bytes() }
func TestPcapLogger(t *testing.T) { ipFlow, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) flow := types.NewTcpIpFlowFromFlows(ipFlow, tcpFlow) pcapLogger := NewPcapLogger("fake-dir", flow) testWriter := NewTestPcapWriter() pcapLogger.fileWriter = testWriter pcapLogger.Start() // test pcap header want := []byte("\xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00") if !bytes.Equal(testWriter.lastWrite, want) { t.Errorf("pcap header is wrong") t.Fail() } // test pcap packet rawPacket := makeTestPacket() testWriter.lastWrite = make([]byte, 0) pcapLogger.WritePacket(rawPacket, time.Now()) if !bytes.Equal(testWriter.lastWrite, rawPacket) { t.Errorf("pcap packet is wrong") t.Fail() } pcapLogger.Stop() }
// PrepareLayerCake prepares a delicious and fluffy protocol layer cake suitable for hackers. func (s *SloppyTrace) PrepareLayerCake() (*layers.IPv4, *layers.TCP) { ipLayer := layers.IPv4{ SrcIP: s.SrcIP, DstIP: s.DstIP, Protocol: layers.IPProtocolTCP, } tcpLayer := layers.TCP{ SrcPort: layers.TCPPort(s.SrcPort), DstPort: layers.TCPPort(s.DstPort), // XXX todo: make configurable ACK: true, PSH: true, } return &ipLayer, &tcpLayer }
func TestFlowString(t *testing.T) { ipFlow, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) tcpIpFlow := NewTcpIpFlowFromFlows(ipFlow, tcpFlow) if !strings.EqualFold("1.2.3.4:1-2.3.4.5:2", tcpIpFlow.String()) { t.Error("TcpIpFlow.String() fail") t.Fail() } }
func main() { // Open device handle, err = pcap.OpenLive(device, snapshot_len, promiscuous, timeout) if err != nil { log.Fatal(err) } defer handle.Close() // Create the layers ethernetLayer := &layers.Ethernet{ SrcMAC: net.HardwareAddr{0xFF, 0xAA, 0xFA, 0xAA, 0xFF, 0xAA}, DstMAC: net.HardwareAddr{0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD}, EthernetType: layers.EthernetTypeIPv4, } ipLayer := &layers.IPv4{ SrcIP: net.IP{192, 168, 1, 3}, DstIP: net.IP{8, 8, 8, 8}, Version: 4, IHL: 5, // 20 bytes standard header size Length: 24, } tcpLayer := &layers.TCP{ SrcPort: layers.TCPPort(4321), DstPort: layers.TCPPort(80), } payload := []byte{10, 20, 30, 40} // Serialize the layers buffer = gopacket.NewSerializeBuffer() gopacket.SerializeLayers(buffer, options, ethernetLayer, ipLayer, tcpLayer, gopacket.Payload(payload), ) outgoingPacket := buffer.Bytes() // Send packet over the wire (or air) err = handle.WritePacketData(outgoingPacket) if err != nil { log.Fatal(err) } }
func TestFlows(t *testing.T) { ipFlow, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) tcpIpFlow := NewTcpIpFlowFromFlows(ipFlow, tcpFlow) ipFlow2, tcpFlow2 := tcpIpFlow.Flows() if ipFlow2 != ipFlow || tcpFlow2 != tcpFlow { t.Error("Flows method fail") t.Fail() } }
func TestFlowEqual(t *testing.T) { ipFlow1, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow1, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) flow1 := NewTcpIpFlowFromFlows(ipFlow1, tcpFlow1) ipFlow2, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow2, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) flow2 := NewTcpIpFlowFromFlows(ipFlow2, tcpFlow2) if !flow1.Equal(flow2) { t.Error("TcpIpFlow.Equal fail") t.Fail() } ipFlow3, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(8, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow3, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) flow3 := NewTcpIpFlowFromFlows(ipFlow3, tcpFlow3) if flow1.Equal(flow3) { t.Error("TcpIpFlow.Equal fail") t.Fail() } }
func BenchmarkMultiStreamGrow(b *testing.B) { t := layers.TCP{ SrcPort: 1, DstPort: 2, Seq: 0, BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}}, } a := NewAssembler(NewStreamPool(&testFactory{})) for i := 0; i < b.N; i++ { t.SrcPort = layers.TCPPort(i) a.Assemble(netFlow, &t) t.Seq += 10 } }
func TestGetOverlapRingsWithZeroRings(t *testing.T) { ip := layers.IPv4{ SrcIP: net.IP{1, 2, 3, 4}, DstIP: net.IP{2, 3, 4, 5}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp := layers.TCP{ SYN: true, SrcPort: 1, DstPort: 2, } tcp.SetNetworkLayerForChecksum(&ip) payload := gopacket.Payload([]byte{1, 2, 3, 4}) p := types.PacketManifest{ IP: ip, TCP: tcp, Payload: payload, } options := ConnectionOptions{ MaxBufferedPagesTotal: 0, MaxBufferedPagesPerConnection: 0, MaxRingPackets: 40, PageCache: nil, LogDir: "fake-log-dir", } f := &DefaultConnFactory{} conn := f.Build(options).(*Connection) ipFlow, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) serverFlow := types.NewTcpIpFlowFromFlows(ipFlow, tcpFlow) clientFlow := serverFlow.Reverse() conn.serverFlow = serverFlow conn.clientFlow = clientFlow head, tail := getOverlapRings(&p, serverFlow, conn.ClientStreamRing) if head == nil || tail == nil { return } else { t.Fail() } return }
func ianaPort(layerType gopacket.LayerType, port uint16) string { if layerType == layers.LayerTypeTCP { proto, in := layers.TCPPortNames[layers.TCPPort(port)] if in { return fmt.Sprintf("%s (TCP)", proto) } else { return "N/A (TCP)" } } else { proto, in := layers.UDPPortNames[layers.UDPPort(port)] if in { return fmt.Sprintf("%s (UDP)", proto) } else { return "N/A (UDP)" } } }
func TestOrderedCoalesceUsedPages(t *testing.T) { maxBufferedPagesTotal := 1024 maxBufferedPagesPerFlow := 1024 streamRing := types.NewRing(40) PageCache := newPageCache() ipFlow, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) flow := types.NewTcpIpFlowFromFlows(ipFlow, tcpFlow) var nextSeq types.Sequence = types.Sequence(1) coalesce := NewOrderedCoalesce(nil, flow, PageCache, streamRing, maxBufferedPagesTotal, maxBufferedPagesPerFlow, false) ip := layers.IPv4{ SrcIP: net.IP{1, 2, 3, 4}, DstIP: net.IP{2, 3, 4, 5}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp := layers.TCP{ Seq: 3, SYN: false, SrcPort: 1, DstPort: 2, } p := types.PacketManifest{ Timestamp: time.Now(), Flow: flow, IP: ip, TCP: tcp, Payload: []byte{1, 2, 3, 4, 5, 6, 7}, } coalesce.insert(&p, nextSeq) if coalesce.PageCache.used != 1 { t.Errorf("coalesce.pager.Used() not equal to 1\n") t.Fail() } coalesce.Close() }
func BenchmarkMultiStreamConn(b *testing.B) { t := layers.TCP{ SrcPort: 1, DstPort: 2, Seq: 0, SYN: true, BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}}, } a := NewAssembler(NewStreamPool(&testFactory{})) for i := 0; i < b.N; i++ { t.SrcPort = layers.TCPPort(i) a.Assemble(netFlow, &t) if i%65536 == 65535 { if t.SYN { t.SYN = false t.Seq += 1 } t.Seq += 10 } } }
func TestNewTcpIpFlowFromPacket(t *testing.T) { buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } ip := layers.IPv4{ SrcIP: net.IP{1, 2, 3, 4}, DstIP: net.IP{2, 3, 4, 5}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp := layers.TCP{ SYN: true, SrcPort: 1, DstPort: 2, Seq: 123, BaseLayer: layers.BaseLayer{Payload: []byte{1, 2, 3}}, } tcp.SetNetworkLayerForChecksum(&ip) gopacket.SerializeLayers(buf, opts, &ip, &tcp) packetData := buf.Bytes() flow1, err := NewTcpIpFlowFromPacket(packetData) ipFlow2, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow2, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) flow2 := NewTcpIpFlowFromFlows(ipFlow2, tcpFlow2) if err != nil && !flow2.Equal(flow1) { t.Error("NewTcpIpFlowFromPacket fail") t.Fail() } flow1, err = NewTcpIpFlowFromPacket([]byte{1, 2, 3, 4, 5, 6, 7}) if err == nil || !flow1.Equal(&TcpIpFlow{}) { t.Error("NewTcpIpFlowFromPacket fail") t.Fail() } }
func TestGetOverlapBytes(t *testing.T) { overlapBytesTests := []struct { in reassemblyInput want TestOverlapBytesWant }{ { //0 reassemblyInput{3, []byte{2, 3, 4}}, TestOverlapBytesWant{ bytes: []byte{6}, startOffset: 2, endOffset: 3, }, }, { //1 reassemblyInput{4, []byte{2, 3, 4}}, TestOverlapBytesWant{ bytes: []byte{6, 7}, startOffset: 1, endOffset: 3, }, }, { //2 reassemblyInput{5, []byte{2, 3, 4}}, TestOverlapBytesWant{ bytes: []byte{6, 7, 8}, startOffset: 0, endOffset: 3, }, }, { //3 reassemblyInput{6, []byte{1, 2, 3}}, TestOverlapBytesWant{ bytes: []byte{7, 8, 9}, startOffset: 0, endOffset: 3, }, }, { //4 reassemblyInput{4, []byte{91, 92, 93, 94, 95, 96, 97}}, TestOverlapBytesWant{ bytes: []byte{6, 7, 8, 9, 10, 11}, startOffset: 1, endOffset: 7, }, }, { reassemblyInput{4, []byte{91, 92, 93, 94, 95, 96, 97, 98}}, TestOverlapBytesWant{ bytes: []byte{6, 7, 8, 9, 10, 11, 12}, startOffset: 1, endOffset: 8, }, }, { reassemblyInput{4, []byte{91, 92, 93, 94, 95, 96, 97, 98, 99}}, TestOverlapBytesWant{ bytes: []byte{6, 7, 8, 9, 10, 11, 12, 13}, startOffset: 1, endOffset: 9, }, }, { reassemblyInput{3, []byte{1, 2, 3, 4, 5, 6, 7}}, TestOverlapBytesWant{ bytes: []byte{6, 7, 8, 9, 10}, startOffset: 2, endOffset: 7, }, }, { reassemblyInput{34, []byte{1, 2, 3, 4, 5, 6, 7}}, TestOverlapBytesWant{ bytes: []byte{35, 36, 37, 38, 39, 40}, startOffset: 0, endOffset: 6, }, }, { reassemblyInput{34, []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}, TestOverlapBytesWant{ bytes: []byte{35, 36, 37, 38, 39, 40}, startOffset: 0, endOffset: 6, }, }, { reassemblyInput{5, []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, TestOverlapBytesWant{ bytes: []byte{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}, startOffset: 0, endOffset: 35, }, }, { reassemblyInput{5, []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}, TestOverlapBytesWant{ bytes: []byte{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}, startOffset: 0, endOffset: 35, }, }, { reassemblyInput{5, []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}, TestOverlapBytesWant{ bytes: []byte{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}, startOffset: 0, endOffset: 35, }, }, { reassemblyInput{4, []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, TestOverlapBytesWant{ bytes: []byte{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}, startOffset: 1, endOffset: 36, }, }, { reassemblyInput{3, []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, TestOverlapBytesWant{ bytes: []byte{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}, startOffset: 2, endOffset: 37, }, }, { reassemblyInput{4, []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}, TestOverlapBytesWant{ bytes: []byte{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}, startOffset: 1, endOffset: 36, }, }, } options := ConnectionOptions{ MaxBufferedPagesTotal: 0, MaxBufferedPagesPerConnection: 0, MaxRingPackets: 40, PageCache: nil, LogDir: "fake-log-dir", } f := &DefaultConnFactory{} conn := f.Build(options).(*Connection) for j := 5; j < 40; j += 5 { reassembly := types.Reassembly{ Seq: types.Sequence(j), Bytes: []byte{byte(j + 1), byte(j + 2), byte(j + 3), byte(j + 4), byte(j + 5)}, } conn.ClientStreamRing.Reassembly = &reassembly conn.ClientStreamRing = conn.ClientStreamRing.Next() } for i := 0; i < len(overlapBytesTests); i++ { var startSeq uint32 = overlapBytesTests[i].in.Seq start := types.Sequence(startSeq) end := start.Add(len(overlapBytesTests[i].in.Payload) - 1) p := types.PacketManifest{ IP: layers.IPv4{ SrcIP: net.IP{1, 2, 3, 4}, DstIP: net.IP{2, 3, 4, 5}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, }, TCP: layers.TCP{ Seq: startSeq, SrcPort: 1, DstPort: 2, }, Payload: overlapBytesTests[i].in.Payload, } ipFlow, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) serverFlow := types.NewTcpIpFlowFromFlows(ipFlow, tcpFlow) clientFlow := serverFlow.Reverse() conn.serverFlow = serverFlow conn.clientFlow = clientFlow head, tail := getOverlapRings(&p, serverFlow, conn.ClientStreamRing) if head == nil || tail == nil { t.Errorf("%d getOverlapRings returned a nil\n", i) t.Fail() continue } log.Printf("test #%d", i) overlapBytes, startOffset, endOffset := getOverlapBytes(head, tail, start, end) if startOffset != overlapBytesTests[i].want.startOffset { t.Errorf("test %d startOffset %d does not match want.startOffset %d\n", i, startOffset, overlapBytesTests[i].want.startOffset) t.Fail() } if endOffset != overlapBytesTests[i].want.endOffset { t.Errorf("test %d endOffset %d does not match want.endOffset %d\n", i, endOffset, overlapBytesTests[i].want.endOffset) t.Fail() } if len(overlapBytes) != len(overlapBytesTests[i].want.bytes) { t.Errorf("test %d overlapBytes len %d not equal to want.bytes len %d\n", i, len(overlapBytes), len(overlapBytesTests[i].want.bytes)) t.Fail() } if !bytes.Equal(overlapBytes, overlapBytesTests[i].want.bytes) { t.Errorf("test %d overlapBytes %x not equal to want.bytes %x\n", i, overlapBytes, overlapBytesTests[i].want.bytes) t.Fail() } } }
func TestGetOverlapRings(t *testing.T) { overlapTests := []struct { in reassemblyInput want []*types.Reassembly }{ { reassemblyInput{7, []byte{1, 2}}, []*types.Reassembly{ { Seq: 5, }, { Seq: 5, }, }, }, { reassemblyInput{7, []byte{6, 7}}, []*types.Reassembly{ { Seq: 5, }, { Seq: 5, }, }, }, { reassemblyInput{5, []byte{1, 2, 3, 4, 5}}, []*types.Reassembly{ { Seq: 5, }, { Seq: 5, }, }, }, { reassemblyInput{5, []byte{1, 2, 3, 4, 5, 6}}, []*types.Reassembly{ { Seq: 5, }, { Seq: 10, }, }, }, { reassemblyInput{6, []byte{1, 2, 3, 4, 5}}, []*types.Reassembly{ { Seq: 5, }, { Seq: 10, }, }, }, { reassemblyInput{7, []byte{1, 2, 3, 4, 5}}, []*types.Reassembly{ { Seq: 5, }, { Seq: 10, }, }, }, { reassemblyInput{32, []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}, []*types.Reassembly{ { Seq: 30, }, { Seq: 35, }, }, }, { reassemblyInput{0, []byte{1, 2, 3}}, []*types.Reassembly{ nil, nil, }, }, { reassemblyInput{0, []byte{1, 2, 3, 4, 5, 6, 7, 8}}, []*types.Reassembly{ { Seq: 5, }, { Seq: 5, }, }, }, { reassemblyInput{0, []byte{1, 2, 3, 4, 5, 6}}, []*types.Reassembly{ { Seq: 5, }, { Seq: 5, }, }, }, { reassemblyInput{0, []byte{1, 2, 3}}, []*types.Reassembly{ nil, nil, }, }, { reassemblyInput{0, []byte{1, 2, 3, 4, 5}}, []*types.Reassembly{ nil, nil, }, }, { reassemblyInput{0, []byte{1, 2, 3, 4, 5, 6}}, []*types.Reassembly{ { Seq: 5, }, { Seq: 5, }, }, }, { reassemblyInput{40, []byte{1}}, []*types.Reassembly{ nil, nil, }, }, { reassemblyInput{42, []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}, []*types.Reassembly{ nil, nil, }, }, { reassemblyInput{38, []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}, []*types.Reassembly{ { Seq: 35, }, { Seq: 35, }, }, }, } ip := layers.IPv4{ SrcIP: net.IP{1, 2, 3, 4}, DstIP: net.IP{2, 3, 4, 5}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } options := ConnectionOptions{ MaxBufferedPagesTotal: 0, MaxBufferedPagesPerConnection: 0, MaxRingPackets: 40, PageCache: nil, LogDir: "fake-log-dir", } f := &DefaultConnFactory{} conn := f.Build(options).(*Connection) for j := 5; j < 40; j += 5 { reassembly := types.Reassembly{ Skip: 0, Seq: types.Sequence(j), Bytes: []byte{1, 2, 3, 4, 5}, } conn.ClientStreamRing.Reassembly = &reassembly conn.ClientStreamRing = conn.ClientStreamRing.Next() } for i := 0; i < len(overlapTests); i++ { log.Printf("test # %d", i) tcp := layers.TCP{ Seq: overlapTests[i].in.Seq, SYN: false, SrcPort: 1, DstPort: 2, } p := types.PacketManifest{ IP: ip, TCP: tcp, Payload: overlapTests[i].in.Payload, } ipFlow, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) serverFlow := types.NewTcpIpFlowFromFlows(ipFlow, tcpFlow) clientFlow := serverFlow.Reverse() conn.serverFlow = serverFlow conn.clientFlow = clientFlow head, tail := getOverlapRings(&p, serverFlow, conn.ClientStreamRing) log.Printf("head %v tail %v", head, tail) log.Printf("want %v", overlapTests[i].want[0]) if overlapTests[i].want[0] == nil { log.Print("want nil results") if head != nil { t.Error("getOverlapRings did not return a nil ring segment head\n") t.Fail() } if tail != nil { t.Error("getOverlapRings did not return a nil ring segment tail\n") t.Fail() } } else { if overlapTests[i].want[0] != nil { if head == nil || tail == nil { t.Error("head or tail is nil\n") t.Fail() } } if overlapTests[i].want[0] != nil { if head.Reassembly.Seq.Difference(overlapTests[i].want[0].Seq) != 0 { t.Errorf("test %d: reassembly.Seq %d != want.Seq %d\n", i, head.Reassembly.Seq, overlapTests[i].want[0].Seq) t.Fail() } } if overlapTests[i].want[1] != nil { if tail.Reassembly.Seq.Difference(overlapTests[i].want[1].Seq) != 0 { t.Errorf("test num %d in.Seq %d != want.Seq %d\n", i, head.Reassembly.Seq, overlapTests[i].want[1].Seq) t.Fail() } } } } return }
func (vnet *VNET) handleTCP(pkt *Packet, now time.Time) { // fmt.Printf("TCP: %08x %s\n", pkt.Flags, pkt.String()) defer pkt.Release() var err error if bytes.Equal(pkt.Eth.DstMAC, layers.EthernetBroadcast[:]) { // ignore return } if pkt.DstHost == nil { // ignore return } if !pkt.DstHost.Up { log.Printf("destination is down: %s", pkt.DstHost.Name) // ignore return } var ( srcIP net.IP dstIP net.IP srcPort = uint16(pkt.TCP.SrcPort) dstPort = uint16(pkt.TCP.DstPort) ) if pkt.IPv4 != nil { srcIP = CloneIP(pkt.IPv4.SrcIP.To16()) dstIP = CloneIP(pkt.IPv4.DstIP.To16()) } else if pkt.IPv6 != nil { srcIP = CloneIP(pkt.IPv6.SrcIP.To16()) dstIP = CloneIP(pkt.IPv6.DstIP.To16()) } else { log.Printf("invalid protocol") // ignore return } route := vnet.routes.GetTable().Lookup( protocols.TCP, srcIP, dstIP, srcPort, dstPort) if route == nil { rule, found := vnet.rules.GetTable().Lookup(protocols.TCP, pkt.DstHost.ID, dstPort) if !found { log.Printf("no rule") // ignore return } var ( ruleDstIP = rule.DstIP ruleDstPort = rule.DstPort hostIP net.IP hostPort uint16 ) if ruleDstIP != nil { hostIP = dstIP hostPort, err = vnet.ports.Allocate(pkt.DstHost.ID, protocols.TCP, 0) if err != nil { // ignore log.Printf("TCP/error: %s", err) return } var r routes.Route r.Protocol = protocols.TCP r.HostID = pkt.DstHost.ID r.SetInboundSource(hostIP, hostPort) r.SetInboundDestination(vnet.system.GatewayIPv4(), vnet.proxy.TCPPort) r.SetOutboundDestination(ruleDstIP, rule.DstPort) route, err = vnet.routes.AddRoute(&r) if err != nil { // ignore log.Printf("TCP/error: %s", err) return } ruleDstIP = vnet.system.GatewayIPv4() ruleDstPort = vnet.proxy.TCPPort } if ruleDstIP == nil { gateway := vnet.hosts.GetTable().LookupByName("gateway") if gateway == nil || !gateway.Up { log.Printf("no gateway") // ignore return } if dstIP.To4() != nil { if len(gateway.IPv4Addrs) > 0 { ruleDstIP = gateway.IPv4Addrs[0] } } else { if len(gateway.IPv6Addrs) > 0 { ruleDstIP = gateway.IPv6Addrs[0] } } } if ruleDstIP == nil { log.Printf("no destination ip") // ignore return } var r routes.Route r.Protocol = protocols.TCP r.HostID = pkt.DstHost.ID r.SetInboundSource(srcIP, srcPort) r.SetInboundDestination(dstIP, dstPort) r.SetOutboundSource(hostIP, hostPort) r.SetOutboundDestination(ruleDstIP, ruleDstPort) route, err = vnet.routes.AddRoute(&r) if err != nil { // ignore log.Printf("TCP/error: %s", err) return } } if route == nil { log.Printf("no route") // ignore return } var ( eth layers.Ethernet tcp layers.TCP ) eth = *pkt.Eth eth.SrcMAC = vnet.system.ControllerMAC() eth.DstMAC = vnet.system.GatewayMAC() tcp = *pkt.TCP tcp.SrcPort = layers.TCPPort(route.Outbound.SrcPort) tcp.DstPort = layers.TCPPort(route.Outbound.DstPort) if route.Outbound.DstIP.To4() != nil { ip := layers.IPv4{ SrcIP: route.Outbound.SrcIP.To4(), DstIP: route.Outbound.DstIP.To4(), Version: 4, Protocol: layers.IPProtocolTCP, TTL: 64, } tcp.SetNetworkLayerForChecksum(&ip) err = vnet.writePacket( ð, &ip, &tcp, gopacket.Payload(pkt.TCP.Payload)) if err != nil { log.Printf("TCP/error: %s", err) return } } else { ip := layers.IPv6{ SrcIP: route.Outbound.SrcIP.To16(), DstIP: route.Outbound.DstIP.To16(), Version: 4, NextHeader: layers.IPProtocolTCP, } tcp.SetNetworkLayerForChecksum(&ip) err = vnet.writePacket( ð, &ip, &tcp, gopacket.Payload(pkt.TCP.Payload)) if err != nil { log.Printf("TCP/error: %s", err) return } } route.RoutedPacket(now, len(pkt.buf)) }
/* protos must contain a UDP or TCP layer on top of IPv4 */ func forgeTestPacket(t *testing.T, seed int64, swap bool, protos ...ProtocolType) *gopacket.Packet { rnd := rand.New(rand.NewSource(seed)) rawBytes := []byte{10, 20, 30} var protoStack []gopacket.SerializableLayer for i, proto := range protos { switch proto { case GRE: greLayer := &layers.GRE{} switch protos[i+1] { case IPv4: greLayer.Protocol = layers.EthernetTypeIPv4 case IPv6: greLayer.Protocol = layers.EthernetTypeIPv6 default: t.Error(fmt.Sprintf("Protocol %s can not be encapsulated in GRE", protos[i+1])) } protoStack = append(protoStack, greLayer) case ETH: ethernetLayer := &layers.Ethernet{ SrcMAC: net.HardwareAddr{0x00, 0x0F, 0xAA, 0xFA, 0xAA, byte(rnd.Intn(0x100))}, DstMAC: net.HardwareAddr{0x00, 0x0D, 0xBD, 0xBD, byte(rnd.Intn(0x100)), 0xBD}, EthernetType: layers.EthernetTypeIPv4, } if swap { ethernetLayer.SrcMAC, ethernetLayer.DstMAC = ethernetLayer.DstMAC, ethernetLayer.SrcMAC } protoStack = append(protoStack, ethernetLayer) case IPv4: ipv4Layer := &layers.IPv4{ SrcIP: net.IP{127, 0, 0, byte(rnd.Intn(0x100))}, DstIP: net.IP{byte(rnd.Intn(0x100)), 8, 8, 8}, } switch protos[i+1] { case TCP: ipv4Layer.Protocol = layers.IPProtocolTCP case UDP: ipv4Layer.Protocol = layers.IPProtocolUDP case GRE: ipv4Layer.Protocol = layers.IPProtocolGRE } if swap { ipv4Layer.SrcIP, ipv4Layer.DstIP = ipv4Layer.DstIP, ipv4Layer.SrcIP } protoStack = append(protoStack, ipv4Layer) case TCP: tcpLayer := &layers.TCP{ SrcPort: layers.TCPPort(uint16(1024 + rnd.Intn(0x10000-1024))), DstPort: layers.TCPPort(uint16(1024 + rnd.Intn(0x10000-1024))), } if swap { tcpLayer.SrcPort, tcpLayer.DstPort = tcpLayer.DstPort, tcpLayer.SrcPort } protoStack = append(protoStack, tcpLayer) case UDP: udpLayer := &layers.UDP{ SrcPort: layers.UDPPort(uint16(1024 + rnd.Intn(0x10000-1024))), DstPort: layers.UDPPort(uint16(1024 + rnd.Intn(0x10000-1024))), } if swap { udpLayer.SrcPort, udpLayer.DstPort = udpLayer.DstPort, udpLayer.SrcPort } protoStack = append(protoStack, udpLayer) default: t.Log("forgeTestPacket : Unsupported protocol ", proto) } } protoStack = append(protoStack, gopacket.Payload(rawBytes)) buffer := gopacket.NewSerializeBuffer() options := gopacket.SerializeOptions{FixLengths: true} err := gopacket.SerializeLayers(buffer, options, protoStack...) if err != nil { t.Fail() } firstLayerType := layers.LayerTypeEthernet switch protos[0] { case IPv4: firstLayerType = layers.LayerTypeIPv4 case IPv6: firstLayerType = layers.LayerTypeIPv6 } gpacket := gopacket.NewPacket(buffer.Bytes(), firstLayerType, gopacket.Default) return &gpacket }
func main() { defer util.Run()() var eth layers.Ethernet var dot1q layers.Dot1Q var ip4 layers.IPv4 var ip6 layers.IPv6 var ip6extensions layers.IPv6ExtensionSkipper var tcp layers.TCP var payload gopacket.Payload decoded := make([]gopacket.LayerType, 0, 4) // target/track all TCP flows from this TCP/IP service endpoint trackedFlows := make(map[types.TcpIpFlow]int) serviceIP := net.ParseIP(*serviceIPstr) if serviceIP == nil { panic(fmt.Sprintf("non-ip target: %q\n", serviceIPstr)) } serviceIP = serviceIP.To4() if serviceIP == nil { panic(fmt.Sprintf("non-ipv4 target: %q\n", serviceIPstr)) } streamInjector := attack.TCPStreamInjector{} err := streamInjector.Init("0.0.0.0") if err != nil { panic(err) } streamInjector.Payload = []byte("meowmeowmeow") handle, err := pcap.OpenLive(*iface, int32(*snaplen), true, pcap.BlockForever) if err != nil { log.Fatal("error opening pcap handle: ", err) } if err := handle.SetBPFFilter(*filter); err != nil { log.Fatal("error setting BPF filter: ", err) } parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &dot1q, &ip4, &ip6, &ip6extensions, &tcp, &payload) flow := &types.TcpIpFlow{} log.Print("collecting packets...\n") for { data, ci, err := handle.ZeroCopyReadPacketData() if err != nil { log.Printf("error getting packet: %v %s", err, ci) continue } err = parser.DecodeLayers(data, &decoded) if err != nil { log.Printf("error decoding packet: %v", err) continue } // if we see a flow coming from the tcp/ip service we are watching // then track how many packets we receive from each flow if tcp.SrcPort == layers.TCPPort(*servicePort) && ip4.SrcIP.Equal(serviceIP) { flow = types.NewTcpIpFlowFromLayers(ip4, tcp) _, isTracked := trackedFlows[*flow] if isTracked { trackedFlows[*flow] += 1 } else { trackedFlows[*flow] = 1 } } else { continue } // after 3 packets from a given flow then inject packets into the stream if trackedFlows[*flow]%10 == 0 { err = streamInjector.SetIPLayer(ip4) if err != nil { panic(err) } streamInjector.SetTCPLayer(tcp) err = streamInjector.SpraySequenceRangePackets(tcp.Seq, 20) if err != nil { panic(err) } log.Print("packet spray sent!\n") } } }
func (self oxmBasic) SetField(data *Frame, key OxmKey, payload OxmPayload) error { m := payload.(OxmValueMask) switch uint32(key.(OxmKeyBasic)) { default: return fmt.Errorf("unknown oxm field") case oxm.OXM_OF_IN_PORT: data.inPort = binary.BigEndian.Uint32(m.Value) return nil case oxm.OXM_OF_IN_PHY_PORT: data.inPhyPort = binary.BigEndian.Uint32(m.Value) return nil case oxm.OXM_OF_METADATA: data.metadata = binary.BigEndian.Uint64(m.Value) return nil case oxm.OXM_OF_ETH_DST: for _, layer := range data.Layers() { if t, ok := layer.(*layers.Ethernet); ok { t.DstMAC = net.HardwareAddr(m.Value) return nil } } case oxm.OXM_OF_ETH_SRC: for _, layer := range data.Layers() { if t, ok := layer.(*layers.Ethernet); ok { t.SrcMAC = net.HardwareAddr(m.Value) return nil } } case oxm.OXM_OF_ETH_TYPE: var lastLayer gopacket.Layer for _, layer := range data.Layers() { switch t := layer.(type) { case *layers.Ethernet: lastLayer = t case *layers.Dot1Q: lastLayer = t } } if t, ok := lastLayer.(*layers.Ethernet); ok { t.EthernetType = layers.EthernetType(binary.BigEndian.Uint16(m.Value)) return nil } if t, ok := lastLayer.(*layers.Dot1Q); ok { t.Type = layers.EthernetType(binary.BigEndian.Uint16(m.Value)) return nil } case oxm.OXM_OF_VLAN_VID: for _, layer := range data.Layers() { if t, ok := layer.(*layers.Dot1Q); ok { t.VLANIdentifier = binary.BigEndian.Uint16(m.Value) & 0x0fff return nil } } case oxm.OXM_OF_VLAN_PCP: for _, layer := range data.Layers() { if t, ok := layer.(*layers.Dot1Q); ok { t.Priority = m.Value[0] return nil } } case oxm.OXM_OF_IP_DSCP: for _, layer := range data.Layers() { if t, ok := layer.(*layers.IPv4); ok { t.TOS = t.TOS&0x03 | m.Value[0]<<2 return nil } if t, ok := layer.(*layers.IPv6); ok { t.TrafficClass = t.TrafficClass&0x03 | m.Value[0]<<2 return nil } } case oxm.OXM_OF_IP_ECN: for _, layer := range data.Layers() { if t, ok := layer.(*layers.IPv4); ok { t.TOS = t.TOS&0xFC | m.Value[0]&0x03 return nil } if t, ok := layer.(*layers.IPv6); ok { t.TrafficClass = t.TrafficClass&0xFC | m.Value[0]&0x03 return nil } } case oxm.OXM_OF_IP_PROTO: for _, layer := range data.Layers() { if t, ok := layer.(*layers.IPv4); ok { t.Protocol = layers.IPProtocol(m.Value[0]) return nil } if t, ok := layer.(*layers.IPv6); ok { t.NextHeader = layers.IPProtocol(m.Value[0]) return nil } } case oxm.OXM_OF_IPV4_SRC: for _, layer := range data.Layers() { if t, ok := layer.(*layers.IPv4); ok { t.SrcIP = net.IP(m.Value) return nil } } case oxm.OXM_OF_IPV4_DST: for _, layer := range data.Layers() { if t, ok := layer.(*layers.IPv4); ok { t.DstIP = net.IP(m.Value) return nil } } case oxm.OXM_OF_TCP_SRC: for _, layer := range data.Layers() { if t, ok := layer.(*layers.TCP); ok { t.SrcPort = layers.TCPPort(binary.BigEndian.Uint16(m.Value)) return nil } } case oxm.OXM_OF_TCP_DST: for _, layer := range data.Layers() { if t, ok := layer.(*layers.TCP); ok { t.DstPort = layers.TCPPort(binary.BigEndian.Uint16(m.Value)) return nil } } case oxm.OXM_OF_UDP_SRC: for _, layer := range data.Layers() { if t, ok := layer.(*layers.UDP); ok { t.SrcPort = layers.UDPPort(binary.BigEndian.Uint16(m.Value)) return nil } } case oxm.OXM_OF_UDP_DST: for _, layer := range data.Layers() { if t, ok := layer.(*layers.UDP); ok { t.DstPort = layers.UDPPort(binary.BigEndian.Uint16(m.Value)) return nil } } case oxm.OXM_OF_SCTP_SRC: for _, layer := range data.Layers() { if t, ok := layer.(*layers.SCTP); ok { t.SrcPort = layers.SCTPPort(binary.BigEndian.Uint16(m.Value)) return nil } } case oxm.OXM_OF_SCTP_DST: for _, layer := range data.Layers() { if t, ok := layer.(*layers.SCTP); ok { t.DstPort = layers.SCTPPort(binary.BigEndian.Uint16(m.Value)) return nil } } case oxm.OXM_OF_ICMPV4_TYPE: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ICMPv4); ok { t.TypeCode = layers.ICMPv4TypeCode(uint16(t.TypeCode)&0x00FF | uint16(m.Value[0])<<8) return nil } } case oxm.OXM_OF_ICMPV4_CODE: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ICMPv4); ok { t.TypeCode = layers.ICMPv4TypeCode(uint16(t.TypeCode)&0xFF00 | uint16(m.Value[0])) return nil } } case oxm.OXM_OF_ARP_OP: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ARP); ok { t.Operation = binary.BigEndian.Uint16(m.Value) return nil } } case oxm.OXM_OF_ARP_SPA: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ARP); ok { t.SourceProtAddress = m.Value return nil } } case oxm.OXM_OF_ARP_TPA: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ARP); ok { t.DstProtAddress = m.Value return nil } } case oxm.OXM_OF_ARP_SHA: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ARP); ok { t.SourceHwAddress = m.Value return nil } } case oxm.OXM_OF_ARP_THA: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ARP); ok { t.DstHwAddress = m.Value return nil } } case oxm.OXM_OF_IPV6_SRC: for _, layer := range data.Layers() { if t, ok := layer.(*layers.IPv6); ok { t.SrcIP = net.IP(m.Value) return nil } } case oxm.OXM_OF_IPV6_DST: for _, layer := range data.Layers() { if t, ok := layer.(*layers.IPv6); ok { t.DstIP = net.IP(m.Value) return nil } } case oxm.OXM_OF_IPV6_FLABEL: for _, layer := range data.Layers() { if t, ok := layer.(*layers.IPv6); ok { t.FlowLabel = binary.BigEndian.Uint32(m.Value) return nil } } case oxm.OXM_OF_ICMPV6_TYPE: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ICMPv6); ok { t.TypeCode = layers.ICMPv6TypeCode(uint16(t.TypeCode)&0x00FF | uint16(m.Value[0])<<8) return nil } } case oxm.OXM_OF_ICMPV6_CODE: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ICMPv6); ok { t.TypeCode = layers.ICMPv6TypeCode(uint16(t.TypeCode)&0xFF00 | uint16(m.Value[0])) return nil } } case oxm.OXM_OF_IPV6_ND_TARGET: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ICMPv6); ok { typ := uint8(t.TypeCode >> 8) if typ == layers.ICMPv6TypeNeighborSolicitation || typ == layers.ICMPv6TypeNeighborAdvertisement { copy(t.Payload[:16], m.Value) return nil } } } case oxm.OXM_OF_IPV6_ND_SLL: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ICMPv6); ok { typ := uint8(t.TypeCode >> 8) if typ == layers.ICMPv6TypeNeighborSolicitation { for cur := 16; cur < len(t.Payload); { length := int(t.Payload[cur+1]) * 8 if t.Payload[cur] == 1 { // source link-layer address (RFC 2461 4.6) copy(t.Payload[cur+2:], m.Value) return nil } cur += length } buf := make([]byte, 8) buf[0] = 2 buf[1] = 1 copy(buf[2:], m.Value) t.Payload = append(t.Payload, buf...) return nil } } } case oxm.OXM_OF_IPV6_ND_TLL: for _, layer := range data.Layers() { if t, ok := layer.(*layers.ICMPv6); ok { typ := uint8(t.TypeCode >> 8) if typ == layers.ICMPv6TypeNeighborAdvertisement { for cur := 16; cur < len(t.Payload); { length := int(t.Payload[cur+1]) * 8 if t.Payload[cur] == 2 { // target link-layer address (RFC 2461 4.6) copy(t.Payload[cur+2:], m.Value) return nil } cur += length } buf := make([]byte, 8) buf[0] = 2 buf[1] = 1 copy(buf[2:], m.Value) t.Payload = append(t.Payload, buf...) return nil } } } case oxm.OXM_OF_MPLS_LABEL: for _, layer := range data.Layers() { if t, ok := layer.(*layers.MPLS); ok { t.Label = binary.BigEndian.Uint32(m.Value) return nil } } case oxm.OXM_OF_MPLS_TC: for _, layer := range data.Layers() { if t, ok := layer.(*layers.MPLS); ok { t.TrafficClass = m.Value[0] return nil } } case oxm.OXM_OF_MPLS_BOS: for _, layer := range data.Layers() { if t, ok := layer.(*layers.MPLS); ok { if m.Value[0] == 0 { t.StackBottom = false } else { t.StackBottom = true } return nil } } case oxm.OXM_OF_PBB_ISID: for _, layer := range data.Layers() { if t, ok := layer.(*layers2.PBB); ok { t.ServiceIdentifier = binary.BigEndian.Uint32(append(make([]byte, 1), m.Value...)) return nil } } case oxm.OXM_OF_TUNNEL_ID: data.tunnelId = binary.BigEndian.Uint64(m.Value) return nil case oxm.OXM_OF_IPV6_EXTHDR: return fmt.Errorf("OXM_OF_IPV6_EXTHDR setter is unsupported") } return fmt.Errorf("layer not found: %v", m) }
func HelperTestThreeWayClose(isClient bool, t *testing.T) { PageCache := newPageCache() var closerState, remoteState *uint8 attackLogger := NewDummyAttackLogger() options := ConnectionOptions{ MaxBufferedPagesTotal: 0, MaxBufferedPagesPerConnection: 0, MaxRingPackets: 40, PageCache: PageCache, LogDir: "fake-log-dir", } f := &DefaultConnFactory{} conn := f.Build(options).(*Connection) conn.AttackLogger = attackLogger conn.state = TCP_DATA_TRANSFER conn.serverNextSeq = 4666 conn.clientNextSeq = 9666 if isClient { closerState = &conn.clientState remoteState = &conn.serverState } else { closerState = &conn.serverState remoteState = &conn.clientState } ipFlow, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) ip := layers.IPv4{ SrcIP: net.IP{1, 2, 3, 4}, DstIP: net.IP{2, 3, 4, 5}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp := layers.TCP{ Seq: 9666, Ack: 4111, FIN: true, SYN: false, ACK: true, SrcPort: 1, DstPort: 2, } flow := types.NewTcpIpFlowFromFlows(ipFlow, tcpFlow) p := types.PacketManifest{ Timestamp: time.Now(), Flow: flow, IP: ip, TCP: tcp, Payload: []byte{}, } conn.clientFlow = flow conn.serverFlow = flow.Reverse() conn.ReceivePacket(&p) log.Print("meow1") if conn.state != TCP_CONNECTION_CLOSING { t.Error("connection state must transition to TCP_CONNECTION_CLOSING\n") t.Fail() } if *closerState != TCP_FIN_WAIT1 { t.Error("closer state must be in TCP_FINE_WAIT1\n") t.Fail() } if *remoteState != TCP_CLOSE_WAIT { t.Error("remote state must be in TCP_CLOSE_WAIT\n") t.Fail() } // next state transition ip = layers.IPv4{ SrcIP: net.IP{2, 3, 4, 5}, DstIP: net.IP{1, 2, 3, 4}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp = layers.TCP{ Seq: 4111, SYN: false, FIN: true, ACK: true, Ack: 9667, SrcPort: 2, DstPort: 1, } flow2 := flow.Reverse() p = types.PacketManifest{ Timestamp: time.Now(), Flow: flow2, IP: ip, TCP: tcp, Payload: []byte{}, } conn.ReceivePacket(&p) log.Print("meow2") if conn.state != TCP_CONNECTION_CLOSING { t.Error("connection state must transition to TCP_CONNECTION_CLOSING\n") t.Fail() } // next state transition ip = layers.IPv4{ SrcIP: net.IP{1, 2, 3, 4}, DstIP: net.IP{2, 3, 4, 5}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp = layers.TCP{ Seq: 9667, SYN: false, FIN: false, ACK: true, Ack: 4112, SrcPort: 1, DstPort: 2, } p = types.PacketManifest{ Timestamp: time.Now(), Flow: flow, IP: ip, TCP: tcp, Payload: []byte{}, } conn.ReceivePacket(&p) log.Print("freeing page cache") }
//Detectinitcwnd attempts to detect the initial congession window of an http endpoint. //First does a 3 way tcp handshake, sends GET request and then does not ack any response while measuring the packets received. This allows us to see how much data the server can send without acknowledgement. func Detectinitcwnd(host, url string, dstip net.IP) (pkt_count, payload_size int, fullpayload []byte, err error) { pldata := []byte(fmt.Sprintf("GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", url, host)) var dstport layers.TCPPort dstport = layers.TCPPort(80) srcip, sport := localIPPort(dstip) srcport := layers.TCPPort(sport) log.Printf("using srcip: %v", srcip.String()) log.Printf("using dstip: %v", dstip.String()) // Our IP header... not used, but necessary for TCP checksumming. ip := &layers.IPv4{ SrcIP: srcip, DstIP: dstip, Protocol: layers.IPProtocolTCP, } //layers.TCPOption{3, 3, []byte{7}} maybe for window scaling... dunno tcpopts := []layers.TCPOption{layers.TCPOption{2, 4, []byte{5, 172}}} //Set MSS 1452 // Our TCP header tcp := &layers.TCP{ SrcPort: srcport, DstPort: dstport, Seq: 1105024978, SYN: true, Window: 65535, Options: tcpopts, } tcp.SetNetworkLayerForChecksum(ip) // Serialize. Note: we only serialize the TCP layer, because the // socket we get with net.ListenPacket wraps our data in IPv4 packets // already. We do still need the IP layer to compute checksums // correctly, though. buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ ComputeChecksums: true, FixLengths: true, } err = gopacket.SerializeLayers(buf, opts, tcp) if err != nil { return } var out1 bytes.Buffer iptset := exec.Command("iptables", "-A", "OUTPUT", "-p", "tcp", "--tcp-flags", "RST", "RST", "-s", srcip.String(), "--sport", porttoint(srcport), "--dport", porttoint(dstport), "-j", "DROP") iptset.Stderr = &out1 log.Println(iptset) err = iptset.Run() if err != nil { return } log.Println(out1.String()) iptrem := exec.Command("iptables", "-D", "OUTPUT", "-p", "tcp", "--tcp-flags", "RST", "RST", "-s", srcip.String(), "--sport", porttoint(srcport), "--dport", porttoint(dstport), "-j", "DROP") conn, err := net.ListenPacket("ip4:tcp", "0.0.0.0") if err != nil { return } defer func() { fmt.Println(iptrem) var out bytes.Buffer iptrem.Stderr = &out err = iptrem.Run() if err != nil { log.Println(err) } fmt.Printf(out.String()) log.Println("Removed iptable rule") //Now RST should be allowed... send it rst_pkt := &layers.TCP{ SrcPort: srcport, DstPort: dstport, Seq: 1105024980, Window: 65535, RST: true, } rst_pkt.SetNetworkLayerForChecksum(ip) if err := gopacket.SerializeLayers(buf, opts, rst_pkt); err != nil { //Shadowing err since we dont care log.Println(err) } if _, err := conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip}); err != nil { //Shadowing err since we dont care log.Println(err) } }() log.Println("writing request") _, err = conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip}) if err != nil { return } // Set deadline so we don't wait forever. err = conn.SetDeadline(time.Now().Add(15 * time.Second)) if err != nil { return } //Capture synack from our syn, return the ack value ack, err := getack(conn, srcport, dstip.String()) if err != nil { log.Println(err) return } else { //Prepare http request, ack the synack payload := &layers.TCP{ SrcPort: srcport, DstPort: dstport, Seq: 1105024979, ACK: true, Window: 65535, Ack: ack + 1, } payload.SetNetworkLayerForChecksum(ip) if err := gopacket.SerializeLayers(buf, opts, payload, gopacket.Payload(pldata)); err != nil { log.Fatal(err) } if _, err := conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip}); err != nil { log.Fatal(err) } pkt_count, payload_size, fullpayload = listenandcount(conn, dstip.String(), srcport) log.Println("Initcwnd: ", pkt_count) log.Println("Data: ", payload_size) return } return }
func TestTCPHijack(t *testing.T) { attackLogger := NewDummyAttackLogger() options := ConnectionOptions{ MaxBufferedPagesTotal: 0, MaxBufferedPagesPerConnection: 0, MaxRingPackets: 40, PageCache: nil, LogDir: "fake-log-dir", DetectHijack: true, } f := &DefaultConnFactory{} conn := f.Build(options).(*Connection) conn.AttackLogger = attackLogger ip := layers.IPv4{ SrcIP: net.IP{1, 2, 3, 4}, DstIP: net.IP{2, 3, 4, 5}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp := layers.TCP{ Seq: 3, SYN: true, ACK: false, SrcPort: 1, DstPort: 2, } ipFlow, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) flow := types.NewTcpIpFlowFromFlows(ipFlow, tcpFlow) p := types.PacketManifest{ Timestamp: time.Now(), Flow: flow, IP: ip, TCP: tcp, Payload: []byte{}, } tcp.SetNetworkLayerForChecksum(&ip) flowReversed := flow.Reverse() conn.clientFlow = flow conn.serverFlow = flowReversed conn.ReceivePacket(&p) if conn.state != TCP_CONNECTION_REQUEST { t.Error("invalid state transition\n") t.Fail() } // next state transition test ip = layers.IPv4{ SrcIP: net.IP{2, 3, 4, 5}, DstIP: net.IP{1, 2, 3, 4}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp = layers.TCP{ Seq: 9, SYN: true, ACK: true, Ack: 4, SrcPort: 2, DstPort: 1, } p = types.PacketManifest{ Timestamp: time.Now(), Flow: flowReversed, IP: ip, TCP: tcp, Payload: []byte{}, } conn.ReceivePacket(&p) if conn.state != TCP_CONNECTION_ESTABLISHED { t.Errorf("invalid state transition: current state %d\n", conn.state) t.Fail() } // test hijack in TCP_CONNECTION_ESTABLISHED state ip = layers.IPv4{ SrcIP: net.IP{2, 3, 4, 5}, DstIP: net.IP{1, 2, 3, 4}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp = layers.TCP{ Seq: 6699, SYN: true, ACK: true, Ack: 4, SrcPort: 2, DstPort: 1, } p = types.PacketManifest{ Timestamp: time.Now(), Flow: flowReversed, IP: ip, TCP: tcp, Payload: []byte{}, } conn.ReceivePacket(&p) if attackLogger.Count != 1 { t.Error("hijack detection fail") t.Fail() } // next state transition test ip = layers.IPv4{ SrcIP: net.IP{1, 2, 3, 4}, DstIP: net.IP{2, 3, 4, 5}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp = layers.TCP{ Seq: 4, SYN: false, ACK: true, Ack: 10, SrcPort: 1, DstPort: 2, } p = types.PacketManifest{ Timestamp: time.Now(), Flow: flow, IP: ip, TCP: tcp, Payload: []byte{}, } conn.ReceivePacket(&p) if conn.state != TCP_DATA_TRANSFER { t.Errorf("invalid state transition; state is %d\n", conn.state) t.Fail() } // test hijack in TCP_DATA_TRANSFER state ip = layers.IPv4{ SrcIP: net.IP{2, 3, 4, 5}, DstIP: net.IP{1, 2, 3, 4}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } tcp = layers.TCP{ Seq: 7711, SYN: true, ACK: true, Ack: 4, SrcPort: 2, DstPort: 1, } p = types.PacketManifest{ Timestamp: time.Now(), Flow: flowReversed, IP: ip, TCP: tcp, Payload: []byte{}, } conn.ReceivePacket(&p) if attackLogger.Count != 2 { t.Error("hijack detection fail") t.Fail() } }
func main() { if len(os.Args) != 3 { log.Printf("Usage: %s <host/ip> <port>\n", os.Args[0]) os.Exit(-1) } log.Println("starting") dstaddrs, err := net.LookupIP(os.Args[1]) if err != nil { log.Fatal(err) } // parse the destination host and port from the command line os.Args dstip := dstaddrs[0].To4() var dstport layers.TCPPort if d, err := strconv.ParseInt(os.Args[2], 10, 16); err != nil { log.Fatal(err) } else { dstport = layers.TCPPort(d) } srcip, sport := localIPPort(dstip) srcport := layers.TCPPort(sport) log.Printf("using srcip: %v", srcip.String()) // Our IP header... not used, but necessary for TCP checksumming. ip := &layers.IPv4{ SrcIP: srcip, DstIP: dstip, Protocol: layers.IPProtocolTCP, } // Our TCP header tcp := &layers.TCP{ SrcPort: srcport, DstPort: dstport, Seq: 1105024978, SYN: true, Window: 14600, } tcp.SetNetworkLayerForChecksum(ip) // Serialize. Note: we only serialize the TCP layer, because the // socket we get with net.ListenPacket wraps our data in IPv4 packets // already. We do still need the IP layer to compute checksums // correctly, though. buf := gopacket.NewSerializeBuffer() opts := gopacket.SerializeOptions{ ComputeChecksums: true, FixLengths: true, } if err := gopacket.SerializeLayers(buf, opts, tcp); err != nil { log.Fatal(err) } conn, err := net.ListenPacket("ip4:tcp", "0.0.0.0") if err != nil { log.Fatal(err) } log.Println("writing request") if _, err := conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dstip}); err != nil { log.Fatal(err) } // Set deadline so we don't wait forever. if err := conn.SetDeadline(time.Now().Add(10 * time.Second)); err != nil { log.Fatal(err) } for { b := make([]byte, 4096) log.Println("reading from conn") n, addr, err := conn.ReadFrom(b) if err != nil { log.Println("error reading packet: ", err) return } else if addr.String() == dstip.String() { // Decode a packet packet := gopacket.NewPacket(b[:n], layers.LayerTypeTCP, gopacket.Default) // Get the TCP layer from this packet if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil { tcp, _ := tcpLayer.(*layers.TCP) if tcp.DstPort == srcport { if tcp.SYN && tcp.ACK { log.Printf("Port %d is OPEN\n", dstport) } else { log.Printf("Port %d is CLOSED\n", dstport) } return } } } else { log.Printf("Got packet not matching addr") } } }
func main() { flag.Parse() args := flag.Args() if len(args) != 2 { log.Printf("Usage: %s <ip> <port>\n", os.Args[0]) os.Exit(-1) } // parse the destination host and port from the command line args dstip := net.ParseIP(args[0]).To4() dport_, err := strconv.ParseInt(args[1], 10, 16) if err != nil { log.Fatal(err) } dport := layers.TCPPort(dport_) sport := layers.TCPPort(5000) // get our local ip. srcip, err := localIP(dstip) if err != nil { log.Fatal(err) } devs, err := pcap.FindAllDevs() if err != nil { log.Fatal(err) } dev := "" for _, d := range devs { for _, a := range d.Addresses { if bytes.Equal(a.IP, srcip) { dev = d.Name } } // if d.Description == "Realtek PCIe GBE Family Controller" { // fmt.Println(d.Name) // dev = d.Name // } // fmt.Println(dev.Description) } if dev == "" { log.Fatal("Could not find the appropriate adapter device") } srcmac, err := localMac(dev) if err != nil { log.Fatal(err) } dstmac, err := remoteMac(dev, srcmac, srcip, dstip) if err != nil { log.Fatal(err) } eth := &layers.Ethernet{ SrcMAC: srcmac, DstMAC: dstmac, EthernetType: layers.EthernetTypeIPv4, } // Our IPv4 header ip := &layers.IPv4{ Version: 4, IHL: 5, TOS: 0, Length: 20, // FIX Id: 2, Flags: layers.IPv4DontFragment, FragOffset: 0, //16384, TTL: 3, //64, Protocol: layers.IPProtocolTCP, Checksum: 0, SrcIP: srcip, DstIP: dstip, } // Our TCP header tcp := &layers.TCP{ SrcPort: sport, DstPort: dport, Seq: 0, Ack: 0, SYN: true, Window: 64240, Checksum: 0, Urgent: 0, } tcp.DataOffset = 5 // uint8(unsafe.Sizeof(tcp)) tcp.SetNetworkLayerForChecksum(ip) buf := gopacket.NewSerializeBuffer() err = gopacket.SerializeLayers( buf, gopacket.SerializeOptions{ ComputeChecksums: true, // automatically compute checksums FixLengths: true, }, eth, ip, tcp, ) if err != nil { log.Fatal(err) } handle, err := pcap.OpenLive(`rpcap://`+dev, 65535, true, time.Second*1) if err != nil { log.Fatal(err) } defer handle.Close() var wg sync.WaitGroup handle.SetBPFFilter(fmt.Sprintf("tcp and host %s and host %s and port %d and port %d", srcip.String(), dstip.String(), sport, dport)) packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) wg.Add(1) go func() { stop := false go func() { <-time.After(time.Second * 2) stop = true }() for { if stop { break } packet, err := packetSource.NextPacket() if err == io.EOF { break } else if err != nil { //log.Println("Error:", err) continue } if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil { tcp, _ := tcpLayer.(*layers.TCP) if tcp.SrcPort == dport && tcp.DstPort == sport { if tcp.SYN && tcp.ACK { fmt.Printf("Port %d is OPEN\n", dport_) } else { fmt.Printf("Port %d is CLOSED\n", dport_) } break } //fmt.Printf("From src port %d to dst port %d\n", tcp.SrcPort, tcp.DstPort) } } wg.Done() }() err = handle.WritePacketData(buf.Bytes()) if err != nil { log.Fatal(err) } wg.Wait() }
// Given an EvePacket, convert the payload to a PCAP faking out the // headers as best we can. // // A buffer containing the 1 packet pcap file will be returned. func EvePayloadToPcap(event *EveEvent) ([]byte, error) { buffer := gopacket.NewSerializeBuffer() options := gopacket.SerializeOptions{ FixLengths: true, ComputeChecksums: true, } payloadLayer := gopacket.Payload(event.Payload.Bytes()) payloadLayer.SerializeTo(buffer, options) srcIp := net.ParseIP(event.SrcIP) if srcIp == nil { return nil, fmt.Errorf("Failed to parse IP address %s.", event.SrcIP) } dstIp := net.ParseIP(event.DstIP) if dstIp == nil { return nil, fmt.Errorf("Failed to parse IP address %s.", event.DstIP) } proto, err := ProtoNumber(event.Proto) if err != nil { return nil, err } switch proto { case layers.IPProtocolTCP: // Could probably fake up a better TCP layer here. tcpLayer := layers.TCP{ SrcPort: layers.TCPPort(event.SrcPort), DstPort: layers.TCPPort(event.DstPort), } tcpLayer.SerializeTo(buffer, options) break case layers.IPProtocolUDP: udpLayer := layers.UDP{ SrcPort: layers.UDPPort(event.SrcPort), DstPort: layers.UDPPort(event.DstPort), } udpLayer.SerializeTo(buffer, options) break case layers.IPProtocolICMPv4: icmpLayer := layers.ICMPv4{ TypeCode: layers.CreateICMPv4TypeCode( event.IcmpType, event.IcmpCode), Id: 0, Seq: 0, } icmpLayer.SerializeTo(buffer, options) break case layers.IPProtocolICMPv6: icmp6Layer := layers.ICMPv6{ TypeCode: layers.CreateICMPv6TypeCode( event.IcmpType, event.IcmpCode), } icmp6Layer.SerializeTo(buffer, options) break default: return nil, fmt.Errorf("Unsupported protocol %d.", proto) } isIp6 := dstIp.To4() == nil if !isIp6 { ipLayer := layers.IPv4{ SrcIP: srcIp, DstIP: dstIp, Version: 4, Protocol: proto, TTL: 64, } ipLayer.SerializeTo(buffer, options) } else { ip6Layer := layers.IPv6{ Version: 6, SrcIP: srcIp, DstIP: dstIp, } ip6Layer.SerializeTo(buffer, options) } return pcap.CreatePcap(event.Timestamp.Time, buffer.Bytes(), layers.LinkTypeRaw) }
func TestInjectionDetector(t *testing.T) { log.Print("TestInjectionDetector") attackLogger := NewDummyAttackLogger() options := ConnectionOptions{ MaxBufferedPagesTotal: 0, MaxBufferedPagesPerConnection: 0, MaxRingPackets: 40, PageCache: nil, LogDir: "fake-log-dir", AttackLogger: attackLogger, } f := &DefaultConnFactory{} conn := f.Build(options).(*Connection) reassembly := types.Reassembly{ Seq: types.Sequence(5), Bytes: []byte{1, 2, 3, 4, 5}, } conn.ClientStreamRing.Reassembly = &reassembly conn.ClientStreamRing = conn.ClientStreamRing.Next() p := types.PacketManifest{ IP: layers.IPv4{ SrcIP: net.IP{1, 2, 3, 4}, DstIP: net.IP{2, 3, 4, 5}, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, }, TCP: layers.TCP{ Seq: 7, SrcPort: 1, DstPort: 2, }, Payload: []byte{1, 2, 3, 4, 5, 6, 7}, } ipFlow, _ := gopacket.FlowFromEndpoints(layers.NewIPEndpoint(net.IPv4(1, 2, 3, 4)), layers.NewIPEndpoint(net.IPv4(2, 3, 4, 5))) tcpFlow, _ := gopacket.FlowFromEndpoints(layers.NewTCPPortEndpoint(layers.TCPPort(1)), layers.NewTCPPortEndpoint(layers.TCPPort(2))) serverFlow := types.NewTcpIpFlowFromFlows(ipFlow, tcpFlow) conn.serverFlow = serverFlow clientFlow := serverFlow.Reverse() conn.clientFlow = clientFlow conn.detectInjection(&p, serverFlow) if attackLogger.Count != 1 { t.Errorf("detectInjection failed; count == %d\n", attackLogger.Count) t.Fail() } // next test case p.TCP = layers.TCP{ Seq: 7, SrcPort: 1, DstPort: 2, } p.Payload = []byte{3, 4, 5} conn.detectInjection(&p, serverFlow) if attackLogger.Count == 0 { t.Error("failed to detect injection\n") t.Fail() } // next test case attackLogger.Count = 0 p.TCP = layers.TCP{ Seq: 1, SrcPort: 1, DstPort: 2, } p.Payload = []byte{1, 2, 3, 4, 5, 6} conn.detectInjection(&p, serverFlow) if attackLogger.Count == 0 { t.Error("failed to detect injection\n") t.Fail() } // next test case attackLogger.Count = 0 p.TCP = layers.TCP{ Seq: 1, SrcPort: 1, DstPort: 2, } p.Payload = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17} conn.detectInjection(&p, serverFlow) if attackLogger.Count != 1 { t.Error("injection detection failure\n") t.Fail() } }