def exportuml(interactions, outputdirectory, foldername, filename): content = '@startuml\n' for i in interactions: content += i.get('sender') + ' -> ' + i.get( 'recipient') + ': ' + i.get('name') + '\n' content += '@enduml\n' # writing UML diagram file to output return writetofile(outputdirectory, foldername, filename, content)
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
def builder_writecode(outputdirectory, module, version, logmodule=None): if logmodule == None: logserverurl = getserverurl(module) + '/log/' # generating allowed incoming methods implementations methodcode_in = loadfilecontent( './builders/templates/python/logmethod_in.py') componentname = 'log' method = 'log' allowedlogmethods = ',\n\t' + '\'/' + method + '/\'' + ', \'' + method + 'view\'' replacements = {'{{{METHODNAME}}}': method} methodcode = methodcode_in for k in replacements: methodcode = methodcode.replace(k, str(replacements.get(k))) logmethodscode = methodcode # generating main log server program implementation logservercode = loadfilecontent( './builders/templates/python/server.py') replacements = { '{{{LISTENDADDRESS}}}': module.get('bindaddress'), '{{{LISTENPORT}}}': module.get('listeningport'), '{{{SSLENABLED}}}': ('True' if module.get('ssl') else 'False'), '{{{SERVERVERSION}}}': version, '{{{COMPONENTNAME}}}': componentname, '{{{OUTGOINGMETHODSCODE}}}': '', '{{{ALLOWEDMETHODS}}}': allowedlogmethods, '{{{INCOMINGMETHODSCODE}}}': logmethodscode[:-1] } for k in replacements: logservercode = logservercode.replace(k, str(replacements.get(k))) # writing main log server file to output module['name'] = componentname writetofile(outputdirectory, getfoldername(module), 'server.py', logservercode + 'b') return True # getting server object for the current module server = module.get('server') # getting log server url logserverurl = getserverurl(logmodule) + '/log/' # building log file from template logcode = loadfilecontent('./builders/templates/python/log.py') replacements = { '{{{LOGS_ENABLED}}}': True, '{{{LOGSERVER_URL}}}': logserverurl } for k in replacements: logcode = logcode.replace(k, str(replacements.get(k))) # writing log file to output writetofile(outputdirectory, getfoldername(module), 'log.py', logcode) # generating outgoing methods implementations methodcode_out = loadfilecontent( './builders/templates/python/method_out.py') outgoingmethodscode = '' if len(module.get('output_interactions')) == 0: outgoingmethodscode = '# no outgoing calls available' for el in module.get('output_interactions'): interaction = el.get('interaction') url = getserverurl(el.get('server')) url += '/' + interaction.get('method_uri') + '/' sampledata = interaction.get('sampledata') replacements = { '{{{METHODNAME}}}': interaction.get('name'), '{{{URL}}}': url, '{{{SENTDATA}}}': sampledata.get('sent'), '{{{RECEIVEDDATA}}}': sampledata.get('received') } methodcode = methodcode_out for k in replacements: methodcode = methodcode.replace(k, str(replacements.get(k))) outgoingmethodscode += methodcode # generating allowed incoming methods implementations methodcode_in = loadfilecontent('./builders/templates/python/method_in.py') incomingmethodscode = '' allowedmethods = '' for method in module.get('input_interactions'): sampledata = module.get('input_interactions').get(method).get( 'sampledata') allowedmethods += ',\n\t' + '\'/' + method + '/\'' + ', \'' + method + 'view\'' replacements = { '{{{METHODNAME}}}': method, '{{{REQUESTDATA}}}': sampledata.get('received'), '{{{RESPONSEDATA}}}': sampledata.get('sent') } methodcode = methodcode_in for k in replacements: methodcode = methodcode.replace(k, str(replacements.get(k))) incomingmethodscode += methodcode # generating processing base code processingfile = getfullpathname(outputdirectory, getfoldername(module), 'processing.py') if os.path.isfile(processingfile): # moving all processing file, for backup (will overwrite previous backup files) os.rename(processingfile, processingfile + '_old') method_processing = loadfilecontent( './builders/templates/python/method_processing.py') processingcode = '' for method in module.get('input_interactions'): replacements = {'{{{METHODNAME}}}': method} methodcode = method_processing for k in replacements: methodcode = methodcode.replace(k, str(replacements.get(k))) processingcode += methodcode # writing processing file to output writetofile(outputdirectory, getfoldername(module), 'processing.py', processingcode) # generating main server program implementation servercode = loadfilecontent('./builders/templates/python/server.py') replacements = { '{{{LISTENDADDRESS}}}': server.get('bindaddress'), '{{{LISTENPORT}}}': server.get('listeningport'), '{{{SSLENABLED}}}': ('True' if server.get('ssl') else 'False'), '{{{SERVERVERSION}}}': version, '{{{COMPONENTNAME}}}': module.get('name'), '{{{OUTGOINGMETHODSCODE}}}': outgoingmethodscode[:-1], '{{{ALLOWEDMETHODS}}}': allowedmethods, '{{{INCOMINGMETHODSCODE}}}': incomingmethodscode[:-1] } for k in replacements: servercode = servercode.replace(k, str(replacements.get(k))) # writing main server file to output writetofile(outputdirectory, getfoldername(module), 'server.py', servercode) # return result return True
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
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