def dumpmatchstats(): if len(opentcpflows) > 0 or len(openudpflows) > 0: if configopts['verbose'] and configopts['verboselevel'] >= 1: dumpopenstreams() print if len(ippacketsdict) > 0: if configopts['verbose'] and configopts['verboselevel'] >= 1: dumpippacketsdict() print writepackets() if configopts['verbose'] and configopts['verboselevel'] >= 1: print if 'quite' in configopts['outmodes']: print donorm('UDP Stats: { Processed: %d, Matched: %d { Shortest: %dB (#%d), Longest: %dB (#%d) }}' % ( configopts['inspudppacketct'], configopts['udpmatches'], configopts['shortestmatch']['packet'], configopts['shortestmatch']['packetid'], configopts['longestmatch']['packet'], configopts['longestmatch']['packetid'])) donorm('TCP Stats: { Processed: %d, Matched: %d { Shortest: %dB (#%d), Longest: %dB (#%d) }}' % ( configopts['insptcpstreamct'], configopts['tcpmatches'], configopts['shortestmatch']['stream'], configopts['shortestmatch']['streamid'], configopts['longestmatch']['stream'], configopts['longestmatch']['streamid']))
def dumpmatchstats(): if len(opentcpflows) > 0 or len(openudpflows) > 0: if configopts['verbose'] and configopts['verboselevel'] >= 1: dumpopenstreams() print if len(ippacketsdict) > 0: if configopts['verbose'] and configopts['verboselevel'] >= 1: dumpippacketsdict() print writepackets() if configopts['verbose'] and configopts['verboselevel'] >= 1: print if 'quite' in configopts['outmodes']: print donorm( 'UDP Stats: { Processed: %d, Matched: %d { Shortest: %dB (#%d), Longest: %dB (#%d) }}' % (configopts['inspudppacketct'], configopts['udpmatches'], configopts['shortestmatch']['packet'], configopts['shortestmatch']['packetid'], configopts['longestmatch']['packet'], configopts['longestmatch']['packetid'])) donorm( 'TCP Stats: { Processed: %d, Matched: %d { Shortest: %dB (#%d), Longest: %dB (#%d) }}' % (configopts['insptcpstreamct'], configopts['tcpmatches'], configopts['shortestmatch']['stream'], configopts['shortestmatch']['streamid'], configopts['longestmatch']['stream'], configopts['longestmatch']['streamid']))
def doexit(): configopts['endtime'] = getcurtime() configopts['totalruntime'] = configopts['endtime'] - configopts['starttime'] print donorm('Session completed in %s. Exiting.' % (configopts['totalruntime'])) if configopts['udpmatches'] > 0 or configopts['tcpmatches'] > 0: sys.exit(0) else: sys.exit(1)
def doexit(): configopts['endtime'] = getcurtime() configopts[ 'totalruntime'] = configopts['endtime'] - configopts['starttime'] print donorm('Session completed in %s. Exiting.' % (configopts['totalruntime'])) if configopts['udpmatches'] > 0 or configopts['tcpmatches'] > 0: sys.exit(0) else: sys.exit(1)
def handletcp(tcp): id = 0 showmatch = False addrkey = tcp.addr ((src, sport), (dst, dport)) = tcp.addr if not configopts['linemode']: if configopts['tcpdone']: if configopts['udpdone']: if configopts['verbose'] and configopts['verboselevel'] >= 1: if addrkey in opentcpflows: id = opentcpflows[addrkey]['id'] doinfo('[IP#%d.TCP#%d] Done inspecting max packets (%d) and max streams (%d), preparing for exit' % ( opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'], configopts['maxinsppackets'], configopts['maxinspstreams'])) exitwithstats() else: if configopts['verbose'] and configopts['verboselevel'] >= 1: if addrkey in opentcpflows: id = opentcpflows[addrkey]['id'] doinfo('[IP#%d.TCP#%d] Ignoring stream %s:%s %s %s:%s { insptcppacketct: %d == maxinspstreams: %d }' % ( opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'], src, sport, dst, dport, configopts['insptcppacketct'], configopts['maxinspstreams'])) return regexes = [] fuzzpatterns = [] yararuleobjects = [] timestamp = datetime.datetime.fromtimestamp(nids.get_pkt_ts()).strftime('%H:%M:%S | %Y/%m/%d') endstates = [ nids.NIDS_CLOSE, nids.NIDS_TIMED_OUT, nids.NIDS_RESET ] inspectcts = False inspectstc = False if len(configopts['ctsregexes']) > 0 or len(configopts['ctsfuzzpatterns']) > 0 or len(configopts['ctsyararules']) > 0: inspectcts = True if len(configopts['stcregexes']) > 0 or len(configopts['stcfuzzpatterns']) > 0 or len(configopts['stcyararules']) > 0: inspectstc = True if tcp.nids_state == nids.NIDS_JUST_EST: if addrkey not in opentcpflows: tcp.server.collect = 0 tcp.client.collect = 0 if configopts['verbose'] and configopts['verboselevel'] >= 1: doinfo('[IP#%d.TCP#%d] %s:%s - %s:%s remains untracked { IP tracking missed this flow }' % ( opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'], src, sport, dst, dport)) else: configopts['insptcpstreamct'] += 1 if configopts['verbose'] and configopts['verboselevel'] >= 1: doinfo('[IP#%d.TCP#%d] %s:%s - %s:%s [NEW] { TRACKED: %d }' % ( opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'], src, sport, dst, dport, len(opentcpflows))) if configopts['linemode'] or 'shellcode' in configopts['inspectionmodes']: tcp.server.collect = 1 tcp.client.collect = 1 if configopts['verbose'] and configopts['verboselevel'] >= 1: doinfo('[IP#%d.TCP#%d] Enabled both CTS and STC data collection for %s:%s - %s:%s' % ( opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'], src, sport, dst, dport)) else: if inspectcts or 'shellcode' in configopts['inspectionmodes']: tcp.server.collect = 1 if configopts['verbose'] and configopts['verboselevel'] >= 1: doinfo('[IP#%d.TCP#%d] Enabled CTS data collection for %s:%s - %s:%s' % ( opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'], src, sport, dst, dport)) if inspectstc or 'shellcode' in configopts['inspectionmodes']: tcp.client.collect = 1 if configopts['verbose'] and configopts['verboselevel'] >= 1: doinfo('[IP#%d.TCP#%d] Enabled STC data collection for %s:%s - %s:%s' % ( opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'], src, sport, dst, dport)) if tcp.nids_state == nids.NIDS_DATA: tcp.discard(0) configopts['insptcppacketct'] += 1 if tcp.server.count_new > 0: direction = configopts['ctsdirectionstring'] directionflag = configopts['ctsdirectionflag'] count = tcp.server.count newcount = tcp.server.count_new start = tcp.server.count - tcp.server.count_new end = tcp.server.count opentcpflows[addrkey]['totdatasize'] += tcp.server.count_new if configopts['offset'] > 0 and configopts['offset'] < count: offset = configopts['offset'] else: offset = 0 if configopts['depth'] > 0 and configopts['depth'] <= (count - offset): depth = configopts['depth'] + offset else: depth = count offset += opentcpflows[addrkey]['multimatchskipoffset'] configopts['inspoffset'] = offset inspdata = tcp.server.data[offset:depth] inspdatalen = len(inspdata) if 'regex' in configopts['inspectionmodes']: for regex in configopts['ctsregexes'].keys(): regexes.append(regex) if 'fuzzy' in configopts['inspectionmodes']: for fuzzpattern in configopts['ctsfuzzpatterns']: fuzzpatterns.append(fuzzpattern) if 'yara' in configopts['inspectionmodes']: for yararuleobj in configopts['ctsyararules']: yararuleobjects.append(yararuleobj) if tcp.client.count_new > 0: direction = configopts['stcdirectionstring'] directionflag = configopts['stcdirectionflag'] count = tcp.client.count newcount = tcp.client.count_new start = tcp.client.count - tcp.client.count_new end = tcp.client.count opentcpflows[addrkey]['totdatasize'] += tcp.client.count_new if configopts['offset'] > 0 and configopts['offset'] < count: offset = configopts['offset'] else: offset = 0 offset += opentcpflows[addrkey]['multimatchskipoffset'] configopts['inspoffset'] = offset if configopts['depth'] > 0 and configopts['depth'] < (count - offset): depth = offset + configopts['depth'] else: depth = count inspdata = tcp.client.data[offset:depth] inspdatalen = len(inspdata) if 'regex' in configopts['inspectionmodes']: for regex in configopts['stcregexes'].keys(): regexes.append(regex) if 'fuzzy' in configopts['inspectionmodes']: for fuzzpattern in configopts['stcfuzzpatterns']: fuzzpatterns.append(fuzzpattern) if 'yara' in configopts['inspectionmodes']: for yararuleobj in configopts['stcyararules']: yararuleobjects.append(yararuleobj) if configopts['verbose'] and configopts['verboselevel'] >= 1: doinfo('[IP#%d.TCP#%d] %s:%s %s %s:%s [%dB] { CTS: %d, STC: %d, TOT: %d }' % ( opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'], src, sport, directionflag, dst, dport, newcount, tcp.server.count, tcp.client.count, opentcpflows[addrkey]['totdatasize'])) if configopts['linemode']: matchstats['addr'] = addrkey matchstats['start'] = start matchstats['end'] = end matchstats['matchsize'] = matchstats['end'] - matchstats['start'] matchstats['direction'] = direction matchstats['directionflag'] = directionflag donorm('[IP#%d.TCP#%d] Skipping inspection as linemode is enabled.' % (opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'])) showtcpmatches(inspdata[matchstats['start']:matchstats['end']]) if configopts['writepcap']: markmatchedippackets(addrkey) return if configopts['maxinspstreams'] != 0 and configopts['insptcppacketct'] >= configopts['maxinspstreams']: configopts['tcpdone'] = True if configopts['verbose'] and configopts['verboselevel'] >= 1: doinfo('[IP#%d.TCP#%d] Initiating inspection on %s[%d:%d] - %dB' % ( opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'], direction, offset, depth, inspdatalen)) matched = inspect('TCP', inspdata, inspdatalen, regexes, fuzzpatterns, yararuleobjects, addrkey, direction, directionflag) if matched: if configopts['killtcp']: tcp.kill if configopts['writepcap']: markmatchedippackets(addrkey) elif configopts['writepcapfast']: if addrkey in ippacketsdict.keys() and ippacketsdict[addrkey]['proto'] == 'TCP': ippacketsdict[addrkey]['matched'] = True ippacketsdict[addrkey]['id'] = opentcpflows[addrkey]['id'] ippacketsdict[addrkey]['matchedid'] = len(ippacketsdict[addrkey].keys()) - configopts['ipmetavars'] else: ((sip, sp), (dip, dp)) = addrkey newaddrkey = ((dip, dp), (sip, sp)) if newaddrkey in ippacketsdict.keys() and ippacketsdict[newaddrkey]['proto'] == 'TCP': ippacketsdict[newaddrkey]['matched'] = True ippacketsdict[newaddrkey]['id'] = opentcpflows[newaddrkey]['id'] ippacketsdict[newaddrkey]['matchedid'] = len(ippacketsdict[newaddrkey].keys()) - configopts['ipmetavars'] if direction == configopts['ctsdirectionstring']: matchstats['direction'] = configopts['ctsdirectionstring'] matchstats['directionflag'] = configopts['ctsdirectionflag'] elif direction == 'STC': matchstats['direction'] = configopts['stcdirectionstring'] matchstats['directionflag'] = configopts['stcdirectionflag'] if configopts['tcpmatches'] == 0: configopts['shortestmatch']['stream'] = matchstats['matchsize'] configopts['shortestmatch']['streamid'] = opentcpflows[addrkey]['id'] configopts['longestmatch']['stream'] = matchstats['matchsize'] configopts['longestmatch']['streamid'] = opentcpflows[addrkey]['id'] else: if matchstats['matchsize'] <= configopts['shortestmatch']['stream']: configopts['shortestmatch']['stream'] = matchstats['matchsize'] configopts['shortestmatch']['streamid'] = opentcpflows[addrkey]['id'] if matchstats['matchsize'] >= configopts['longestmatch']['stream']: configopts['longestmatch']['stream'] = matchstats['matchsize'] configopts['longestmatch']['streamid'] = opentcpflows[addrkey]['id'] configopts['tcpmatches'] += 1 matchstats['addr'] = addrkey showtcpmatches(inspdata[matchstats['start']:matchstats['end']]) if not configopts['tcpmultimatch']: tcp.server.collect = 0 tcp.client.collect = 0 if configopts['verbose'] and configopts['verboselevel'] >= 1: doinfo('[IP#%d.TCP#%d] %s:%s - %s:%s not being tracked any further { tcpmultimatch: %s }' % ( opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'], src, sport, dst, dport, configopts['tcpmultimatch'])) del opentcpflows[addrkey] else: if direction == configopts['ctsdirectionstring']: opentcpflows[addrkey]['ctspacketlendict'].clear() elif direction == configopts['stcdirectionstring']: opentcpflows[addrkey]['stcpacketlendict'].clear() opentcpflows[addrkey]['multimatchskipoffset'] += matchstats['end'] if configopts['verbose'] and configopts['verboselevel'] >= 1: doinfo('[IP#%d.TCP#%d] Marked %dB to be skipped for further %s inspection' % ( opentcpflows[addrkey]['ipct'], opentcpflows[addrkey]['id'], opentcpflows[addrkey]['multimatchskipoffset'], direction)) else: opentcpflows[addrkey]['previnspbufsize'] = inspdatalen if tcp.nids_state in endstates: if addrkey in opentcpflows: ipct = opentcpflows[addrkey]['ipct'] id = opentcpflows[addrkey]['id'] del opentcpflows[addrkey] if configopts['verbose'] and configopts['verboselevel'] >= 1: if tcp.nids_state == nids.NIDS_CLOSE: state = 'FIN' elif tcp.nids_state == nids.NIDS_TIMED_OUT: state = 'TIMED_OUT' elif tcp.nids_state == nids.NIDS_RESET: state = 'RST' else: state = 'UNKNOWN' doinfo('[IP#%d.TCP#%d] %s:%s - %s:%s [%s] { TRACKED: %d }' % ( ipct, id, src, sport, dst, dport, state, len(opentcpflows)))
configopts['killtcp'] = False configopts['livemode'] = False if args.dumpargs: dumpargstats(configopts) try: nids.chksum_ctl([('0.0.0.0/0', False)]) nids.param('scan_num_hosts', 0) nids.init() nids.register_ip(handleip) nids.register_udp(handleudp) nids.register_tcp(handletcp) donorm('NIDS initialized, waiting for events...') print try: nids.run() except KeyboardInterrupt: print dumpmatchstats() doexit() except nids.error, nx: print doerror('NIDS error: %s' % nx) print sys.exit(1)
configopts['killtcp'] = False configopts['livemode'] = False if args.dumpargs: dumpargstats(configopts) try: nids.chksum_ctl([('0.0.0.0/0', False)]) nids.param('scan_num_hosts', 0) nids.init() nids.register_ip(handleip) nids.register_udp(handleudp) nids.register_tcp(handletcp) donorm('NIDS initialized, waiting for events...') print try: nids.run() except KeyboardInterrupt: print dumpmatchstats() doexit() except nids.error, nx: print doerror('NIDS error: %s' % nx) print sys.exit(1) # except Exception, ex: