Exemplo n.º 1
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.º 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 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.º 4
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.º 5
0
def writepackets():
    pktlist = []

    for key in ippacketsdict.keys():
        if ippacketsdict[key]['matched']:
            packets = 0
            del pktlist[:]
            ((src, sport), (dst, dport)) = key
            pcapfile = '%s-%08d-%s.%s-%s.%s.pcap' % (ippacketsdict[key]['proto'], ippacketsdict[key]['id'], src, sport, dst, dport)
            for subkey in ippacketsdict[key].keys():
                if subkey not in ['proto', 'id', 'matched', 'matchedid']:
                    pktlist.append(ippacketsdict[key][subkey])
                    packets += 1
            pcapwriter(pcapfile, pktlist)
            if configopts['verbose'] and configopts['verboselevel'] >= 1:
                doinfo('Wrote %d packets to %s' % (packets, pcapfile))
            del ippacketsdict[key]
Exemplo n.º 6
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.º 7
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.º 8
0
def handleip(pkt):
    ipmetavars = configopts['ipmetavars']

    iphdr = unpack('!BBHHHBBH4s4s', pkt[:20])
    ipversion = iphdr[0] >> 4
    ipihl = iphdr[0] & 0xF
    ipihl *= 4
    iptos = iphdr[1]
    iptotallen = iphdr[2]
    ipid = iphdr[3]
    ipttl = iphdr[5]
    ipproto = iphdr[6]
    ipsrc = socket.inet_ntoa(iphdr[8])
    ipdst = socket.inet_ntoa(iphdr[9])

    if ipproto == ipprotodict['tcp']:
        tcphdr = unpack('!HHLLBBHHH', pkt[ipihl:ipihl+20])
        tcpsport = tcphdr[0]
        tcpdport = tcphdr[1]
        tcpseq = tcphdr[2]
        tcpack = tcphdr[3]
        tcpoffset = tcphdr[4] >> 4
        tcphl = tcpoffset * 4
        tcpflags = tcphdr[5]
        tcpwindow = tcphdr[6]
        tcpchksum = tcphdr[7]
        tcpurgptr = tcphdr[8]

        data = pkt[ipihl+tcphl:]

        tcpflagsstr = []
        if tcpflags & 1 == 1: tcpflagsstr.append('F')
        if tcpflags & 2 == 2: tcpflagsstr.append('S')
        if tcpflags & 4 == 4: tcpflagsstr.append('R')
        if tcpflags & 8 == 8: tcpflagsstr.append('P')
        if tcpflags & 16 == 16: tcpflagsstr.append('A')
        if tcpflags & 32 == 32: tcpflagsstr.append('U')
        tcpflagsstr = "".join(tcpflagsstr)

        pktstats = ''
        fivetuple = ((ipsrc, tcpsport), (ipdst, tcpdport))
        revfivetuple = ((ipdst, tcpdport), (ipsrc, tcpsport))

        if configopts['writepcap']:
            if fivetuple in ippacketsdict.keys() and ippacketsdict[fivetuple]['proto'] == 'TCP':
                key = len(ippacketsdict[fivetuple].keys()) - ipmetavars
                ippacketsdict[fivetuple][key] = pkt
                pktstats = 'pktid: %d | ' % (len(ippacketsdict[fivetuple]) - ipmetavars)

            elif revfivetuple in ippacketsdict.keys() and ippacketsdict[revfivetuple]['proto'] == 'TCP':
                key = len(ippacketsdict[revfivetuple].keys()) - ipmetavars
                ippacketsdict[revfivetuple][key] = pkt
                pktstats = 'pktid: %d | ' % (len(ippacketsdict[revfivetuple]) - ipmetavars)

            elif tcpflagsstr == 'S':
                ippacketsdict[fivetuple] = {    'proto': 'TCP',
                                                'id': 0,
                                                'matched':False,
                                                'matchedid': 0,
                                                0: pkt
                                            }
                pktstats = 'pktid: %d | ' % (len(ippacketsdict[fivetuple]) - ipmetavars)

            else:
                return

        if configopts['writepcapfast']:
            if fivetuple in ippacketsdict.keys() and ippacketsdict[fivetuple]['proto'] == 'TCP':
                if not ippacketsdict[fivetuple]['matched']:
                    key = len(ippacketsdict[fivetuple].keys()) - ipmetavars
                    ippacketsdict[fivetuple][key] = pkt
                    pktstats = 'pktid: %d | ' % (len(ippacketsdict[fivetuple]) - ipmetavars)
                else:
                    if (len(ippacketsdict[fivetuple]) - ipmetavars) == (ippacketsdict[fivetuple]['matchedid'] + configopts['pcappacketct']):
                        if configopts['verbose'] and configopts['verboselevel'] >= 2:
                            dodebug('Post match packet collection complete for %s:%s - %s:%s { matchpacket: %d, postpackets: +%d }' % (
                                    ipsrc,
                                    tcpsport,
                                    ipdst,
                                    tcpdport,
                                    ippacketsdict[fivetuple]['matchedid'],
                                    configopts['pcappacketct']))

                        writepackets()
                    else:
                        key = len(ippacketsdict[fivetuple].keys()) - ipmetavars
                        ippacketsdict[fivetuple][key] = pkt
                        pktstats = 'pktid: %d | ' % (len(ippacketsdict[fivetuple]) - ipmetavars)

            elif revfivetuple in ippacketsdict.keys() and ippacketsdict[revfivetuple]['proto'] == 'TCP':
                if not ippacketsdict[revfivetuple]['matched']:
                    key = len(ippacketsdict[revfivetuple].keys()) - ipmetavars
                    ippacketsdict[revfivetuple][key] = pkt
                    pktstats = 'pktid: %d | ' % (len(ippacketsdict[revfivetuple]) - ipmetavars)
                else:
                    if (len(ippacketsdict[revfivetuple]) - ipmetavars) == (ippacketsdict[revfivetuple]['matchedid'] + configopts['pcappacketct']):
                        if configopts['verbose'] and configopts['verboselevel'] >= 2:
                            dodebug('Post match packet collection complete for %s:%s - %s:%s { matchpacket: %d, postpackets: +%d }' % (
                                    ipsrc,
                                    tcpsport,
                                    ipdst,
                                    tcpdport,
                                    ippacketsdict[revfivetuple]['matchedid'],
                                    configopts['pcappacketct']))

                        writepackets()
                    else:
                        key = len(ippacketsdict[revfivetuple].keys()) - ipmetavars
                        ippacketsdict[revfivetuple][key] = pkt
                        pktstats = 'pktid: %d | ' % (len(ippacketsdict[revfivetuple]) - ipmetavars)

            elif tcpflagsstr == 'S':
                ippacketsdict[fivetuple] = {    'proto': 'TCP',
                                                'id': 0,
                                                'matched':False,
                                                'matchedid': 0,
                                                0: pkt
                                            }
                pktstats = 'pktid: %d | ' % (len(ippacketsdict[fivetuple]) - ipmetavars)

            else:
                return

        # if this is a new tcp stream, add it to the opentcpflows table
        addrkey = ((ipsrc, tcpsport), (ipdst, tcpdport))
        tmpaddrkey = ((ipdst, tcpdport), (ipsrc, tcpsport))

        if tcpflagsstr == 'S' and addrkey not in opentcpflows:
            configopts['ipflowsct'] += 1
            configopts['streamct'] += 1
            opentcpflows.update({addrkey:{
                                            'ipct': configopts['ipflowsct'],
                                            'id': configopts['streamct'],
                                            'totdatasize': 0,
                                            'insppackets': 0,
                                            'multimatchskipoffset': 0,
                                            'ctspacketlendict': {},
                                            'stcpacketlendict': {},
                                        }
                                })

        count = len(data)
        if addrkey in opentcpflows:
            # this tcp/ip packet is travelling from CTS direction
            opentcpflows[addrkey]['insppackets'] += 1
            opentcpflows[addrkey]['ctspacketlendict'].update({ opentcpflows[addrkey]['insppackets']:count })
            key = addrkey
        elif tmpaddrkey in opentcpflows:
            # this tcp/ip packet is travelling from STC direction
            opentcpflows[tmpaddrkey]['insppackets'] += 1
            opentcpflows[tmpaddrkey]['stcpacketlendict'].update({ opentcpflows[tmpaddrkey]['insppackets']:count })
            key = tmpaddrkey
        else:
            # this ip flow is untracked, let's not care about it
            key = None

        if configopts['verbose'] and configopts['verboselevel'] >= 2 and key in opentcpflows:
            dodebug('[IP#%d.TCP#%d] %s:%s %s %s:%s { %sflags: %s, seq: %d, ack: %d, win: %d, len: %dB }' % (
                    opentcpflows[key]['ipct'],
                    opentcpflows[key]['id'],
                    ipsrc,
                    tcpsport,
                    configopts['ctsdirectionflag'],
                    ipdst,
                    tcpdport,
                    pktstats,
                    tcpflagsstr,
                    tcpseq,
                    tcpack,
                    tcpwindow,
                    len(data)))

    elif ipproto == ipprotodict['udp']:
        udphdr = unpack('!HHHH', pkt[ipihl:ipihl+UDPHDRLEN])
        udpsport = udphdr[0]
        udpdport = udphdr[1]
        udplen = udphdr[2]

        data = pkt[ipihl+UDPHDRLEN:]

        pktstats = ''
        fivetuple = ((ipsrc, udpsport), (ipdst, udpdport))
        revfivetuple = ((ipdst, udpdport), (ipsrc, udpsport))

        if configopts['writepcap']:
            if fivetuple in ippacketsdict.keys() and ippacketsdict[fivetuple]['proto'] == 'UDP':
                key = len(ippacketsdict[fivetuple].keys()) - ipmetavars
                ippacketsdict[fivetuple][key] = pkt
                pktstats = 'pktid: %d | ' % (len(ippacketsdict[fivetuple]) - ipmetavars)

            elif revfivetuple in ippacketsdict.keys() and ippacketsdict[revfivetuple]['proto'] == 'UDP':
                key = len(ippacketsdict[revfivetuple].keys()) - ipmetavars
                ippacketsdict[revfivetuple][key] = pkt
                pktstats = 'pktid: %d | ' % (len(ippacketsdict[revfivetuple]) - ipmetavars)

            else:
                ippacketsdict[fivetuple] = {    'proto': 'UDP',
                                                'id': 0,
                                                'matched':False,
                                                'matchedid': 0,
                                                0: pkt
                                            }
                pktstats = 'pktid: %d | ' % (len(ippacketsdict[fivetuple]) - ipmetavars)

        if configopts['writepcapfast']:
            if fivetuple in ippacketsdict.keys() and ippacketsdict[fivetuple]['proto'] == 'UDP':
                if not ippacketsdict[fivetuple]['matched']:
                    key = len(ippacketsdict[fivetuple].keys()) - ipmetavars
                    ippacketsdict[fivetuple][key] = pkt
                    pktstats = 'pktid: %d | ' % (len(ippacketsdict[fivetuple]) - ipmetavars)
                else:
                    if (len(ippacketsdict[fivetuple]) - ipmetavars) == (ippacketsdict[fivetuple]['matchedid'] + configopts['pcappacketct']):
                        if configopts['verbose'] and configopts['verboselevel'] >= 2:
                            dodebug('Post match packet collection complete for %s:%s - %s:%s { matchpacket: %d, postpackets: +%d }' % (
                                    ipsrc,
                                    udpsport,
                                    ipdst,
                                    udpdport,
                                    ippacketsdict[fivetuple]['matchedid'],
                                    configopts['pcappacketct']))

                        writepackets()
                    else:
                        key = len(ippacketsdict[fivetuple].keys()) - ipmetavars
                        ippacketsdict[fivetuple][key] = pkt
                        pktstats = 'pktid: %d | ' % (len(ippacketsdict[fivetuple]) - ipmetavars)

            elif revfivetuple in ippacketsdict.keys() and ippacketsdict[revfivetuple]['proto'] == 'UDP':
                if not ippacketsdict[revfivetuple]['matched']:
                    key = len(ippacketsdict[revfivetuple].keys()) - ipmetavars
                    ippacketsdict[revfivetuple][key] = pkt
                    pktstats = 'pktid: %d | ' % (len(ippacketsdict[revfivetuple]) - ipmetavars)
                else:
                    if (len(ippacketsdict[revfivetuple]) - ipmetavars) == (ippacketsdict[revfivetuple]['matchedid'] + configopts['pcappacketct']):
                        if configopts['verbose'] and configopts['verboselevel'] >= 2:
                            dodebug('Post match packet collection complete for %s:%s - %s:%s { matchpacket: %d, postpackets: +%d }' % (
                                    ipsrc,
                                    udpsport,
                                    ipdst,
                                    udpdport,
                                    ippacketsdict[revfivetuple]['matchedid'],
                                    configopts['pcappacketct']))

                        writepackets()
                    else:
                        key = len(ippacketsdict[revfivetuple].keys()) - ipmetavars
                        ippacketsdict[revfivetuple][key] = pkt
                        pktstats = 'pktid: %d | ' % (len(ippacketsdict[revfivetuple]) - ipmetavars)

            else:
                ippacketsdict[fivetuple] = {    'proto': 'UDP',
                                                'id': 0,
                                                'matched':False,
                                                'matchedid': 0,
                                                0: pkt
                                            }
                pktstats = 'pktid: %d | ' % (len(ippacketsdict[fivetuple]) - ipmetavars)


        keya = "%s:%s" % (ipsrc, udpsport)
        keyb = "%s:%s" % (ipdst, udpdport)
        if udpdport <= 1024 and udpsport >= 1024:
            key = keya
            keydst = keyb
        else:
            key = keyb
            keydst = keya

        if key not in openudpflows:
            configopts['ipflowsct'] += 1
            configopts['packetct'] += 1
            openudpflows.update({ key:{
                                            'ipct': configopts['ipflowsct'],
                                            'id':configopts['packetct'],
                                            'keydst':keydst,
                                            'matches':0,
                                            'ctsdatasize':0,
                                            'stcdatasize':0,
                                            'totdatasize':0,
                                        }
                                    })

        if configopts['verbose'] and configopts['verboselevel'] >= 2 and key in openudpflows:
            dodebug('[IP#%d.UDP#%d] %s %s %s [%dB]' % (
                        openudpflows[key]['ipct'],
                        openudpflows[key]['id'],
                        key,
                        configopts['ctsdirectionflag'],
                        keydst,
                        len(data)))
Exemplo n.º 9
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]