Exemplo n.º 1
0
def dumpippacketsdict():
    doinfo('Dumping IP packets dictionary: %d' % len(ippacketsdict.keys()))
    for key in ippacketsdict.keys():
        ((src, sport), (dst, dport)) = key
        doinfo('[%s#%08d] %s:%s - %s:%s { Packets: %d, Matched: %s}' %
               (ippacketsdict[key]['proto'], ippacketsdict[key]['id'], src,
                sport, dst, dport, len(ippacketsdict[key].keys()) -
                configopts['ipmetavars'], ippacketsdict[key]['matched']))
Exemplo n.º 2
0
def dumpippacketsdict():
    doinfo('Dumping IP packets dictionary: %d' % len(ippacketsdict.keys()))
    for key in ippacketsdict.keys():
        ((src, sport), (dst, dport)) = key
        doinfo('[%s#%08d] %s:%s - %s:%s { Packets: %d, Matched: %s}' % (
            ippacketsdict[key]['proto'],
            ippacketsdict[key]['id'],
            src,
            sport,
            dst,
            dport,
            len(ippacketsdict[key].keys()) - configopts['ipmetavars'],
            ippacketsdict[key]['matched']))
Exemplo n.º 3
0
def markmatchedippackets(addrkey):
    ((src, sport), (dst, dport)) = addrkey
    ((sip, sp), (dip, dp)) = addrkey
    newaddrkey = ((dip, dp), (sip, sp))

    if addrkey in ippacketsdict.keys(
    ) and ippacketsdict[addrkey]['proto'] == 'UDP':
        ippacketsdict[addrkey]['matched'] = True
        ippacketsdict[addrkey]['id'] = configopts['packetct']
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo(
                '[IP#%d.UDP#%d] Flow %s:%s - %s:%s marked to be written to a pcap'
                % (openudpflows[key]['ipct'], openudpflows[key]['id'], src,
                   sport, dst, dport))

    elif newaddrkey in ippacketsdict.keys(
    ) and ippacketsdict[newaddrkey]['proto'] == 'UDP':
        ippacketsdict[newaddrkey]['matched'] = True
        ippacketsdict[newaddrkey]['id'] = configopts['packetct']
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo(
                '[IP#%d.UDP#%d] Flow %s:%s - %s:%s marked to be written to a pcap'
                % (openudpflows[key]['ipct'], openudpflows[key]['id'], src,
                   sport, dst, dport))

    elif configopts['verbose'] and configopts['verboselevel'] >= 1:
        doinfo(
            '[IP#%d.UDP#%d] Flow %s:%s - %s:%s not found in ippacketsdict, something\'s wrong'
            % (openudpflows[key]['ipct'], openudpflows[key]['id'], src, sport,
               dst, dport))
Exemplo n.º 4
0
def dumpopenstreams():
    if len(openudpflows) > 0:
        print
        doinfo('Dumping open/tracked UDP streams: %d' % len(openudpflows))

        for (key, value) in openudpflows.items():
            id = value['id']
            keydst = value['keydst']
            matches = value['matches']
            ctsdatasize = value['ctsdatasize']
            stcdatasize = value['stcdatasize']
            totdatasize = value['totdatasize']
            doinfo('[%08d] %s - %s { CTS: %dB, STC: %dB, TOT: %dB } { matches: %d }' % (
                    id,
                    key,
                    keydst,
                    ctsdatasize,
                    stcdatasize,
                    totdatasize,
                    matches))

    if len(opentcpflows) > 0:
        print
        doinfo('Dumping open/tracked TCP streams: %d' % (len(opentcpflows)))

        for (key, value) in opentcpflows.items():
            id = value['id']
            ((src, sport), (dst, dport)) = key

            ctsdatasize = 0
            for size in value['ctspacketlendict'].values():
                ctsdatasize += size

            stcdatasize = 0
            for size in value['stcpacketlendict'].values():
                stcdatasize += size

            totdatasize = ctsdatasize + stcdatasize
            doinfo('[%08d] %s:%s - %s:%s { CTS: %dB, STC: %dB, TOT: %dB }' % (
                    id,
                    src,
                    sport,
                    dst,
                    dport,
                    ctsdatasize,
                    stcdatasize,
                    totdatasize))
Exemplo n.º 5
0
def dumpopenstreams():
    if len(openudpflows) > 0:
        print
        doinfo('Dumping open/tracked UDP streams: %d' % len(openudpflows))

        for (key, value) in openudpflows.items():
            id = value['id']
            keydst = value['keydst']
            matches = value['matches']
            ctsdatasize = value['ctsdatasize']
            stcdatasize = value['stcdatasize']
            totdatasize = value['totdatasize']
            doinfo(
                '[%08d] %s - %s { CTS: %dB, STC: %dB, TOT: %dB } { matches: %d }'
                % (id, key, keydst, ctsdatasize, stcdatasize, totdatasize,
                   matches))

    if len(opentcpflows) > 0:
        print
        doinfo('Dumping open/tracked TCP streams: %d' % (len(opentcpflows)))

        for (key, value) in opentcpflows.items():
            id = value['id']
            ((src, sport), (dst, dport)) = key

            ctsdatasize = 0
            for size in value['ctspacketlendict'].values():
                ctsdatasize += size

            stcdatasize = 0
            for size in value['stcpacketlendict'].values():
                stcdatasize += size

            totdatasize = ctsdatasize + stcdatasize
            doinfo('[%08d] %s:%s - %s:%s { CTS: %dB, STC: %dB, TOT: %dB }' %
                   (id, src, sport, dst, dport, ctsdatasize, stcdatasize,
                    totdatasize))
Exemplo n.º 6
0
def markmatchedippackets(addrkey):
    ((src, sport), (dst, dport)) = addrkey
    ((sip, sp), (dip, dp)) = addrkey
    newaddrkey = ((dip, dp), (sip, sp))

    if addrkey in ippacketsdict.keys() and ippacketsdict[addrkey]['proto'] == 'TCP':
        ippacketsdict[addrkey]['matched'] = True
        ippacketsdict[addrkey]['id'] = opentcpflows[addrkey]['id']
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.TCP#%d] Flow %s:%s - %s:%s marked to be written to a pcap' % (
                    opentcpflows[matchstats['addr']]['ipct'],
                    opentcpflows[matchstats['addr']]['id'],
                    src,
                    sport,
                    dst,
                    dport))

    elif newaddrkey in ippacketsdict.keys() and ippacketsdict[newaddrkey]['proto'] == 'TCP':
        ippacketsdict[newaddrkey]['matched'] = True
        ippacketsdict[newaddrkey]['id'] = opentcpflows[addrkey]['id']
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.TCP#%d] Flow %s:%s - %s:%s marked to be written to a pcap' % (
                    opentcpflows[matchstats['addr']]['ipct'],
                    opentcpflows[matchstats['addr']]['id'],
                    src,
                    sport,
                    dst,
                    dport))

    elif not configopts['linemode']:
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.TCP#%d] Flow %s:%s - %s:%s not found in ippacketsdict, something\'s wrong' % (
                    opentcpflows[matchstats['addr']]['ipct'],
                    opentcpflows[matchstats['addr']]['id'],
                    src,
                    sport,
                    dst,
                    dport))
Exemplo n.º 7
0
def showtcpmatches(data):
    proto = 'TCP'

    if configopts['maxdispbytes'] > 0: maxdispbytes = configopts['maxdispbytes']
    else: maxdispbytes = len(data)

    ((src, sport), (dst, dport)) = matchstats['addr']
    filename = '%s/%s-%08d-%s.%s-%s.%s-%s' % (configopts['logdir'], proto, opentcpflows[matchstats['addr']]['id'], src, sport, dst, dport, matchstats['direction'])

    if configopts['writelogs']:
        writetofile(filename, data)

        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.TCP#%d] Wrote %dB to %s' % (
                    opentcpflows[matchstats['addr']]['ipct'],
                    opentcpflows[matchstats['addr']]['id'],
                    matchstats['matchsize'],
                    filename))

    if 'quite' in configopts['outmodes']:
        if matchstats['detectiontype'] == 'regex':
            pattern = getregexpattern(matchstats['regex'])
        elif matchstats['detectiontype'] == 'fuzzy':
            if matchstats['direction'] == 'CTS':
                pattern = configopts['ctsfuzzpatterns']
            else:
                pattern = configopts['stcfuzzpaterns']
        else:
            pattern = None

        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.TCP#%d] %s:%s %s %s:%s matches \'%s\' @ [%d:%d] - %dB' % (
                        opentcpflows[matchstats['addr']]['ipct'],
                        opentcpflows[matchstats['addr']]['id'],
                        src,
                        sport,
                        matchstats['directionflag'],
                        dst,
                        dport,
                        pattern,
                        matchstats['start'],
                        matchstats['end'],
                        matchstats['matchsize']))
        return

    if configopts['maxdispstreams'] != 0 and configopts['dispstreamct'] >= configopts['maxdispstreams']:
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('Skipping outmode parsing { dispstreamct: %d == maxdispstreams: %d }' % (
                    configopts['dispstreamct'],
                    configopts['maxdispstreams']))
        return

    direction = matchstats['direction']
    startpacket = 0
    endpacket = 0
    if 'meta' in configopts['outmodes']:
        if configopts['invertmatch']:
            invertstatus = " (invert)"
        else:
            invertstatus = ""

        id = opentcpflows[matchstats['addr']]['id']

        if matchstats['direction'] == 'CTS':
            packetlendict = opentcpflows[matchstats['addr']]['ctspacketlendict']
        else:
            packetlendict = opentcpflows[matchstats['addr']]['stcpacketlendict']

        direction = matchstats['direction']
        directionflag = matchstats['directionflag']
        start = matchstats['start']
        end = matchstats['end']
        matchsize = matchstats['matchsize']

        totalcount = 0
        startpacket = 0
        endpacket = 0
        if len(packetlendict) == 1:
            startpacket = packetlendict.keys()[0]
            endpacket = startpacket
        else:
            for (pktid, pktlen) in collections.OrderedDict(sorted(packetlendict.items())).items():
                totalcount += pktlen

                if start <= totalcount and startpacket == 0 and pktlen != 0:
                    startpacket = pktid

                if end <= totalcount:
                    endpacket = pktid

                if configopts['verbose'] and configopts['verboselevel'] >= 5:
                    dodebug('(%06d:%06d) start:%d <= totalcount:%06d | end:%d <= totalcount:%06d ... %s|%-5s\t' % (
                                pktid, pktlen, start, totalcount, end, totalcount, (start <= totalcount), (end <= totalcount)))

                if endpacket != 0:
                    if configopts['verbose'] and configopts['verboselevel'] >= 5:
                        dodebug('startpacket: %d - endpacket: %d' % (startpacket, endpacket))
                    break

            if startpacket > endpacket:
                startpacket, endpacket = endpacket, startpacket

        if matchstats['detectiontype'] == 'regex':
            if direction == configopts['ctsdirectionstring']:
                regexpattern = configopts['ctsregexes'][matchstats['regex']]['regexpattern']
            elif direction == configopts['stcdirectionstring']:
                regexpattern = configopts['stcregexes'][matchstats['regex']]['regexpattern']

            metastr = 'matches regex%s: \'%s\'' % (invertstatus, regexpattern)

        elif matchstats['detectiontype'] == 'fuzzy':
            metastr = 'matches \'%s\' %s%s' % (matchstats['fuzzpattern'], matchstats['fuzzmatchdetails'], invertstatus)

        elif matchstats['detectiontype'] == 'shellcode':
            metastr = 'contains shellcode [Offset: %d]%s' % (matchstats['shellcodeoffset'], invertstatus)

        elif matchstats['detectiontype'] == 'yara':
            metastr = 'matches rule: \'%s\' from %s' % (matchstats['yararulename'], matchstats['yararulefilepath'])

        else:
            metastr = ''

        if not configopts['linemode']:
            packetstats = ' | packet[%d] - packet[%d]' % (startpacket, endpacket)
        else:
            packetstats = ''

        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            bpfstr = generate_bpf("TCP", src, sport, directionflag, dst, dport)
            doinfo('[IP#%d.TCP#%d] BPF: %s' % (opentcpflows[matchstats['addr']]['ipct'], opentcpflows[matchstats['addr']]['id'], bpfstr))

        print '[MATCH] (%08d/%08d) [IP#%d.TCP#%d] %s:%s %s %s:%s %s' % (
                configopts['insptcppacketct'],
                configopts['tcpmatches'],
                opentcpflows[matchstats['addr']]['ipct'],
                opentcpflows[matchstats['addr']]['id'],
                src,
                sport,
                directionflag,
                dst,
                dport,
                metastr)

        print '[MATCH] (%08d/%08d) [IP#%d.TCP#%d] match @ %s[%d:%d] (%dB%s)' % (
                configopts['insptcppacketct'],
                configopts['tcpmatches'],
                opentcpflows[matchstats['addr']]['ipct'],
                opentcpflows[matchstats['addr']]['id'],
                direction,
                start + configopts['inspoffset'],
                end + configopts['inspoffset'],
                matchsize,
                packetstats)

    if 'print' in configopts['outmodes']:
        if configopts['colored']:
            if direction == configopts['ctsdirectionstring']:
                printable(data[:maxdispbytes], configopts['ctsoutcolor'])
            elif direction == configopts['stcdirectionstring']:
                printable(data[:maxdispbytes], configopts['stcoutcolor'])
        else:
            printable(data[:maxdispbytes], None)

    if 'raw' in configopts['outmodes']:
        if configopts['colored']:
            print colored(data[:maxdispbytes])
        else:
            print data[:maxdispbytes]

    if 'hex' in configopts['outmodes']:
        if configopts['colored']:
            if direction == configopts['ctsdirectionstring']:
                hexdump(data[:maxdispbytes], configopts['ctsoutcolor'])
            elif direction == configopts['stcdirectionstring']:
                hexdump(data[:maxdispbytes], configopts['stcoutcolor'])
        else:
            hexdump(data[:maxdispbytes], None)

    if configopts['asm4shellcode']:
        print
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.TCP#%d] Generating disassembled output for %dB of detected shellcode' % (
                        opentcpflows[matchstats['addr']]['ipct'],
                        opentcpflows[matchstats['addr']]['id'],
                        len(data)))
        dumpasm(data)

    configopts['dispstreamct'] += 1

    if not configopts['colored']:
        print
Exemplo n.º 8
0
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)))
Exemplo n.º 9
0
    if args.nosummary:
        configopts['nosummary'] = True

    configopts['starttime'] = starttime

    if not configopts['nobanner']:
        print '%s' % (banner)
        print '          %s - %s' % (configopts['name'], configopts['desc'])
        print '          %s' % configopts['author']
        print

    if not configopts['inspectionmodes'] and not configopts['linemode']:
        configopts['linemode'] = True
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('Inspection disabled as no mode selected/available')
            doinfo('Fallback - linemode enabled')
            print

    if configopts['writepcapfast'] and configopts['linemode']:
        configopts['writepcapfast'] = False
        configopts['writepcap'] = True
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo(
                'Fast pcap writing is incompatible with linemode. Using slow pcap writing as fallback.'
            )

    if configopts['writepcapfast'] and configopts['tcpmultimatch']:
        configopts['writepcapfast'] = False
        configopts['writepcap'] = True
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
Exemplo n.º 10
0
    if args.nosummary:
        configopts['nosummary'] = True

    configopts['starttime'] = starttime

    if not configopts['nobanner']:
        print '%s' % (banner)
        print '          %s - %s' % (configopts['name'], configopts['desc'])
        print '          %s' % configopts['author']
        print

    if not configopts['inspectionmodes'] and not configopts['linemode']:
        configopts['linemode'] = True
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('Inspection disabled as no mode selected/available')
            doinfo('Fallback - linemode enabled')
            print

    if configopts['writepcapfast'] and configopts['linemode']:
        configopts['writepcapfast'] = False
        configopts['writepcap'] = True
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('Fast pcap writing is incompatible with linemode. Using slow pcap writing as fallback.')

    if configopts['writepcapfast'] and configopts['tcpmultimatch']:
        configopts['writepcapfast'] = False
        configopts['writepcap'] = True
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('Fast pcap writing is incompatible with multimatch. Using slow pcap writing as fallback.')
Exemplo n.º 11
0
def showudpmatches(data):
    proto = 'UDP'

    ((src, sport), (dst, dport)) = matchstats['addr']

    key = "%s:%s" % (src, sport)
    if key not in openudpflows:
        key = "%s:%s" % (dst, dport)

    if configopts['maxdispbytes'] > 0: maxdispbytes = configopts['maxdispbytes']
    else: maxdispbytes = len(data)

    filename = '%s/%s-%08d-%s.%s-%s.%s-%s' % (configopts['logdir'], proto, configopts['packetct'], src, sport, dst, dport, matchstats['direction'])

    if configopts['writelogs']:
        writetofile(filename, data)

        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.UDP#%d] Wrote %dB to %s/%s-%08d.%s.%s.%s.%s' % (
                    openudpflows[key]['ipct'],
                    openudpflows[key]['id'],
                    matchstats['matchsize'],
                    configopts['logdir'],
                    proto,
                    configopts['packetct'],
                    src,
                    sport,
                    dst,
                    dport))

    if 'quite' in configopts['outmodes']:
        if matchstats['regex']:
            pattern = getregexpattern(matchstats['regex'])
        else:
            pattern = None

        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.UDP#%d] %s:%s %s %s:%s matches \'%s\' @ [%d:%d] - %dB' % (
                    openudpflows[key]['ipct'],
                    openudpflows[key]['id'],
                    src,
                    sport,
                    matchstats['directionflag'],
                    dst,
                    dport,
                    pattern,
                    matchstats['start'],
                    matchstats['end'],
                    matchstats['matchsize']))
        return

    if configopts['maxdisppackets'] != 0 and configopts['disppacketct'] >= configopts['maxdisppackets']:
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('Skipping outmode parsing { disppacketct: %d == maxdisppackets: %d }' % (
                    configopts['disppacketct'],
                    configopts['maxdisppackets']))
        return

    direction = matchstats['direction']
    directionflag = matchstats['directionflag']
    if 'meta' in configopts['outmodes']:
        if configopts['invertmatch']:
            invertstatus = " (invert)"
        else:
            invertstatus = ""

        start = matchstats['start']
        end = matchstats['end']
        matchsize = matchstats['matchsize']

        if matchstats['detectiontype'] == 'regex':
            metastr = 'matches regex%s: \'%s\'' % (invertstatus, getregexpattern(matchstats['regex']))

        elif matchstats['detectiontype'] == 'shellcode':
            metastr = 'contains shellcode [Offset: %d]%s' % (matchstats['shellcodeoffset'], invertstatus)

        elif matchstats['detectiontype'] == 'yara':
            metastr = 'matches rule: \'%s\' from %s' % (matchstats['yararulename'], matchstats['yararulefilepath'])

        else:
            metastr = ''

        if configopts['verbose'] and configopts['verboselevel'] >= 1:
             bpfstr = generate_bpf("UDP", src, sport, directionflag, dst, dport)
             doinfo('[IP#%d.UDP#%d] BPF: %s' % (
                openudpflows[key]['ipct'],
                openudpflows[key]['id'],
                bpfstr))

        print '[MATCH] (%08d/%08d) [IP#%d.UDP#%d] %s:%s %s %s:%s %s' % (
                configopts['inspudppacketct'],
                configopts['udpmatches'],
                openudpflows[key]['ipct'],
                openudpflows[key]['id'],
                src,
                sport,
                directionflag,
                dst,
                dport,
                metastr)

        print '[MATCH] (%08d/%08d) [IP#%d.UDP#%d] match @ %s[%d:%d] (%dB)' % (
                configopts['inspudppacketct'],
                configopts['udpmatches'],
                openudpflows[key]['ipct'],
                openudpflows[key]['id'],
                direction,
                start,
                end,
                matchsize)

    if 'print' in configopts['outmodes']:
        if configopts['colored']:
            if direction == configopts['ctsdirectionstring']:
                printable(data[:maxdispbytes], configopts['ctsoutcolor'])
            elif direction == configopts['stcdirectionstring']:
                printable(data[:maxdispbytes], configopts['stcoutcolor'])
        else:
            printable(data[:maxdispbytes], None)

    if 'raw' in configopts['outmodes']:
        if configopts['colored']:
            print colored(data[:maxdispbytes])
        else:
            print data[:maxdispbytes]

    if 'hex' in configopts['outmodes']:
        if configopts['colored']:
            if direction == configopts['ctsdirectionstring']:
                hexdump(data[:maxdispbytes], configopts['ctsoutcolor'])
            elif direction == configopts['stcdirectionstring']:
                hexdump(data[:maxdispbytes], configopts['stcoutcolor'])
        else:
            hexdump(data[:maxdispbytes], None)

    if configopts['asm4shellcode']:
        print
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
             doinfo('[IP#%d.UDP#%d] Generating disassembled output for %dB of detected shellcode' % (
                        openudpflows[key]['ipct'],
                        openudpflows[key]['id'],
                        len(data)))
        dumpasm(data)

    configopts['dispstreamct'] += 1

    if not configopts['colored']:
        print
Exemplo n.º 12
0
def handleudp(addr, payload, pkt):
    showmatch = False
    addrkey = addr
    ((src, sport), (dst, dport)) = addr
    count = len(payload)
    start = 0
    end = count
    data = payload

    if len(configopts['ctsregexes']) > 0 or len(configopts['ctsfuzzpatterns']) > 0 or len(configopts['ctsyararules']) > 0:
        inspectcts = True
    else:
        inspectcts = False

    if len(configopts['stcregexes']) > 0 or len(configopts['stcfuzzpatterns']) > 0 or len(configopts['stcyararules']) > 0:
        inspectstc = True
    else:
        inspectstc = False

    keya = "%s:%s" % (src, sport)
    keyb = "%s:%s" % (dst, dport)
    key = None
    if keya in openudpflows:
        key = "%s:%s" % (src, sport)
        keydst = "%s:%s" % (dst, dport)
        direction = configopts['ctsdirectionstring']
        directionflag = configopts['ctsdirectionflag']
    elif keyb in openudpflows:
        key = "%s:%s" % (dst, dport)
        keydst = "%s:%s" % (src, sport)
        direction = configopts['stcdirectionstring']
        directionflag = configopts['stcdirectionflag']

    if key in openudpflows and openudpflows[key]['keydst'] == keydst:
        openudpflows[key]['totdatasize'] += count
    else:
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.UDP#%d] %s:%s - %s:%s remains untracked { IP tracking missed this flow }' % (
                        openudpflows[key]['ipct'],
                        openudpflows[key]['id'],
                        src,
                        sport,
                        dst,
                        dport))

    regexes = []
    fuzzpatterns = []
    yararuleobjects = []
    timestamp = datetime.datetime.fromtimestamp(nids.get_pkt_ts()).strftime('%H:%M:%S | %Y/%m/%d')

    if direction == configopts['ctsdirectionstring']:
        openudpflows[key]['ctsdatasize'] += count
        if 'regex' in configopts['inspectionmodes']:
            for regex in configopts['ctsregexes']:
                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)

    elif direction == configopts['stcdirectionstring']:
        openudpflows[key]['stcdatasize'] += count
        if 'regex' in configopts['inspectionmodes']:
            for regex in configopts['stcregexes']:
                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.UDP#%d] %s %s %s [%dB] { TRACKED: %d } { CTS: %dB, STC: %dB, TOT: %dB }' % (
                openudpflows[key]['ipct'],
                openudpflows[key]['id'],
                key,
                directionflag,
                keydst,
                count,
                len(openudpflows),
                openudpflows[key]['ctsdatasize'],
                openudpflows[key]['stcdatasize'],
                openudpflows[key]['totdatasize']))

    if not configopts['linemode']:
        if configopts['udpdone']:
            if configopts['tcpdone']:
                if configopts['verbose'] and configopts['verboselevel'] >= 1:
                    doinfo('Done inspecting max packets (%d) and max streams (%d), \
                            preparing for exit' % (
                            configopts['maxinsppackets'],
                            configopts['maxinspstreams']))
                exitwithstats()
            else:
                if configopts['verbose'] and configopts['verboselevel'] >= 1:
                    doinfo('Ignoring packet %s:%s %s %s:%s { inspudppacketct: %d == maxinsppackets: %d }' % (
                            src,
                            sport,
                            dst,
                            dport,
                            configopts['inspudppacketct'],
                            configopts['maxinsppackets']))
            return

    configopts['inspudppacketct'] += 1

    if configopts['linemode']:
        matchstats['addr'] = addrkey
        matchstats['start'] = start
        matchstats['end'] = end
        matchstats['matchsize'] = matchstats['end'] - matchstats['start']
        matchstats['direction'] = direction
        matchstats['directionflag'] = directionflag
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.UDP#%d] Skipping inspection as linemode is enabled.' % (
                        openudpflows[key]['ipct'],
                        openudpflows[key]['id']))
        showudpmatches(data[matchstats['start']:matchstats['end']])

        if configopts['writepcap']:
            markmatchedippackets(addrkey)
        return

    if configopts['maxinsppackets'] != 0 and configopts['inspudppacketct'] >= configopts['maxinsppackets']:
        configopts['udpdone'] = True

    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

    inspdata = data[offset:depth]
    inspdatalen = len(inspdata)

    if configopts['verbose'] and configopts['verboselevel'] >= 1:
        doinfo('[IP#%d.UDP#%d] Initiating inspection on %s[%d:%d] - %dB' % (
                openudpflows[key]['ipct'],
                openudpflows[key]['id'],
                direction,
                offset,
                depth,
                inspdatalen))

    matched = inspect('UDP', inspdata, inspdatalen, regexes, fuzzpatterns, yararuleobjects, addrkey, direction, directionflag)

    if matched:
        openudpflows[key]['matches'] += 1

        if configopts['writepcap']:
            markmatchedippackets(addrkey)

        if configopts['writepcapfast']:
            if addrkey in ippacketsdict.keys() and ippacketsdict[addrkey]['proto'] == 'UDP':
                ippacketsdict[addrkey]['matched'] = True
                ippacketsdict[addrkey]['id'] = configopts['packetct']
                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'] == 'UDP':
                    ippacketsdict[newaddrkey]['matched'] = True
                    ippacketsdict[newaddrkey]['id'] = configopts['packetct']
                    ippacketsdict[newaddrkey]['matchedid'] = len(ippacketsdict[newaddrkey].keys()) - configopts['ipmetavars']

        matchstats['start'] += offset
        matchstats['end'] += offset

        matchstats['direction'] = direction
        matchstats['directionflag'] = directionflag

        if configopts['udpmatches'] == 0:
            configopts['shortestmatch']['packet'] = matchstats['matchsize']
            configopts['shortestmatch']['packetid'] = configopts['packetct']
            configopts['longestmatch']['packet'] = matchstats['matchsize']
            configopts['longestmatch']['packetid'] = configopts['packetct']
        else:
            if matchstats['matchsize'] <= configopts['shortestmatch']['packet']:
                configopts['shortestmatch']['packet'] = matchstats['matchsize']
                configopts['shortestmatch']['packetid'] = configopts['packetct']

            if matchstats['matchsize'] >= configopts['longestmatch']['packet']:
                configopts['longestmatch']['packet'] = matchstats['matchsize']
                configopts['longestmatch']['packetid'] = configopts['packetct']

        configopts['udpmatches'] += 1

        matchstats['addr'] = addrkey
        showudpmatches(data[matchstats['start']:matchstats['end']])
        del openudpflows[key]
Exemplo n.º 13
0
def inspect(proto, data, datalen, regexes, fuzzpatterns, yararuleobjects, addrkey, direction, directionflag):
    if configopts['regexengine'] == 're':
        import re
    if configopts['fuzzengine']:
        from fuzzywuzzy import fuzz
    if configopts['yaraengine']:
        import yara
    if configopts['shellcodeengine']:
        import pylibemu as emu

    skip = False
    matched = False

    ((src, sport), (dst, dport)) = addrkey

    if proto == 'TCP':
        ipct = opentcpflows[addrkey]['ipct']
        id = opentcpflows[addrkey]['id']
    elif proto == 'UDP':
        for key in openudpflows.keys():
            skey = '%s:%s' % (src, sport)
            dkey = '%s:%s' % (dst, dport)
            if skey == key:
                ipct = openudpflows[key]['ipct']
                id = openudpflows[key]['id']
                addrkey = skey
            elif dkey == key:
                ipct = openudpflows[key]['ipct']
                id = openudpflows[key]['id']
                addrkey = dkey

    if configopts['verbose'] and configopts['verboselevel'] >= 1:
        doinfo('[IP#%d.%s#%d] Received %dB for inspection from %s:%s %s %s:%s' % (
                ipct,
                proto,
                id,
                datalen,
                src,
                sport,
                directionflag,
                dst,
                dport))

    if 'regex' in configopts['inspectionmodes']:
        for regex in regexes:
            matchstats['match'] = regex.search(data)

            if direction == configopts['ctsdirectionstring']:
                regexpattern = configopts['ctsregexes'][regex]['regexpattern']
            elif direction == configopts['stcdirectionstring']:
                regexpattern = configopts['stcregexes'][regex]['regexpattern']

            if matchstats['match'] and not configopts['invertmatch']:
                matchstats['detectiontype'] = 'regex'
                matchstats['regex'] = regex
                matchstats['start'] = matchstats['match'].start()
                matchstats['end'] = matchstats['match'].end()
                matchstats['matchsize'] = matchstats['end'] - matchstats['start']
                if configopts['verbose'] and configopts['verboselevel'] >= 1:
                    doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s matches regex: \'%s\'' % (
                            ipct,
                            proto,
                            id,
                            src,
                            sport,
                            directionflag,
                            dst,
                            dport,
                            regexpattern))
                return True

            if not matchstats['match'] and configopts['invertmatch']:
                matchstats['detectiontype'] = 'regex'
                matchstats['regex'] = regex
                matchstats['start'] = 0
                matchstats['end'] = datalen
                matchstats['matchsize'] = matchstats['end'] - matchstats['start']
                if configopts['verbose'] and configopts['verboselevel'] >= 1:
                    doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s matches regex (invert): \'%s\'' % (
                            ipct,
                            proto,
                            id,
                            src,
                            sport,
                            directionflag,
                            dst,
                            dport,
                            regexpattern))
                return True

            if configopts['verbose'] and configopts['verboselevel'] >= 1:
                if configopts['invertmatch']:
                    invertstatus = " (invert)"
                else:
                    invertstatus = ""

                doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s did not match regex%s: \'%s\'' % (
                        ipct,
                        proto,
                        id,
                        src,
                        sport,
                        directionflag,
                        dst,
                        dport,
                        invertstatus,
                        regexpattern))

    if 'fuzzy' in configopts['inspectionmodes']:
        for pattern in fuzzpatterns:
            partialratio = fuzz.partial_ratio(data, pattern)

            if partialratio >= configopts['fuzzminthreshold']:
                if not configopts['invertmatch']:
                    matched = True
                    matchstr = 'matches'
                    matchreason = '>='
                else:
                    matched = False
                    matchstr = 'doesnot match'
                    matchreason = '|'
            else:
                if configopts['invertmatch']:
                    matched = True
                    matchstr = 'matches'
                    matchreason = '|'
                else:
                    matched = False
                    matchstr = 'doesnot match'
                    matchreason = '<'

            fuzzmatchdetails = "(ratio: %d %s threshold: %d)" % (partialratio, matchreason, configopts['fuzzminthreshold'])

            if configopts['verbose'] and configopts['verboselevel'] >= 1:
                doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s %s \'%s\' (ratio: %d %s threshold: %d)' % (
                        ipct,
                        proto,
                        id,
                        src,
                        sport,
                        directionflag,
                        dst,
                        dport,
                        matchstr,
                        pattern,
                        partialratio,
                        matchreason,
                        configopts['fuzzminthreshold']))

            if matched:
                matchstats['detectiontype'] = 'fuzzy'
                matchstats['fuzzpattern'] = pattern
                matchstats['start'] = 0
                matchstats['end'] = datalen
                matchstats['matchsize'] = matchstats['end'] - matchstats['start']
                matchstats['fuzzmatchdetails'] = fuzzmatchdetails
                return True

    if 'shellcode' in configopts['inspectionmodes']:
        emulator = emu.Emulator(configopts['emuprofileoutsize'])
        offset = emulator.shellcode_getpc_test(data)
        if offset < 0: offset = 0
        emulator.prepare(data, offset)
        emulator.test()

        matched = False
        invert = False
        invertstatus = ""

        if emulator.emu_profile_output: # shellcode found!
            if configopts['invertmatch']:
                matched = True
                invert = False
                invertstatus = ""
            else:
                matched = True
                invert = False
                invertstatus = ""
        else: # shellcode not found!
            if configopts['invertmatch']:
                matched = True
                invert = True
                invertstatus = " (invert)"
            else:
                matched = False
                invert = False
                invertstatus = ""

        if matched:
            emulator.free()
            matchstats['detectiontype'] = 'shellcode'
            matchstats['shellcodeoffset'] = offset
            matchstats['start'] = offset
            matchstats['end'] = datalen
            matchstats['matchsize'] = matchstats['end'] - matchstats['start']
            if configopts['verbose'] and configopts['verboselevel'] >= 1:
                doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s contains shellcode%s' % (
                        ipct,
                        proto,
                        id,
                        src,
                        sport,
                        directionflag,
                        dst,
                        dport,
                        invertstatus))

            if configopts['emuprofile'] and not invert:
                filename = '%s-%08d-%s.%s-%s.%s-%s.emuprofile' % (
                            proto,
                            id,
                            src,
                            sport,
                            dst,
                            dport,
                            direction)

                data = emulator.emu_profile_output.decode('utf8')

                if emulator.emu_profile_truncated and configopts['verbose'] and configopts['verboselevel'] >= 1:
                    doinfo('[IP#%d.%s#%d] Skipping emulator profile output generation as its truncated' % (ipct, proto, id))
                else:
                    fo = open(filename, 'w')
                    fo.write(data)
                    fo.close()
                    if configopts['verbose'] and configopts['verboselevel'] >= 1:
                        doinfo('[IP#%d.%s#%d] Wrote %d byte emulator profile output to %s' % (ipct, proto, id, len(data), filename))

            return True

        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s doesnot contain shellcode%s' % (
                            ipct,
                            proto,
                            id,
                            src,
                            sport,
                            directionflag,
                            dst,
                            dport,
                            invertstatus))

    if 'yara' in configopts['inspectionmodes']:
       for ruleobj in yararuleobjects:
            matchstats['start'] = -1
            matchstats['end'] = -1
            matchstats['yararulenamespace'] = None
            matchstats['yararulename'] = None
            matchstats['yararulemeta'] = None

            matches = ruleobj.match(data=data, callback=yaramatchcallback)

            if matches:
                if not configopts['invertmatch']: matched = True
                else: matched = False
            else:
                if configopts['invertmatch']: matched = True
                else: matched = False

            if matched:
                matchstats['detectiontype'] = 'yara'

                for rule in configopts['ctsyararules']:
                    if rule == ruleobj: matchstats['yararulefilepath'] = configopts['ctsyararules'][rule]['filepath']
                for rule in configopts['stcyararules']:
                    if rule == ruleobj: matchstats['yararulefilepath'] = configopts['stcyararules'][rule]['filepath']

                if matchstats['start'] == -1 and matchstats['end'] == -1:
                    matchstats['start'] = 0
                    matchstats['end'] = len(data)

                matchstats['matchsize'] = matchstats['end'] - matchstats['start']
                return True

            if configopts['verbose'] and configopts['verboselevel'] >= 1:
                if ruleobj in configopts['ctsyararules']:
                    filepath = configopts['ctsyararules'][ruleobj]['filepath']
                elif ruleobj in configopts['stcyararules']:
                    filepath = configopts['stcyararules'][ruleobj]['filepath']

                doinfo('[IP#%d.%s#%d] %s:%s %s %s:%s doesnot match any rule in %s' % (
                            ipct,
                            proto,
                            id,
                            src,
                            sport,
                            directionflag,
                            dst,
                            dport,
                            filepath))

    return False
Exemplo n.º 14
0
def showudpmatches(data):
    proto = 'UDP'

    ((src, sport), (dst, dport)) = matchstats['addr']

    key = "%s:%s" % (src, sport)
    if key not in openudpflows:
        key = "%s:%s" % (dst, dport)

    if configopts['maxdispbytes'] > 0:
        maxdispbytes = configopts['maxdispbytes']
    else:
        maxdispbytes = len(data)

    filename = '%s/%s-%08d-%s.%s-%s.%s-%s' % (
        configopts['logdir'], proto, configopts['packetct'], src, sport, dst,
        dport, matchstats['direction'])

    if configopts['writelogs']:
        writetofile(filename, data)

        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo('[IP#%d.UDP#%d] Wrote %dB to %s/%s-%08d.%s.%s.%s.%s' %
                   (openudpflows[key]['ipct'], openudpflows[key]['id'],
                    matchstats['matchsize'], configopts['logdir'], proto,
                    configopts['packetct'], src, sport, dst, dport))

    if 'quite' in configopts['outmodes']:
        if matchstats['regex']:
            pattern = getregexpattern(matchstats['regex'])
        else:
            pattern = None

        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo(
                '[IP#%d.UDP#%d] %s:%s %s %s:%s matches \'%s\' @ [%d:%d] - %dB'
                % (openudpflows[key]['ipct'], openudpflows[key]['id'], src,
                   sport, matchstats['directionflag'], dst, dport, pattern,
                   matchstats['start'], matchstats['end'],
                   matchstats['matchsize']))
        return

    if configopts['maxdisppackets'] != 0 and configopts[
            'disppacketct'] >= configopts['maxdisppackets']:
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo(
                'Skipping outmode parsing { disppacketct: %d == maxdisppackets: %d }'
                % (configopts['disppacketct'], configopts['maxdisppackets']))
        return

    direction = matchstats['direction']
    directionflag = matchstats['directionflag']
    if 'meta' in configopts['outmodes']:
        if configopts['invertmatch']:
            invertstatus = " (invert)"
        else:
            invertstatus = ""

        start = matchstats['start']
        end = matchstats['end']
        matchsize = matchstats['matchsize']

        if matchstats['detectiontype'] == 'regex':
            metastr = 'matches regex%s: \'%s\'' % (
                invertstatus, getregexpattern(matchstats['regex']))

        elif matchstats['detectiontype'] == 'shellcode':
            metastr = 'contains shellcode [Offset: %d]%s' % (
                matchstats['shellcodeoffset'], invertstatus)

        elif matchstats['detectiontype'] == 'yara':
            metastr = 'matches rule: \'%s\' from %s' % (
                matchstats['yararulename'], matchstats['yararulefilepath'])

        else:
            metastr = ''

        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            bpfstr = generate_bpf("UDP", src, sport, directionflag, dst, dport)
            doinfo(
                '[IP#%d.UDP#%d] BPF: %s' %
                (openudpflows[key]['ipct'], openudpflows[key]['id'], bpfstr))

        print '[MATCH] (%08d/%08d) [IP#%d.UDP#%d] %s:%s %s %s:%s %s' % (
            configopts['inspudppacketct'], configopts['udpmatches'],
            openudpflows[key]['ipct'], openudpflows[key]['id'], src, sport,
            directionflag, dst, dport, metastr)

        print '[MATCH] (%08d/%08d) [IP#%d.UDP#%d] match @ %s[%d:%d] (%dB)' % (
            configopts['inspudppacketct'], configopts['udpmatches'],
            openudpflows[key]['ipct'], openudpflows[key]['id'], direction,
            start, end, matchsize)

    if 'print' in configopts['outmodes']:
        if configopts['colored']:
            if direction == configopts['ctsdirectionstring']:
                printable(data[:maxdispbytes], configopts['ctsoutcolor'])
            elif direction == configopts['stcdirectionstring']:
                printable(data[:maxdispbytes], configopts['stcoutcolor'])
        else:
            printable(data[:maxdispbytes], None)

    if 'raw' in configopts['outmodes']:
        if configopts['colored']:
            print colored(data[:maxdispbytes])
        else:
            print data[:maxdispbytes]

    if 'hex' in configopts['outmodes']:
        if configopts['colored']:
            if direction == configopts['ctsdirectionstring']:
                hexdump(data[:maxdispbytes], configopts['ctsoutcolor'])
            elif direction == configopts['stcdirectionstring']:
                hexdump(data[:maxdispbytes], configopts['stcoutcolor'])
        else:
            hexdump(data[:maxdispbytes], None)

    if configopts['asm4shellcode']:
        print
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo(
                '[IP#%d.UDP#%d] Generating disassembled output for %dB of detected shellcode'
                % (openudpflows[key]['ipct'], openudpflows[key]['id'],
                   len(data)))
        dumpasm(data)

    configopts['dispstreamct'] += 1

    if not configopts['colored']:
        print
Exemplo n.º 15
0
def handleudp(addr, payload, pkt):
    showmatch = False
    addrkey = addr
    ((src, sport), (dst, dport)) = addr
    count = len(payload)
    start = 0
    end = count
    data = payload

    if len(configopts['ctsregexes']) > 0 or len(
            configopts['ctsfuzzpatterns']) > 0 or len(
                configopts['ctsyararules']) > 0:
        inspectcts = True
    else:
        inspectcts = False

    if len(configopts['stcregexes']) > 0 or len(
            configopts['stcfuzzpatterns']) > 0 or len(
                configopts['stcyararules']) > 0:
        inspectstc = True
    else:
        inspectstc = False

    keya = "%s:%s" % (src, sport)
    keyb = "%s:%s" % (dst, dport)
    key = None
    if keya in openudpflows:
        key = "%s:%s" % (src, sport)
        keydst = "%s:%s" % (dst, dport)
        direction = configopts['ctsdirectionstring']
        directionflag = configopts['ctsdirectionflag']
    elif keyb in openudpflows:
        key = "%s:%s" % (dst, dport)
        keydst = "%s:%s" % (src, sport)
        direction = configopts['stcdirectionstring']
        directionflag = configopts['stcdirectionflag']

    if key in openudpflows and openudpflows[key]['keydst'] == keydst:
        openudpflows[key]['totdatasize'] += count
    else:
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo(
                '[IP#%d.UDP#%d] %s:%s - %s:%s remains untracked { IP tracking missed this flow }'
                % (openudpflows[key]['ipct'], openudpflows[key]['id'], src,
                   sport, dst, dport))

    regexes = []
    fuzzpatterns = []
    yararuleobjects = []
    timestamp = datetime.datetime.fromtimestamp(
        nids.get_pkt_ts()).strftime('%H:%M:%S | %Y/%m/%d')

    if direction == configopts['ctsdirectionstring']:
        openudpflows[key]['ctsdatasize'] += count
        if 'regex' in configopts['inspectionmodes']:
            for regex in configopts['ctsregexes']:
                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)

    elif direction == configopts['stcdirectionstring']:
        openudpflows[key]['stcdatasize'] += count
        if 'regex' in configopts['inspectionmodes']:
            for regex in configopts['stcregexes']:
                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.UDP#%d] %s %s %s [%dB] { TRACKED: %d } { CTS: %dB, STC: %dB, TOT: %dB }'
            % (openudpflows[key]['ipct'],
               openudpflows[key]['id'], key, directionflag, keydst, count,
               len(openudpflows), openudpflows[key]['ctsdatasize'],
               openudpflows[key]['stcdatasize'],
               openudpflows[key]['totdatasize']))

    if not configopts['linemode']:
        if configopts['udpdone']:
            if configopts['tcpdone']:
                if configopts['verbose'] and configopts['verboselevel'] >= 1:
                    doinfo(
                        'Done inspecting max packets (%d) and max streams (%d), \
                            preparing for exit' %
                        (configopts['maxinsppackets'],
                         configopts['maxinspstreams']))
                exitwithstats()
            else:
                if configopts['verbose'] and configopts['verboselevel'] >= 1:
                    doinfo(
                        'Ignoring packet %s:%s %s %s:%s { inspudppacketct: %d == maxinsppackets: %d }'
                        %
                        (src, sport, dst, dport, configopts['inspudppacketct'],
                         configopts['maxinsppackets']))
            return

    configopts['inspudppacketct'] += 1

    if configopts['linemode']:
        matchstats['addr'] = addrkey
        matchstats['start'] = start
        matchstats['end'] = end
        matchstats['matchsize'] = matchstats['end'] - matchstats['start']
        matchstats['direction'] = direction
        matchstats['directionflag'] = directionflag
        if configopts['verbose'] and configopts['verboselevel'] >= 1:
            doinfo(
                '[IP#%d.UDP#%d] Skipping inspection as linemode is enabled.' %
                (openudpflows[key]['ipct'], openudpflows[key]['id']))
        showudpmatches(data[matchstats['start']:matchstats['end']])

        if configopts['writepcap']:
            markmatchedippackets(addrkey)
        return

    if configopts['maxinsppackets'] != 0 and configopts[
            'inspudppacketct'] >= configopts['maxinsppackets']:
        configopts['udpdone'] = True

    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

    inspdata = data[offset:depth]
    inspdatalen = len(inspdata)

    if configopts['verbose'] and configopts['verboselevel'] >= 1:
        doinfo('[IP#%d.UDP#%d] Initiating inspection on %s[%d:%d] - %dB' %
               (openudpflows[key]['ipct'], openudpflows[key]['id'], direction,
                offset, depth, inspdatalen))

    matched = inspect('UDP', inspdata, inspdatalen, regexes, fuzzpatterns,
                      yararuleobjects, addrkey, direction, directionflag)

    if matched:
        openudpflows[key]['matches'] += 1

        if configopts['writepcap']:
            markmatchedippackets(addrkey)

        if configopts['writepcapfast']:
            if addrkey in ippacketsdict.keys(
            ) and ippacketsdict[addrkey]['proto'] == 'UDP':
                ippacketsdict[addrkey]['matched'] = True
                ippacketsdict[addrkey]['id'] = configopts['packetct']
                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'] == 'UDP':
                    ippacketsdict[newaddrkey]['matched'] = True
                    ippacketsdict[newaddrkey]['id'] = configopts['packetct']
                    ippacketsdict[newaddrkey]['matchedid'] = len(
                        ippacketsdict[newaddrkey].keys(
                        )) - configopts['ipmetavars']

        matchstats['start'] += offset
        matchstats['end'] += offset

        matchstats['direction'] = direction
        matchstats['directionflag'] = directionflag

        if configopts['udpmatches'] == 0:
            configopts['shortestmatch']['packet'] = matchstats['matchsize']
            configopts['shortestmatch']['packetid'] = configopts['packetct']
            configopts['longestmatch']['packet'] = matchstats['matchsize']
            configopts['longestmatch']['packetid'] = configopts['packetct']
        else:
            if matchstats['matchsize'] <= configopts['shortestmatch']['packet']:
                configopts['shortestmatch']['packet'] = matchstats['matchsize']
                configopts['shortestmatch']['packetid'] = configopts[
                    'packetct']

            if matchstats['matchsize'] >= configopts['longestmatch']['packet']:
                configopts['longestmatch']['packet'] = matchstats['matchsize']
                configopts['longestmatch']['packetid'] = configopts['packetct']

        configopts['udpmatches'] += 1

        matchstats['addr'] = addrkey
        showudpmatches(data[matchstats['start']:matchstats['end']])
        del openudpflows[key]