diff --git a/warden3/contrib/connectors/hp-dio/warden3-dio-sender.py b/warden3/contrib/connectors/hp-dio/warden3-dio-sender.py index f6cb949743568f9a1ffbbe641fddceed8eff979e..9782f1bad5abb83fb65075b4d05117e11044f275 100644 --- a/warden3/contrib/connectors/hp-dio/warden3-dio-sender.py +++ b/warden3/contrib/connectors/hp-dio/warden3-dio-sender.py @@ -25,11 +25,20 @@ DEFAULT_CON_ATTEMPTS = 3 DEFAULT_CON_RETRY_INTERVAL = 5 DEFAULT_ATTACH_NAME = 'att1' DEFAULT_HASHTYPE = 'md5' +DEFAULT_CONTENT_TYPE = 'application/octet-stream' +DEFAULT_CONTENT_ENCODING = 'base64' -def gen_attach_idea(logger, binaries_path, filename, hashtype, hashdigest, vtpermalink, avref): +def gen_attach_idea(logger, report_binaries, binaries_path, filename, hashtype, hashdigest, vtpermalink, avref): refs = [] + attach = { + "Handle": DEFAULT_ATTACH_NAME, + "FileName": [filename], + "Type": ["Malware"], + "Hash": ["%s:%s" % (hashtype, hashdigest)], + } + if vtpermalink is not None: refs.append('url:' + vtpermalink) @@ -38,34 +47,23 @@ def gen_attach_idea(logger, binaries_path, filename, hashtype, hashdigest, vtper if refs: refs = list(set(refs)) - - try: - fpath = path.join(binaries_path, hashdigest) - with open(fpath, "r") as f: - fdata = f.read() - except (IOError) as e: - logger.info("Reading id file \"%s\" with malware failed, information will not be attached." % (fpath)) - return None - - attach = { - "Attach": [ - { - "Handle": DEFAULT_ATTACH_NAME, - "FileName": [filename], - "Type": ["Malware"], - "ContentType": "application/octet-stream", - "Hash": ["%s:%s" % (hashtype, hashdigest)], - "Size": len(fdata), - "Ref": refs, - "ContentEncoding": "base64", - "Content": base64.b64encode(fdata) - } - ] - } + attach['Ref'] = refs + + if report_binaries == 'true': + try: + fpath = path.join(binaries_path, hashdigest) + with open(fpath, "r") as f: + fdata = f.read() + attach['ContentType'] = DEFAULT_CONTENT_TYPE + attach['ContentEncoding'] = DEFAULT_CONTENT_ENCODING + attach['Size'] = len(fdata) + attach['Content'] = base64.b64encode(fdata) + except (IOError) as e: + logger.info("Reading id file \"%s\" with malware failed, information will not be attached." % (fpath)) return attach -def gen_event_idea(logger, binaries_path, report_binaries, client_name, detect_time, win_start_time, win_end_time, aggr_win, **data): +def gen_event_idea(logger, binaries_path, report_binaries, client_name, detect_time, win_start_time, win_end_time, aggr_win, data): category = [] event = { @@ -90,10 +88,6 @@ def gen_event_idea(logger, binaries_path, report_binaries, client_name, detect_t # Determine IP address family af = "IP4" if not ':' in data['src_ip'] else "IP6" - # event['Source'].append( af : [data['src_ip']] ) - event['Source'][0][af] = [data['src_ip']] - event['Target'][0][af] = [data['dst_ip']] - # Extract & save proto and service name proto = [data['proto']] @@ -102,8 +96,6 @@ def gen_event_idea(logger, binaries_path, report_binaries, client_name, detect_t elif data['service'] in ['httpd', 'smbd']: proto.append(data['service'][:-1]) - event['Target'][0]['Proto'] = proto - # Choose correct category if data['service'] != 'pcap': category.append('Attempt.Exploit') @@ -114,91 +106,94 @@ def gen_event_idea(logger, binaries_path, report_binaries, client_name, detect_t if data['service'] == 'smbd' and data['download_md5_hash'] is not None: category.append('Malware') event['Source'][0]['URL'] = [data['download_url']] + filename = data['download_url'].split('/')[-1] - if report_binaries == 'true': - filename = data['download_url'].split('/')[-1] - + if filename != '' and data['download_md5_hash'] != '': # Generate "Attach" part of IDEA - a = gen_attach_idea(logger, binaries_path, filename, DEFAULT_HASHTYPE, data['download_md5_hash'], data['virustotal_permalink'], data['scan_result']) - - # Attach malware section if file with malware was loaded successfully - if a is not None: - event['Source'][0]['AttachHand'] = [DEFAULT_ATTACH_NAME] - event.update(a) + a = gen_attach_idea(logger, report_binaries, binaries_path, filename, DEFAULT_HASHTYPE, data['download_md5_hash'], data['virustotal_permalink'], data['scan_result']) + + event['Source'][0]['AttachHand'] = [DEFAULT_ATTACH_NAME] + event['Attach'] = [a] + + + event['Source'][0][af] = [data['src_ip']] + event['Source'][0]['Port'] = [data['src_port']] + + event['Target'][0][af] = [data['dst_ip']] + event['Target'][0]['Port'] = [data['dst_port']] + event['Target'][0]['Proto'] = proto - event['Source'][0]['Port'] = [data['src_port']] - event['Target'][0]['Port'] = [data['dst_port']] event['Category'] = category return event def main(): - aconfig = read_cfg(DEFAULT_ACONFIG) - wconfig = read_cfg(aconfig.get('warden', DEFAULT_WCONFIG)) - - aname = aconfig.get('name', DEFAULT_NAME) - awin = aconfig.get('awin', DEFAULT_AWIN) - - abinpath = aconfig.get('binaries_path', DEFAULT_BINPATH) - adbfile = aconfig.get('dbfile', DEFAULT_DBFILE) - aconattempts = aconfig.get('con_attempts', DEFAULT_CON_ATTEMPTS) - aretryinterval = aconfig.get('con_retry_interval', DEFAULT_CON_RETRY_INTERVAL) - areportbinaries = aconfig.get('report_binaries', DEFAULT_REPORT_BINARIES) - - wconfig['name'] = aname - - wclient = Client(**wconfig) + aconfig = read_cfg(DEFAULT_ACONFIG) + wconfig = read_cfg(aconfig.get('warden', DEFAULT_WCONFIG)) + + aname = aconfig.get('name', DEFAULT_NAME) + awin = aconfig.get('awin', DEFAULT_AWIN) * 60 + + abinpath = aconfig.get('binaries_path', DEFAULT_BINPATH) + adbfile = aconfig.get('dbfile', DEFAULT_DBFILE) + aconattempts = aconfig.get('con_attempts', DEFAULT_CON_ATTEMPTS) + aretryinterval = aconfig.get('con_retry_interval', DEFAULT_CON_RETRY_INTERVAL) + areportbinaries = aconfig.get('report_binaries', DEFAULT_REPORT_BINARIES) + + wconfig['name'] = aname - con = sqlite3.connect(adbfile) - con.row_factory = sqlite3.Row - crs = con.cursor() + wclient = Client(**wconfig) - events = [] - - query = "SELECT c.connection_timestamp AS timestamp, c.remote_host AS src_ip, c.remote_port AS src_port, c.connection_transport AS proto, \ - c.local_host AS dst_ip, c.local_port AS dst_port, COUNT(c.connection) as attack_scale, c.connection_protocol AS service, d.download_url, d.download_md5_hash, \ - v.virustotal_permalink, GROUP_CONCAT('urn:' || vt.virustotalscan_scanner || ':' || vt.virustotalscan_result,';') AS scan_result \ - FROM connections AS c LEFT JOIN downloads AS d ON c.connection = d.connection \ - LEFT JOIN virustotals AS v ON d.download_md5_hash = v.virustotal_md5_hash \ - LEFT JOIN virustotalscans vt ON v.virustotal = vt.virustotal \ - WHERE datetime(connection_timestamp,'unixepoch') > datetime('now','-%d seconds') AND c.remote_host != '' \ - GROUP BY c.remote_host, c.local_port ORDER BY c.connection_timestamp ASC;" % (awin) - - attempts = 0 - while attempts < aconattempts: - try: - crs.execute(query) - break - except sqlite3.Error, e: - attempts += 1 - wclient.logger.info("Info: %s - attempt %d/%d." % (e.args[0], attempts, aconattempts)) - if attempts == aconattempts: - wclient.logger.error("Error: %s (dbfile: %s)" % (e.args[0], adbfile)) - - sleep(aretryinterval) - - rows = crs.fetchall() - - if con: - con.close - - etime = format_timestamp(time()) - stime = format_timestamp(time() - awin) - - for row in rows: - dtime = format_timestamp(row['timestamp']) - events.append(gen_event_idea(logger = wclient.logger, binaries_path = abinpath, report_binaries = areportbinaries, client_name = aname, detect_time = dtime, win_start_time = stime, win_end_time = etime, aggr_win = awin, **row)) - - print "=== Sending ===" - start = time() - ret = wclient.sendEvents(events) - - if ret: - wclient.logger.info("%d event(s) successfully delivered." % len(rows)) + con = sqlite3.connect(adbfile) + con.row_factory = sqlite3.Row + crs = con.cursor() - print "Time: %f" % (time() - start) + events = [] + query = "SELECT c.connection_timestamp AS timestamp, c.remote_host AS src_ip, c.remote_port AS src_port, c.connection_transport AS proto, \ + c.local_host AS dst_ip, c.local_port AS dst_port, COUNT(c.connection) as attack_scale, c.connection_protocol AS service, d.download_url, d.download_md5_hash, \ + v.virustotal_permalink, GROUP_CONCAT('urn:' || vt.virustotalscan_scanner || ':' || vt.virustotalscan_result,';') AS scan_result \ + FROM connections AS c LEFT JOIN downloads AS d ON c.connection = d.connection \ + LEFT JOIN virustotals AS v ON d.download_md5_hash = v.virustotal_md5_hash \ + LEFT JOIN virustotalscans vt ON v.virustotal = vt.virustotal \ + WHERE datetime(connection_timestamp,'unixepoch') > datetime('now','-%d seconds') AND c.remote_host != '' \ + GROUP BY c.remote_host, c.local_port ORDER BY c.connection_timestamp ASC;" % (awin) + + attempts = 0 + while attempts < aconattempts: + try: + crs.execute(query) + break + except sqlite3.Error, e: + attempts += 1 + wclient.logger.info("Info: %s - attempt %d/%d." % (e.args[0], attempts, aconattempts)) + if attempts == aconattempts: + wclient.logger.error("Error: %s (dbfile: %s)" % (e.args[0], adbfile)) + + sleep(aretryinterval) + + rows = crs.fetchall() + + if con: + con.close + + etime = format_timestamp(time()) + stime = format_timestamp(time() - awin) + + for row in rows: + dtime = format_timestamp(row['timestamp']) + events.append(gen_event_idea(logger = wclient.logger, binaries_path = abinpath, report_binaries = areportbinaries, client_name = aname, detect_time = dtime, win_start_time = stime, win_end_time = etime, aggr_win = awin, data = row)) + + print "=== Sending ===" + start = time() + ret = wclient.sendEvents(events) + if ret: + wclient.logger.info("%d event(s) successfully delivered." % len(rows)) + + print "Time: %f" % (time() - start) + + if __name__ == "__main__": main()