func SetupRealConnectionInquisitor() (*Supervisor, PacketDispatcher, types.PacketSource) { tcpIdleTimeout, _ := time.ParseDuration("10m") dispatcherOptions := DispatcherOptions{ BufferedPerConnection: 10, BufferedTotal: 100, LogDir: ".", LogPackets: true, TcpIdleTimeout: tcpIdleTimeout, MaxRingPackets: 40, Logger: logging.NewAttackMetadataJsonLogger("archives"), DetectHijack: true, DetectInjection: true, DetectCoalesceInjection: true, MaxConcurrentConnections: 100, } wireDuration, _ := time.ParseDuration("3s") snifferOptions := types.SnifferDriverOptions{ Device: "myInterface", Filename: "", WireDuration: wireDuration, Snaplen: 65536, Filter: "tcp", } factory := &DefaultConnFactory{} mockPacketLoggerFactory := MockPacketLoggerFactory{} options := SupervisorOptions{ SnifferDriverOptions: &snifferOptions, DispatcherOptions: dispatcherOptions, SnifferFactory: NewMockSniffer, ConnectionFactory: factory, PacketLoggerFactory: mockPacketLoggerFactory, } supervisor := NewSupervisor(options) go supervisor.Run() sniffer := supervisor.GetSniffer() startedChan := sniffer.GetStartedChan() dispatcher := supervisor.GetDispatcher() <-startedChan return supervisor, dispatcher, sniffer }
func main() { var ( pcapfile = flag.String("pcapfile", "", "pcap filename to read packets from rather than a wire interface.") iface = flag.String("i", "eth0", "Interface to get packets from") snaplen = flag.Int("s", 65536, "SnapLen for pcap packet capture") filter = flag.String("f", "tcp", "BPF filter for pcap") logDir = flag.String("l", "", "incoming log dir used initially for pcap files if packet logging is enabled") wireTimeout = flag.String("w", "3s", "timeout for reading packets off the wire") metadataAttackLog = flag.Bool("metadata_attack_log", true, "if set to true then attack reports will only include metadata") logPackets = flag.Bool("log_packets", false, "if set to true then log all packets for each tracked TCP connection") tcpTimeout = flag.Duration("tcp_idle_timeout", time.Minute*5, "tcp idle timeout duration") maxRingPackets = flag.Int("max_ring_packets", 40, "Max packets per connection stream ring buffer") detectHijack = flag.Bool("detect_hijack", true, "Detect handshake hijack attacks") detectInjection = flag.Bool("detect_injection", true, "Detect injection attacks") detectCoalesceInjection = flag.Bool("detect_coalesce_injection", true, "Detect coalesce injection attacks") maxConcurrentConnections = flag.Int("max_concurrent_connections", 0, "Maximum number of concurrent connection to track.") bufferedPerConnection = flag.Int("connection_max_buffer", 0, ` Max packets to buffer for a single connection before skipping over a gap in data and continuing to stream the connection after the buffer. If zero or less, this is infinite.`) bufferedTotal = flag.Int("total_max_buffer", 0, ` Max packets to buffer total before skipping over gaps in connections and continuing to stream connection data. If zero or less, this is infinite`) maxPcapLogSize = flag.Int("max_pcap_log_size", 1, "maximum pcap size per rotation in megabytes") maxNumPcapRotations = flag.Int("max_pcap_rotations", 10, "maximum number of pcap rotations per connection") archiveDir = flag.String("archive_dir", "", "archive directory for storing attack logs and related pcap files") daq = flag.String("daq", "libpcap", "Data AcQuisition packet source") ) flag.Parse() if *daq == "" { log.Fatal("must specify a Data AcQuisition packet source`") } // XXX TODO use the pure golang pcap file sniffing API; gopacket's pcapgo if *pcapfile != "" && *daq != "libpcap" { log.Fatal("only libpcap DAQ supports sniffing pcap files") } if *archiveDir == "" || *logDir == "" { log.Fatal("must specify both incoming log dir and archive log dir") } wireDuration, err := time.ParseDuration(*wireTimeout) if err != nil { log.Fatal("invalid wire timeout duration: ", *wireTimeout) } if *maxConcurrentConnections == 0 { log.Fatal("maxConcurrentConnections must be specified") } if *bufferedPerConnection == 0 || *bufferedTotal == 0 { log.Fatal("connection_max_buffer and total_max_buffer must be set to a non-zero value") } var logger types.Logger if *metadataAttackLog { loggerInstance := logging.NewAttackMetadataJsonLogger(*archiveDir) loggerInstance.Start() defer func() { loggerInstance.Stop() }() logger = loggerInstance } else { loggerInstance := logging.NewAttackJsonLogger(*archiveDir) loggerInstance.Start() defer func() { loggerInstance.Stop() }() logger = loggerInstance } dispatcherOptions := HoneyBadger.DispatcherOptions{ BufferedPerConnection: *bufferedPerConnection, BufferedTotal: *bufferedTotal, LogDir: *logDir, LogPackets: *logPackets, MaxPcapLogRotations: *maxNumPcapRotations, MaxPcapLogSize: *maxPcapLogSize, TcpIdleTimeout: *tcpTimeout, MaxRingPackets: *maxRingPackets, Logger: logger, DetectHijack: *detectHijack, DetectInjection: *detectInjection, DetectCoalesceInjection: *detectCoalesceInjection, MaxConcurrentConnections: *maxConcurrentConnections, } snifferDriverOptions := types.SnifferDriverOptions{ DAQ: *daq, Device: *iface, Filename: *pcapfile, WireDuration: wireDuration, Snaplen: int32(*snaplen), Filter: *filter, } connectionFactory := &HoneyBadger.DefaultConnFactory{} var packetLoggerFactory types.PacketLoggerFactory if *logPackets { packetLoggerFactory = logging.NewPcapLoggerFactory(*logDir, *archiveDir, *maxNumPcapRotations, *maxPcapLogSize) } else { packetLoggerFactory = nil } log.Println("HoneyBadger: comprehensive TCP injection attack detection.") options := HoneyBadger.SupervisorOptions{ SnifferDriverOptions: &snifferDriverOptions, DispatcherOptions: dispatcherOptions, SnifferFactory: HoneyBadger.NewSniffer, ConnectionFactory: connectionFactory, PacketLoggerFactory: packetLoggerFactory, } supervisor := HoneyBadger.NewSupervisor(options) supervisor.Run() }