def kippo(): MODUL = "KIPPO" logme(MODUL, "Starting Kippo Modul.", ("P1"), ECFG) # collect honeypot config dic ITEMS = ("kippo", "nodeid", "mysqlhost", "mysqldb", "mysqluser", "mysqlpw") HONEYPOT = readcfg(MODUL, ITEMS, ECFG["cfgfile"]) HONEYPOT["ip"] = readonecfg(MODUL, "ip", ECFG["cfgfile"]) if HONEYPOT["ip"].lower() == "false" or HONEYPOT["ip"].lower() == "null": HONEYPOT["ip"] = ECFG["ip"] # open database try: con = MySQLdb.connect(host=HONEYPOT["mysqlhost"], user=HONEYPOT["mysqluser"], passwd=HONEYPOT["mysqlpw"], db=HONEYPOT["mysqldb"], cursorclass=MySQLdb.cursors.DictCursor) except MySQLdb.Error, e: logme(MODUL, "[ERROR] %s" % (str(e)), ("P3", "LOG"), ECFG)
def kippo(): MODUL = "KIPPO" logme(MODUL,"Starting Kippo Modul.",("P1"),ECFG) # collect honeypot config dic ITEMS = ("kippo","nodeid","mysqlhost","mysqldb","mysqluser","mysqlpw") HONEYPOT = readcfg(MODUL,ITEMS,ECFG["cfgfile"]) HONEYPOT["ip"] = readonecfg(MODUL,"ip", ECFG["cfgfile"]) if HONEYPOT["ip"].lower() == "false" or HONEYPOT["ip"].lower() == "null": HONEYPOT["ip"] = ECFG["ip"] # open database try: con = MySQLdb.connect(host=HONEYPOT["mysqlhost"], user=HONEYPOT["mysqluser"], passwd=HONEYPOT["mysqlpw"], db=HONEYPOT["mysqldb"], cursorclass=MySQLdb.cursors.DictCursor) except MySQLdb.Error,e: logme(MODUL,"[ERROR] %s" %(str(e)),("P3","LOG"),ECFG)
def glastopfv3(): MODUL = "GLASTOPFV3" logme(MODUL, "Starting Glastopf V3.x Modul.", ("P1"), ECFG) # collect honeypot config dic ITEMS = ("glastopfv3", "nodeid", "sqlitedb", "malwaredir") HONEYPOT = readcfg(MODUL, ITEMS, ECFG["cfgfile"]) HONEYPOT["ip"] = readonecfg(MODUL, "ip", ECFG["cfgfile"]) if HONEYPOT["ip"].lower() == "false" or HONEYPOT["ip"].lower() == "null": HONEYPOT["ip"] = ECFG["ip"] # Malwaredir exist ? Issue in Glastopf ! RFI Directory first create when the first RFI was downloaded #if os.path.isdir(HONEYPOT["malwaredir"]) == False: # logme(MODUL,"[ERROR] Missing Malware Dir " + HONEYPOT["malwaredir"] + ". Abort !",("P3","LOG"),ECFG) # return # is sqlitedb exist ? if os.path.isfile(HONEYPOT["sqlitedb"]) is False: logme( MODUL, "[INFO] Missing sqlitedb file " + HONEYPOT["sqlitedb"] + ". Skip !", ("P3", "LOG"), ECFG) return # open database con = sqlite3.connect(HONEYPOT["sqlitedb"], 30) con.row_factory = sqlite3.Row c = con.cursor() # calculate send limit c.execute("SELECT max(id) from events") maxid = c.fetchone()["max(id)"] if maxid is None: logme(MODUL, "[INFO] No entry's in Glastopf Database. Skip !", ("P2", "LOG"), ECFG) return imin, imax = calcminmax(MODUL, int(countme(MODUL, 'sqliteid', -1, ECFG)), int(maxid), ECFG) # read alerts from database c.execute("SELECT * from events where id > ? and id <= ?;", (imin, imax)) rows = c.fetchall() # counter inits x = 0 y = 1 esm = ewsauth(ECFG["username"], ECFG["token"]) jesm = "" for row in rows: x, y = viewcounter(MODUL, x, y) # filter empty requests and nagios checks if row["request_url"] == os.sep or row[ "request_url"] == "/index.do?hash=DEADBEEF&activate=1": countme(MODUL, 'sqliteid', row["id"], ECFG) continue # Prepair and collect Alert Data DATA = { "aid": HONEYPOT["nodeid"], "timestamp": row["time"], "sadr": re.sub(":.*$", "", row["source"]), "sipv": "ipv" + ip4or6(re.sub(":.*$", "", row["source"])), "sprot": "tcp", "sport": "", "tipv": "ipv" + ip4or6(HONEYPOT["ip"]), "tadr": HONEYPOT["ip"], "tprot": "tcp", "tport": "80", } REQUEST = { "description": "WebHoneypot : Glastopf v3.1", "url": urllib.quote(row["request_url"].encode('ascii', 'ignore')) } if "request_raw" in row.keys() and len(row["request_raw"]) > 0: REQUEST["raw"] = base64.encodestring(row["request_raw"].encode( 'ascii', 'ignore')) if "filename" in row.keys() and row["filename"] != None: error, malwarefile = malware(HONEYPOT["malwaredir"], row["filename"], ECFG["del_malware_after_send"]) if error == 0: REQUEST["binary"] = malwarefile else: logme(MODUL, "Mission Malwarefile %s" % row["filename"], ("P1", "LOG"), ECFG) # Collect additional Data ADATA = { "sqliteid": row["id"], } if "request_method" in row.keys(): ADATA["httpmethod"] = row["request_method"] if "request_raw" in row.keys(): m = re.search(r'Host: (\b.+\b)', row["request_raw"], re.M) if m: ADATA["host"] = str(m.group(1)) if "request_header" in row.keys(): if 'Host' in json.loads(row["request_header"]): ADATA["host"] = str(json.loads(row["request_header"])["Host"]) if "request_body" in row.keys(): if len(row["request_body"]) > 0: ADATA["requestbody"] = row["request_body"] esm = buildews(esm, DATA, REQUEST, ADATA) if "request_body" in row.keys(): if len(row["request_body"]) > 0: ADATA["requestbody"] = row["request_body"] esm = buildews(esm, DATA, REQUEST, ADATA) jesm = buildjson(jesm, DATA, REQUEST, ADATA) countme(MODUL, 'sqliteid', row["id"], ECFG) countme(MODUL, 'daycounter', -2, ECFG) if ECFG["a.verbose"] is True: verbosemode(MODUL, DATA, REQUEST, ADATA) con.close() if int(esm.xpath('count(//Alert)')) > 0: sendews(esm) writejson(jesm) if y > 1: logme(MODUL, "%s EWS alert records send ..." % (x + y - 1), ("P2"), ECFG) return
def conpot(): MODUL = "CONPOT" logme(MODUL, "Starting Conpot Modul.", ("P1"), ECFG) # collect honeypot config dic ITEMS = ("conpot", "nodeid", "logfile") HONEYPOT = readcfg(MODUL, ITEMS, ECFG["cfgfile"]) # logfile file exists ? if os.path.isfile(HONEYPOT["logfile"]) is False: logme(MODUL, "[ERROR] Missing LogFile " + HONEYPOT["logfile"] + ". Skip !", ("P3", "LOG"), ECFG) # count limit imin = int(countme(MODUL, 'fileline', -1, ECFG)) if int(ECFG["sendlimit"]) > 0: logme( MODUL, "Send Limit is set to : " + str(ECFG["sendlimit"]) + ". Adapting to limit!", ("P1"), ECFG) I = 0 x = 0 y = 1 esm = ewsauth(ECFG["username"], ECFG["token"]) jesm = "" while True: x, y = viewcounter(MODUL, x, y) I += 1 if int(ECFG["sendlimit"]) > 0 and I > int(ECFG["sendlimit"]): break line = getline(HONEYPOT["logfile"], (imin + I)).rstrip() if len(line) == 0: break else: # parse json try: content = json.loads(line) except ValueError, e: logme( MODUL, "Invalid json entry found in line " + str(I) + ", skipping entry.", ("P3"), ECFG) countme(MODUL, 'fileline', -2, ECFG) countme(MODUL, 'daycounter', -2, ECFG) pass # invalid json else: DATA = { "aid": HONEYPOT["nodeid"], "timestamp": "%s-%s-%s %s" % (content['timestamp'][0:4], content['timestamp'][5:7], content['timestamp'][8:10], content['timestamp'][11:19]), "sadr": "%s" % content['src_ip'], "sipv": "ipv4", "sprot": "tcp", "sport": "%d" % content['src_port'], "tipv": "ipv4", "tadr": "%s" % content['dst_ip'], "tprot": "tcp", "tport": "undefined", } REQUEST = { "description": "Conpot Honeypot", } # Collect additional Data ADATA = { "conpot_event_type": "%s" % content['event_type'], "conpot_data_type": "%s" % content['data_type'], "conpot_sensor_id": "%s" % content['sensorid'], "conpot_request": "%s" % content['request'], "conpot_id": "%s" % content['id'], "conpot_response": "%s" % content['response'] } # generate template and send esm = buildews(esm, DATA, REQUEST, ADATA) jesm = buildjson(jesm, DATA, REQUEST, ADATA) countme(MODUL, 'fileline', -2, ECFG) countme(MODUL, 'daycounter', -2, ECFG) if ECFG["a.verbose"] is True: verbosemode(MODUL, DATA, REQUEST, ADATA)
def emobility(): MODUL = "EMOBILITY" logme(MODUL, "Starting eMobility Modul.", ("P1"), ECFG) # collect honeypot config dic ITEMS = ("eMobility", "nodeid", "logfile") HONEYPOT = readcfg(MODUL, ITEMS, ECFG["cfgfile"]) # logfile file exists ? if os.path.isfile(HONEYPOT["logfile"]) is False: logme(MODUL, "[ERROR] Missing LogFile " + HONEYPOT["logfile"] + ". Skip !", ("P3", "LOG"), ECFG) # count limit imin = int(countme(MODUL, 'fileline', -1, ECFG)) if int(ECFG["sendlimit"]) > 0: logme( MODUL, "Send Limit is set to : " + str(ECFG["sendlimit"]) + ". Adapting to limit!", ("P1"), ECFG) I = 0 x = 0 y = 1 esm = ewsauth(ECFG["username"], ECFG["token"]) jesm = "" while True: x, y = viewcounter(MODUL, x, y) I += 1 if int(ECFG["sendlimit"]) > 0 and I > int(ECFG["sendlimit"]): break line = getline(HONEYPOT["logfile"], (imin + I)).rstrip() if len(line) == 0: break else: # Prepair and collect Alert Data line = re.sub(r' ', r' ', re.sub(r'[\[\]\-\>]', r'', line)) srcipandport, dstipandport, url, dateandtime = line.split("|", 3) DATA = { "aid": HONEYPOT["nodeid"], "timestamp": "%s-%s-%s %s" % (dateandtime[0:4], dateandtime[4:6], dateandtime[6:8], dateandtime[9:17]), "sadr": "%s.%s.%s.%s" % (srcipandport.split(".")[0], srcipandport.split(".")[1], srcipandport.split(".")[2], srcipandport.split(".")[3]), "sipv": "ipv4", "sprot": "tcp", "sport": srcipandport.split(".")[4], "tipv": "ipv4", "tadr": "%s.%s.%s.%s" % (dstipandport.split(".")[0], dstipandport.split(".")[1], dstipandport.split(".")[2], dstipandport.split(".")[3]), "tprot": "tcp", "tport": dstipandport.split(".")[4], } REQUEST = { "description": "eMobility Honeypot", "url": urllib.quote(url.encode('ascii', 'ignore')) } # Collect additional Data ADATA = {} # generate template and send esm = buildews(esm, DATA, REQUEST, ADATA) jesm = buildjson(jesm, DATA, REQUEST, ADATA) countme(MODUL, 'fileline', -2, ECFG) countme(MODUL, 'daycounter', -2, ECFG) if ECFG["a.verbose"] is True: verbosemode(MODUL, DATA, REQUEST, ADATA) # Cleaning linecache clearcache() if int(esm.xpath('count(//Alert)')) > 0: sendews(esm) writejson(jesm) if y > 1: logme(MODUL, "%s EWS alert records send ..." % (x + y - 2), ("P2"), ECFG) return
def rdpdetect(): MODUL = "RDPDETECT" logme(MODUL, "Starting RDPDetect Modul.", ("P1"), ECFG) # collect honeypot config dic ITEMS = ("rdpdetect", "nodeid", "iptableslog", "targetip") HONEYPOT = readcfg(MODUL, ITEMS, ECFG["cfgfile"]) # iptables file exists ? if os.path.isfile(HONEYPOT["iptableslog"]) is False: logme( MODUL, "[ERROR] Missing Iptables LogFile " + HONEYPOT["iptableslog"] + ". Abort !", ("P3", "LOG"), ECFG) # count limit imin = int(countme(MODUL, 'fileline', -1, ECFG)) if int(ECFG["sendlimit"]) > 0: logme( MODUL, "Send Limit is set to : " + str(ECFG["sendlimit"]) + ". Adapting to limit!", ("P1"), ECFG) I = 0 x = 0 y = 1 esm = ewsauth(ECFG["username"], ECFG["token"]) jesm = "" while True: x, y = viewcounter(MODUL, x, y) I += 1 if int(ECFG["sendlimit"]) > 0 and I > int(ECFG["sendlimit"]): break line = getline(HONEYPOT["iptableslog"], (imin + I)).rstrip() if len(line) == 0: break else: line = re.sub(r' ', r' ', re.sub(r'[\[\]\-\>]', r'', line)) if HONEYPOT["targetip"] == re.search('SRC=(.*?) ', line).groups()[0]: continue # Prepair and collect Alert Data DATA = { "aid": HONEYPOT["nodeid"], "timestamp": "%s-%s-%s %s:%s:%s" % (line[0:4], line[4:6], line[6:8], line[9:11], line[12:14], line[15:17]), "sadr": re.search('SRC=(.*?) ', line).groups()[0], "sipv": "ipv" + ip4or6(re.search('SRC=(.*?) ', line).groups()[0]), "sprot": re.search('PROTO=(.*?) ', line).groups()[0].lower(), "sport": re.search('SPT=(.*?) ', line).groups()[0], "tipv": "ipv" + ip4or6(ECFG["ip"]), "tadr": ECFG["ip"], "tprot": re.search('PROTO=(.*?) ', line).groups()[0].lower(), "tport": re.search('DPT=(.*?) ', line).groups()[0], } REQUEST = {"description": "RDPDetect"} # Collect additional Data ADATA = {} # generate template and send esm = buildews(esm, DATA, REQUEST, ADATA) jesm = buildjson(jesm, DATA, REQUEST, ADATA) countme(MODUL, 'fileline', -2, ECFG) countme(MODUL, 'daycounter', -2, ECFG) if ECFG["a.verbose"] is True: verbosemode(MODUL, DATA, REQUEST, ADATA) # Cleaning linecache clearcache() if int(esm.xpath('count(//Alert)')) > 0: sendews(esm) writejson(jesm) if y > 1: logme(MODUL, "%s EWS alert records send ..." % (x + y - 2), ("P2"), ECFG) return
def honeytrap(): MODUL = "HONEYTRAP" logme(MODUL, "Starting Honeytrap Modul.", ("P1"), ECFG) # collect honeypot config dic ITEMS = ("honeytrap", "nodeid", "attackerfile", "payloaddir", "newversion") HONEYPOT = readcfg(MODUL, ITEMS, ECFG["cfgfile"]) # Attacking file exists ? if os.path.isfile(HONEYPOT["attackerfile"]) is False: logme( MODUL, "[ERROR] Missing Attacker File " + HONEYPOT["attackerfile"] + ". Abort !", ("P3", "LOG"), ECFG) # Payloaddir exist ? if os.path.isdir(HONEYPOT["payloaddir"]) is False: logme( MODUL, "[ERROR] Missing Payload Dir " + HONEYPOT["payloaddir"] + ". Abort !", ("P3", "LOG"), ECFG) # New Version are use ? if HONEYPOT["newversion"].lower() == "true" and not os.path.isdir( HONEYPOT["payloaddir"]): logme( MODUL, "[ERROR] Missing Payload Directory " + HONEYPOT["payloaddir"] + ". Abort !", ("P3", "LOG"), ECFG) # Calc MD5sum for Payloadfiles if HONEYPOT["newversion"].lower() == "true": logme(MODUL, "Calculate MD5sum for Payload Files", ("P2"), ECFG) for i in os.listdir(HONEYPOT["payloaddir"]): if not "_md5_" in i: filein = HONEYPOT["payloaddir"] + os.sep + i os.rename( filein, filein + "_md5_" + hashlib.md5(open(filein, 'rb').read()).hexdigest()) # count limit imin = int(countme(MODUL, 'fileline', -1, ECFG)) if int(ECFG["sendlimit"]) > 0: logme( MODUL, "Send Limit is set to : " + str(ECFG["sendlimit"]) + ". Adapting to limit!", ("P1"), ECFG) I = 0 x = 0 y = 1 esm = ewsauth(ECFG["username"], ECFG["token"]) jesm = "" while True: x, y = viewcounter(MODUL, x, y) I += 1 if int(ECFG["sendlimit"]) > 0 and I > int(ECFG["sendlimit"]): break line = getline(HONEYPOT["attackerfile"], (imin + I)).rstrip() if len(line) == 0: break else: line = re.sub(r' ', r' ', re.sub(r'[\[\]\-\>]', r'', line)) if HONEYPOT["newversion"].lower() == "false": date, time, _, source, dest, _ = line.split(" ", 5) protocol = "" md5 = "" else: date, time, _, protocol, source, dest, md5, _ = line.split( " ", 7) # Prepair and collect Alert Data DATA = { "aid": HONEYPOT["nodeid"], "timestamp": "%s-%s-%s %s" % (date[0:4], date[4:6], date[6:8], time[0:8]), "sadr": re.sub(":.*$", "", source), "sipv": "ipv" + ip4or6(re.sub(":.*$", "", source)), "sprot": protocol, "sport": re.sub("^.*:", "", source), "tipv": "ipv" + ip4or6(re.sub(":.*$", "", dest)), "tadr": re.sub(":.*$", "", dest), "tprot": protocol, "tport": re.sub("^.*:", "", dest), } REQUEST = {"description": "NetworkHoneypot Honeytrap v1.1"} # Search for Payload if HONEYPOT["newversion"].lower() == "true": sfile = "from_port_%s-%s_*_%s-%s-%s_md5_%s" % (re.sub( "^.*:", "", dest), protocol, date[0:4], date[4:6], date[6:8], md5) for mfile in os.listdir(HONEYPOT["payloaddir"]): if fnmatch.fnmatch(mfile, sfile): error, payloadfile = malware(HONEYPOT["payloaddir"], mfile, False) if error == 0: REQUEST["raw"] = payloadfile else: logme(MODUL, "Mission Malwarefile %s" % row["filename"], ("P1", "LOG"), ECFG) # Collect additional Data ADATA = {} # generate template and send esm = buildews(esm, DATA, REQUEST, ADATA) jesm = buildjson(jesm, DATA, REQUEST, ADATA) countme(MODUL, 'fileline', -2, ECFG) countme(MODUL, 'daycounter', -2, ECFG) if ECFG["a.verbose"] is True: verbosemode(MODUL, DATA, REQUEST, ADATA) # Cleaning linecache clearcache() if int(esm.xpath('count(//Alert)')) > 0: sendews(esm) writejson(jesm) if y > 1: logme(MODUL, "%s EWS alert records send ..." % (x + y - 2), ("P2"), ECFG) return
def ecfg(name, version): MODUL = "EINIT" ECFG = {} ECFG['HONEYLIST'] = [ 'glastopfv3', 'dionaea', 'honeytrap', 'emobility', 'conpot', 'cowrie', 'elasticpot', 'suricata', 'rdpy', 'mailoney', 'vnclowpot', 'heralding', 'ciscoasa', 'tanner', 'glutton', 'honeysap', 'adbhoney', 'fatt', 'ipphoney', 'dicompot', 'medpot', 'honeypy', 'citrix' ] parser = argparse.ArgumentParser() parser.add_argument("-c", "--configpath", help="load configuration file from Path") parser.add_argument("-v", "--verbose", help="set output verbosity", action="store_true") parser.add_argument("-d", "--debug", help="set output debug", action="store_true") parser.add_argument( "-l", "--loop", help="endless loop. Set {xx} for seconds to wait for next loop", type=int, default=0, action="store") parser.add_argument("-m", "--modul", help="only send alerts for this modul", choices=ECFG['HONEYLIST'], action="store") parser.add_argument("-s", "--silent", help="silent mode without output", action="store_true") parser.add_argument("-i", "--ignorecert", help="ignore certificate warnings", action="store_true") parser.add_argument("-S", "--sendonly", help="only send unsend alerts", action="store_true") parser.add_argument("-E", "--ewsonly", help="only generate ews alerts files", action="store_true") parser.add_argument("-j", "--jsonpath", help="write JSON output file to path") parser.add_argument( "-L", "--sendlimit", help="set {xxx} for max alerts will send in one session", type=int, action="store") parser.add_argument("-V", "--version", help="show the EWS Poster Version", action="version", version=f"{name} {version}") args = parser.parse_args() ECFG["a.sendlimit"] = (args.sendlimit if args.sendlimit else 0) ECFG["a.loop"] = (args.loop if args.loop else 0) ECFG["a.verbose"] = (True if args.verbose else False) ECFG["a.debug"] = (True if args.debug else False) ECFG["a.ignorecert"] = (True if args.ignorecert else False) ECFG["a.silent"] = (True if args.silent else False) ECFG["a.sendonly"] = (True if args.sendonly else False) ECFG["a.ewsonly"] = (True if args.ewsonly else False) ECFG["a.modul"] = (args.modul if args.modul and args.modul in ECFG['HONEYLIST'] else "") ECFG["a.path"] = (args.configpath if args.configpath else "") ECFG["a.jsondir"] = (args.jsonpath if args.jsonpath else "") if ECFG["a.path"] != "" and os.path.isdir(ECFG["a.path"]) is False: logger.error( f"ConfigDir {ECFG['a.path']} from commandline argument -c/--configpath did not exist. Abort!", '1E') if ECFG["a.jsondir"] != "" and os.path.isdir(ECFG["a.jsondir"]) is False: logger.error( f"JsonDir {ECFG['a.jsondir']} from commandline argument -j/--jsonpath did not exist. Abort!", '1E') """ say hello """ print( f"{name} {version} (c) by Markus Schroer <*****@*****.**>") """ set name and version """ ECFG['name'] = name ECFG['version'] = version """ read EWSPoster Main Path """ ECFG["path"] = os.path.dirname(os.path.abspath(__file__)).replace( "/moduls", "") if ECFG["a.path"] != "": ECFG["path"] = ECFG["a.path"] if os.path.isfile(ECFG["path"] + os.sep + "ews.cfg") is False: logger.error( f"Missing EWS Config {ECFG['path']}{os.sep}ews.cfg. Abort!", '1E') else: ECFG["cfgfile"] = ECFG["path"] + os.sep + "ews.cfg" """ Create IDX File if not exist """ if os.path.isfile(ECFG["path"] + os.sep + "ews.idx") is False: os.open(ECFG["path"] + os.sep + "ews.idx", os.O_RDWR | os.O_CREAT) logger.info(f"Create ews.idx counterfile.", '1') """ Read Main Config Parameter """ ITEMS = ("homedir", "spooldir", "logdir", "del_malware_after_send", "send_malware", "sendlimit", "contact", "proxy", "ip_int", "ip_ext") MCFG = readcfg('MAIN', ITEMS, ECFG['cfgfile']) """ home dir available ? """ if os.path.isdir(MCFG["homedir"]) is False: logger.error(f"Missing homedir {MCFG['homedir']}. Abort!", '1E') else: os.chdir(MCFG["homedir"]) """ spool dir available ? """ if os.path.isdir(MCFG["spooldir"]) is False: logger.error(f"Missing spooldir {MCFG['spooldir']}. Abort!", '1E') """ log dir available ? """ if os.path.isdir(MCFG["logdir"]) is False: logger.error(f"Missing logdir {MCFG['logdir']}. Abort!", '1E') else: MCFG["logfile"] = MCFG["logdir"] + os.sep + "ews.log" """ del_malware_after_send ? """ if MCFG["del_malware_after_send"].lower() == "true": MCFG["del_malware_after_send"] = True else: MCFG["del_malware_after_send"] = False """ send_malware ? """ if MCFG["send_malware"].lower() == "true": MCFG["send_malware"] = True else: MCFG["send_malware"] = False """ sendlimit expect """ if int(ECFG["a.sendlimit"]) > 0: MCFG["sendlimit"] = ECFG["a.sendlimit"] if int(MCFG["sendlimit"]) > 5000: logger.error(f"Sendlimit {str(MCFG['sendlimit'])} to high. Max 5000!", '1E') elif int(MCFG["sendlimit"]) < 1: logger.error(f"Sendlimit {str(MCFG['sendlimit'])} to low. Min 1!", '1E') elif MCFG["sendlimit"] is None: logger.error( f"Sendlimit {str(MCFG['sendlimit'])}. Must set between 1 and 5000.", '1E') """ contact """ """ Proxy Settings """ if MCFG["proxy"] == "" or MCFG["proxy"].lower( ) == "false" or MCFG["proxy"].lower() == "none": MCFG["proxy"] = False """ ip_int and ip_ext""" if MCFG["ip_int"] != "" and MCFG["ip_int"].lower() != "none": try: ipaddress.ip_address(MCFG["ip_int"]) except (ipaddress.AddressValueError, ValueError) as e: logger.error( f"ip_int Address {str(e)} in [EWS] is not an IPv4/IPv6 address. Abort!", '1E') if MCFG["ip_ext"] != "" and MCFG["ip_ext"].lower() != "none": try: ipaddress.ip_address(MCFG["ip_ext"]) except (ipaddress.AddressValueError, ValueError) as e: logger.error( f"ip_ext Address {str(e)} in [EWS] config section is not an IPv4/IPv6 address. Abort!", '1E') """ Read EWS Config Parameter """ ITEMS = ("ews", "username", "token", "rhost_first", "rhost_second", "ignorecert") EWSCFG = readcfg("EWS", ITEMS, ECFG["cfgfile"]) if EWSCFG["ews"].lower() == "true": EWSCFG["ews"] = True else: EWSCFG["ews"] = False for index in ["username", "token", "rhost_first", "rhost_second"]: if EWSCFG[index] == "" and EWSCFG["ews"] is True: logger.error(f"Missing {index} in [EWS] config section. Abort!", '1E') if ECFG["a.ignorecert"] is True: EWSCFG["ignorecert"] = True elif EWSCFG["ignorecert"].lower() == "true": EWSCFG["ignorecert"] = True else: EWSCFG["ignorecert"] = False """ Read HPFEED Config Parameter """ ITEMS = ("hpfeed", "host", "port", "channels", "ident", "secret", "hpfformat", "tlscert") HCFG = readcfg("HPFEED", ITEMS, ECFG["cfgfile"]) if HCFG["hpfeed"].lower() == "true": HCFG["hpfeed"] = True for index in ["host", "port", "channels", "ident", "secret"]: if HCFG[index] == "" and HCFG["hpfeed"] is True: logger.error( f"Missing {index} in [HPFEED] config section. Abort!", '1E') if HCFG["hpfformat"].lower() not in ("ews", "json"): HCFG["hpfformat"] = "ews" if HCFG["tlscert"].lower() == "none" or HCFG["tlscert"] == "false": HCFG["tlscert"] = "none" elif os.path.isfile(HCFG["tlscert"]) is False: logger.error( f"Missing TLS cert {HCFG['tlscert']}. Use tlscert = none", '1') HCFG["tlscert"] = "none" else: logger.info(f"Use TLS cert {HCFG['tlscert']} for HPFeed transfer.", '1') else: HCFG["hpfeed"] = False """ Read EWSJSON Config Parameter """ ITEMS = ("json", "jsondir") EWSJSON = readcfg("EWSJSON", ITEMS, ECFG["cfgfile"]) if ECFG["a.jsondir"] != "": EWSJSON["json"] = True EWSJSON["jsondir"] = ECFG["a.jsondir"] + os.sep + "ews.json" elif EWSJSON["json"].lower() == "true": EWSJSON["json"] = True if os.path.isdir(EWSJSON["jsondir"]) is True: EWSJSON["jsondir"] = EWSJSON["jsondir"] + os.sep + "ews.json" else: logger.error( f"Missing jsondir {EWSJSON['jsondir']} in [EWSJSON]. Abort!", '1E') else: EWSJSON["json"] = False """ Read INFLUX Config Parameter """ ITEMS = ('influxdb', 'host', 'port', 'username', 'password', 'token', 'bucket', 'org') ICFG = readcfg2("INFLUXDB", ITEMS, ECFG["cfgfile"]) if 'influxdb' not in ICFG: ICFG['influxdb'] = False elif ICFG['influxdb'].lower() == "true": ICFG['influxdb'] = True else: ICFG['influxdb'] = False if ICFG['influxdb'] is True: for index in [ 'host', 'port', 'username', 'password', 'token', 'bucket', 'org' ]: if ICFG[index] == '' and ICFG["influxdb"] is True: logger.error( f"Missing {index} in [INFLUXDB] config section. Abort!", '1E') else: ICFG['influx_' + index] = ICFG[index] ICFG[index] = '' ECFG.update(ICFG) ECFG.update(MCFG) ECFG.update(EWSCFG) ECFG.update(HCFG) ECFG.update(EWSJSON) """ Setup UUID """ if os.environ.get('HONEY_UUID') is not None: ECFG['uuid'] = os.environ.get('HONEY_UUID') else: if os.path.isfile(ECFG["path"] + os.sep + "ews.uuid"): with open(ECFG["path"] + os.sep + "ews.uuid", 'r') as filein: ECFG['uuid'] = str(filein.read()) filein.close() else: with open(ECFG["path"] + os.sep + "ews.uuid", 'w') as fileout: ECFG['uuid'] = str(uuid.uuid4()) fileout.write(ECFG['uuid']) fileout.close() """ Setup Hostname """ ECFG['hostname'] = getHostname(MODUL, ECFG) """ Collection IP Config, Enviroment, lookup """ IPCFG = getIP(MODUL, ECFG) for place in ['ip_int', 'ip_ext']: """ ip in ews.cfg """ if ECFG[place] == "" or ECFG[place].lower() == "none": ECFG[place] = IPCFG['env_' + place] """ ip in env """ if ECFG[place] == "" or ECFG[place].lower() == "none": ECFG[place] = IPCFG['file_' + place] """ ip in ews.ip """ if ECFG[place] == "" or ECFG[place].lower() == "none": ECFG[place] = IPCFG['connect_' + place] """ ip from connection """ if ECFG[place] == "" or ECFG[place].lower() == "none": logger.error(f"{place} is 'none' or empty. Abort!", '1E') return (ECFG)
def ecfg(name,version): MODUL = "EINIT" ECFG= {} parser = argparse.ArgumentParser() parser.add_argument("-c","--configpath", help="Load configuration file from Path") parser.add_argument("-v","--verbose", help="set output verbosity",action="store_true") parser.add_argument("-d","--debug", help="set output debug",action="store_true") parser.add_argument("-s","--silent", help="silent mode without output",action="store_true") parser.add_argument("-S","--sendonly", help="only send unsend alerts",action="store_true") parser.add_argument("-E","--ewsonly", help="only generate ews alerts files",action="store_true") parser.add_argument("-dcr","--daycounter", help="reset and log daycounters for all honeypots",action="store_true") parser.add_argument("-V","--version", help="show the EWS Poster Version",action="version", version=name + " " + version) args = parser.parse_args() if args.verbose: ECFG["a.verbose"] = True else: ECFG["a.verbose"] = False if args.debug: ECFG["a.debug"] = True else: ECFG["a.debug"] = False if args.silent: ECFG["a.silent"] = True else: ECFG["a.silent"] = False if args.daycounter: ECFG["a.daycounter"] = True else: ECFG["a.daycounter"] = False if args.sendonly: ECFG["a.sendonly"] = True else: ECFG["a.sendonly"] = False if args.ewsonly: ECFG["a.ewsonly"] = True else: ECFG["a.ewsonly"] = False if args.configpath: ECFG["path2"] = args.configpath if os.path.isdir(args.configpath) is not True: logme(MODUL,"ConfigPath %s did not exist. Abort !" % (args.configpath),("P1","EXIT"),ECFG) else: ECFG["path2"] = "" # say hello logme(MODUL,name + " " + version + " (c) by Markus Schroer <*****@*****.**>\n",("P0"),ECFG) # read EWSPoster Main Path ECFG["path"] = os.path.dirname(os.path.abspath(__file__)).replace("/moduls","") if ECFG["path2"] == "": ECFG["path2"] = ECFG["path"] if os.path.isfile(ECFG["path2"] + os.sep + "ews.cfg" ) is False: logme(MODUL,"Missing EWS Config %s. Abort !"%(ECFG["path2"] + os.sep + "ews.cfg"),("P1","EXIT"),ECFG) else: ECFG["cfgfile"] = ECFG["path2"] + os.sep + "ews.cfg" # Create IDX File if not exist if os.path.isfile(ECFG["path"] + os.sep + "ews.idx" ) is False: os.open(ECFG["path"] + os.sep + "ews.idx", os.O_RDWR|os.O_CREAT ) logme(MODUL,"Create ews.idx counterfile",("P1"),ECFG) # Read Main Config Parameter ITEMS = ("homedir","spooldir","logdir","contact","del_malware_after_send","send_malware","sendlimit") MCFG = readcfg("MAIN",ITEMS, ECFG["cfgfile"]) # IP Handling ewsip = ECFG["path2"] + os.sep + "ews.ip" MCFG["ip"] = readonecfg("MAIN","ip", ECFG["cfgfile"]) if os.path.isfile(ewsip) is True: MCFG["ip"] = readonecfg("MAIN","ip", ewsip) if MCFG["ip"].lower() == "null": logme(MODUL,"Error IP Address in File " + ewsip + " not set. Abort !",("P1","EXIT"),ECFG) if MCFG["ip"].lower() == "null" or MCFG["ip"].lower() == "false": logme(MODUL,"Error IP Address in ews.cfg not set or null. Abort !",("P1","EXIT"),ECFG) # sendlimit expect if int(MCFG["sendlimit"]) > 400: logme(MODUL,"Error Sendlimit " + MCFG["sendlimit"] + " to high. Max 400 ! ",("P1","EXIT"),ECFG) elif int(MCFG["sendlimit"]) < 1: logme(MODUL,"Error Sendlimit " + MCFG["sendlimit"] + " to low. Min 1 ! ",("P1","EXIT"),ECFG) elif MCFG["sendlimit"] == "NULL" or MCFG["sendlimit"] == "UNKNOW": logme(MODUL,"Error Sendlimit " + MCFG["sendlimit"] + " Must set between 1 and 400. ",("P1","EXIT"),ECFG) # send_malware ? if MCFG["send_malware"].lower() == "true": MCFG["send_malware"] = True else: MCFG["send_malware"] = False # del_malware_after_send ? if MCFG["del_malware_after_send"].lower() == "true": MCFG["del_malware_after_send"] = True else: MCFG["del_malware_after_send"] = False # home dir available ? if os.path.isdir(MCFG["homedir"]) is not True: logme(MODUL,"Error missing homedir " + MCFG["homedir"] + " Abort !",("P1","EXIT"),ECFG) else: os.chdir(MCFG["homedir"]) # spool dir available ? if os.path.isdir(MCFG["spooldir"]) is not True: logme(MODUL,"Error missing spooldir " + MCFG["spooldir"] + " Abort !",("P1","EXIT"),ECFG) # log dir available ? MCFG["logdir"] = readonecfg("MAIN","logdir", ECFG["cfgfile"]) if MCFG["logdir"] != "NULL" and MCFG["logdir"] != "FALSE" and os.path.isdir(MCFG["logdir"]) is True: MCFG["logfile"] = MCFG["logdir"] + os.sep + "ews.log" elif MCFG["logdir"] != "NULL" and MCFG["logdir"] != "FALSE" and os.path.isdir(MCFG["logdir"]) is True: logme(MODUL,"Error missing logdir " + MCFG["logdir"] + " Abort !",("P1","EXIT"),ECFG) else: MCFG["logfile"] = "/var/log" + os.sep + "ews.log" # Proxy Settings ? MCFG["proxy"] = readonecfg(MODUL,"proxy", ECFG["cfgfile"]) # Read EWS Config Parameter ITEMS = ("ews","username","token","rhost_first","rhost_second") EWSCFG = readcfg("EWS",ITEMS, ECFG["cfgfile"]) # Set ews real true or false if EWSCFG["ews"].lower() == "true": EWSCFG["ews"] = True else: EWSCFG["ews"] = False # Read HPFEED Config Parameter ITEMS = ("hpfeed","host","port","channels","ident","secret") HCFG = readcfg("HPFEED",ITEMS, ECFG["cfgfile"]) if HCFG["hpfeed"].lower() == "true": HCFG["hpfeed"] = True else: HCFG["hpfeed"] = False # Read EWSJSON Config Parameter ITEMS = ("json","jsondir") EWSJSON = readcfg("EWSJSON",ITEMS, ECFG["cfgfile"]) if EWSJSON["json"].lower() == "true": EWSJSON["json"] = True else: EWSJSON["json"] = False if EWSJSON["jsondir"] != "NULL" and EWSJSON["jsondir"] != "FALSE" and os.path.isdir(EWSJSON["jsondir"]) is True: EWSJSON["jsondir"] = EWSJSON["jsondir"] + os.sep + "ews.json" else: logme(MODUL,"Error missing jsondir " + EWSJSON["jsondir"] + " Abort !",("P1","EXIT"),ECFG) ECFG.update(MCFG) ECFG.update(EWSCFG) ECFG.update(HCFG) ECFG.update(EWSJSON) return ECFG
def rdpdetect(): MODUL = "RDPDETECT" logme(MODUL,"Starting RDPDetect Modul.",("P1"),ECFG) # collect honeypot config dic ITEMS = ("rdpdetect","nodeid","iptableslog","targetip") HONEYPOT = readcfg(MODUL,ITEMS,ECFG["cfgfile"]) # iptables file exists ? if os.path.isfile(HONEYPOT["iptableslog"]) is False: logme(MODUL,"[ERROR] Missing Iptables LogFile " + HONEYPOT["iptableslog"] + ". Abort !",("P3","LOG"),ECFG) # count limit imin = int(countme(MODUL,'fileline',-1,ECFG)) if int(ECFG["sendlimit"]) > 0: logme(MODUL,"Send Limit is set to : " + str(ECFG["sendlimit"]) + ". Adapting to limit!",("P1"),ECFG) I = 0 ; x = 0 ; y = 1 esm = ewsauth(ECFG["username"],ECFG["token"]) jesm = [ ] while True: x,y = viewcounter(MODUL,x,y) I += 1 if int(ECFG["sendlimit"]) > 0 and I > int(ECFG["sendlimit"]): break line = getline(HONEYPOT["iptableslog"],(imin + I)).rstrip() if len(line) == 0: break else: line = re.sub(r' ',r' ',re.sub(r'[\[\]\-\>]',r'',line)) if HONEYPOT["targetip"] == re.search('SRC=(.*?) ', line).groups()[0]: continue # Prepair and collect Alert Data DATA = { "aid" : HONEYPOT["nodeid"], "timestamp" : "%s-%s-%s %s:%s:%s" % (line[0:4], line[4:6], line[6:8], line[9:11], line[12:14], line[15:17]), "sadr" : re.search('SRC=(.*?) ', line).groups()[0], "sipv" : "ipv" + ip4or6(re.search('SRC=(.*?) ', line).groups()[0]), "sprot" : re.search('PROTO=(.*?) ', line).groups()[0].lower(), "sport" : re.search('SPT=(.*?) ', line).groups()[0], "tipv" : "ipv" + ip4or6(ECFG["ip"]), "tadr" : ECFG["ip"], "tprot" : re.search('PROTO=(.*?) ', line).groups()[0].lower(), "tport" : re.search('DPT=(.*?) ', line).groups()[0], } REQUEST = { "description" : "RDPDetect" } # Collect additional Data ADATA = { } # generate template and send esm = buildews(esm,DATA,REQUEST,ADATA) jesm = buildjson(jesm,DATA,REQUEST,ADATA) countme(MODUL,'fileline',-2,ECFG) countme(MODUL,'daycounter', -2,ECFG) if ECFG["a.verbose"] is True: verbosemode(MODUL,DATA,REQUEST,ADATA) if int(esm.xpath('count(//Alert)')) > 0: sendews(esm) writejson(jesm) if y > 1: logme(MODUL,"%s EWS alert records send ..." % (x+y-2),("P2"),ECFG) return
def honeytrap(): MODUL = "HONEYTRAP" logme(MODUL,"Starting Honeytrap Modul.",("P1"),ECFG) # collect honeypot config dic ITEMS = ("honeytrap","nodeid","attackerfile","payloaddir","newversion") HONEYPOT = readcfg(MODUL,ITEMS,ECFG["cfgfile"]) # Attacking file exists ? if os.path.isfile(HONEYPOT["attackerfile"]) is False: logme(MODUL,"[ERROR] Missing Attacker File " + HONEYPOT["attackerfile"] + ". Abort !",("P3","LOG"),ECFG) # Payloaddir exist ? if os.path.isdir(HONEYPOT["payloaddir"]) is False: logme(MODUL,"[ERROR] Missing Payload Dir " + HONEYPOT["payloaddir"] + ". Abort !",("P3","LOG"),ECFG) # New Version are use ? if HONEYPOT["newversion"].lower() == "true" and not os.path.isdir(HONEYPOT["payloaddir"]): logme(MODUL,"[ERROR] Missing Payload Directory " + HONEYPOT["payloaddir"] + ". Abort !",("P3","LOG"),ECFG) # Calc MD5sum for Payloadfiles if HONEYPOT["newversion"].lower() == "true": logme(MODUL,"Calculate MD5sum for Payload Files",("P2"),ECFG) for i in os.listdir(HONEYPOT["payloaddir"]): if not "_md5_" in i: filein = HONEYPOT["payloaddir"] + os.sep + i os.rename(filein,filein + "_md5_" + hashlib.md5(open(filein, 'rb').read()).hexdigest()) # count limit imin = int(countme(MODUL,'fileline',-1,ECFG)) if int(ECFG["sendlimit"]) > 0: logme(MODUL,"Send Limit is set to : " + str(ECFG["sendlimit"]) + ". Adapting to limit!",("P1"),ECFG) I = 0 ; x = 0 ; y = 1 esm = ewsauth(ECFG["username"],ECFG["token"]) jesm = [ ] while True: x,y = viewcounter(MODUL,x,y) I += 1 if int(ECFG["sendlimit"]) > 0 and I > int(ECFG["sendlimit"]): break line = getline(HONEYPOT["attackerfile"],(imin + I)).rstrip() if len(line) == 0: break else: line = re.sub(r' ',r' ',re.sub(r'[\[\]\-\>]',r'',line)) if HONEYPOT["newversion"].lower() == "false": date , time , _ , source, dest, _ = line.split(" ",5) protocol = "" ; md5 = "" else: date , time , _ , protocol, source, dest, md5, _ = line.split(" ",7) # Prepair and collect Alert Data DATA = { "aid" : HONEYPOT["nodeid"], "timestamp" : "%s-%s-%s %s" % (date[0:4], date[4:6], date[6:8], time[0:8]), "sadr" : re.sub(":.*$","",source), "sipv" : "ipv" + ip4or6(re.sub(":.*$","",source)), "sprot" : protocol, "sport" : re.sub("^.*:","",source), "tipv" : "ipv" + ip4or6(re.sub(":.*$","",dest)), "tadr" : re.sub(":.*$","",dest), "tprot" : protocol, "tport" : re.sub("^.*:","",dest), } REQUEST = { "description" : "NetworkHoneypot Honeytrap vX.x" } # Search for Payload if HONEYPOT["newversion"].lower() == "true": sfile = "from_port_%s-%s_*_%s-%s-%s_md5_%s" % (re.sub("^.*:","",dest),protocol,date[0:4], date[4:6], date[6:8],md5) for mfile in os.listdir(HONEYPOT["payloaddir"]): if fnmatch.fnmatch(mfile, sfile): error , payloadfile = malware(HONEYPOT["payloaddir"],mfile,False) if error == 0: REQUEST["raw"] = payloadfile else: logme(MODUL,"Mission Malwarefile %s" % row["filename"] ,("P1","LOG"),ECFG) # Collect additional Data ADATA = { } # generate template and send esm = buildews(esm,DATA,REQUEST,ADATA) jesm = buildjson(jesm,DATA,REQUEST,ADATA) countme(MODUL,'fileline',-2,ECFG) countme(MODUL,'daycounter', -2,ECFG) if ECFG["a.verbose"] is True: verbosemode(MODUL,DATA,REQUEST,ADATA) if int(esm.xpath('count(//Alert)')) > 0: sendews(esm) writejson(jesm) if y > 1: logme(MODUL,"%s EWS alert records send ..." % (x+y-2),("P2"),ECFG) return
def dionaea(): MODUL = "DIONAEA" logme(MODUL,"Starting Dionaea Modul.",("P1"),ECFG) # collect honeypot config dic ITEMS = ("dionaea","nodeid","sqlitedb","malwaredir") HONEYPOT = readcfg(MODUL,ITEMS,ECFG["cfgfile"]) # Malwaredir exist ? if os.path.isdir(HONEYPOT["malwaredir"]) is False: logme(MODUL,"[ERROR] Missing Malware Dir " + HONEYPOT["malwaredir"] + ". Abort !",("P3","LOG"),ECFG) # is sqlitedb exist ? if os.path.isfile(HONEYPOT["sqlitedb"]) is False: logme(MODUL,"[ERROR] Missing sqlitedb file " + HONEYPOT["sqlitedb"] + ". Abort !",("P3","LOG"),ECFG) return # open database con = sqlite3.connect(HONEYPOT["sqlitedb"],30) con.row_factory = sqlite3.Row c = con.cursor() # calculate send limit c.execute("SELECT max(connection) from connections;") maxid = c.fetchone()["max(connection)"] if maxid is None: logme(MODUL,"[ERROR] No entry's in Dionaea Database. Abort!",("P2","LOG"),ECFG) return imin, imax = calcminmax(MODUL,int(countme(MODUL,'sqliteid',-1,ECFG)),int(maxid),ECFG) # read alerts from database c.execute("SELECT * from connections where connection > ? and connection <= ?;",(imin,imax,)) rows = c.fetchall() # counter inits x = 0 ; y = 1 esm = ewsauth(ECFG["username"],ECFG["token"]) jesm = [ ] for row in rows: x,y = viewcounter(MODUL,x,y) # filter empty remote_host if row["remote_host"] == "": countme(MODUL,'sqliteid',row["connection"],ECFG) continue # Prepair and collect Alert Data DATA = { "aid" : HONEYPOT["nodeid"], "timestamp" : datetime.fromtimestamp(int(row["connection_timestamp"])).strftime('%Y-%m-%d %H:%M:%S'), "sadr" : str(row["remote_host"]), "sipv" : "ipv" + ip4or6(str(row["remote_host"])), "sprot" : str(row["connection_type"]), "sport" : str(row["remote_port"]), "tipv" : "ipv" + ip4or6(str(row["local_host"])), "tadr" : str(row["local_host"]), "tprot" : str(row["connection_type"]), "tport" : str(row["local_port"]), } REQUEST = { "description" : "Network Honeyport Dionaea vX.x", } # Check for malware bin's c.execute("SELECT download_md5_hash from downloads where connection = ?;",(str(row["connection"]),)) check = c.fetchone() if check is not None: error,malwarefile = malware(HONEYPOT["malwaredir"],check[0],ECFG["del_malware_after_send"]) if error == 0: REQUEST["binary"] = malwarefile else: logme(MODUL,"Mission Malwarefile %s" % row["filename"] ,("P1","LOG"),ECFG) # Collect additional Data ADATA = { "sqliteid" : str(row["connection"]), } # generate template and send esm = buildews(esm,DATA,REQUEST,ADATA) jesm = buildjson(jesm,DATA,REQUEST,ADATA) countme(MODUL,'sqliteid',row["connection"],ECFG) countme(MODUL,'daycounter', -2,ECFG) if ECFG["a.verbose"] is True: verbosemode(MODUL,DATA,REQUEST,ADATA) con.close() if int(esm.xpath('count(//Alert)')) > 0: sendews(esm) writejson(jesm) if y > 1: logme(MODUL,"%s EWS alert records send ..." % (x+y-1),("P2"),ECFG) return
def glastopfv3(): MODUL = "GLASTOPFV3" logme(MODUL,"Starting Glastopf V3.x Modul.",("P1"),ECFG) # collect honeypot config dic ITEMS = ("glastopfv3","nodeid","sqlitedb","malwaredir") HONEYPOT = readcfg(MODUL,ITEMS,ECFG["cfgfile"]) HONEYPOT["ip"] = readonecfg(MODUL,"ip", ECFG["cfgfile"]) if HONEYPOT["ip"].lower() == "false" or HONEYPOT["ip"].lower() == "null": HONEYPOT["ip"] = ECFG["ip"] # Malwaredir exist ? Issue in Glastopf ! RFI Directory first create when the first RFI was downloaded #if os.path.isdir(HONEYPOT["malwaredir"]) == False: # logme(MODUL,"[ERROR] Missing Malware Dir " + HONEYPOT["malwaredir"] + ". Abort !",("P3","LOG"),ECFG) # return # is sqlitedb exist ? if os.path.isfile(HONEYPOT["sqlitedb"]) is False: logme(MODUL,"[ERROR] Missing sqlitedb file " + HONEYPOT["sqlitedb"] + ". Abort !",("P3","LOG"),ECFG) return # open database con = sqlite3.connect(HONEYPOT["sqlitedb"],30) con.row_factory = sqlite3.Row c = con.cursor() # calculate send limit c.execute("SELECT max(id) from events") maxid = c.fetchone()["max(id)"] if maxid is None: logme(MODUL,"[ERROR] No entry's in Glastopf Database. Abort!",("P2","LOG"),ECFG) return imin, imax = calcminmax(MODUL,int(countme(MODUL,'sqliteid',-1,ECFG)),int(maxid),ECFG) # read alerts from database c.execute("SELECT * from events where id > ? and id <= ?;",(imin,imax)) rows = c.fetchall() # counter inits x = 0 ; y = 1 esm = ewsauth(ECFG["username"],ECFG["token"]) jesm = [ ] for row in rows: x,y = viewcounter(MODUL,x,y) # filter empty requests and nagios checks if row["request_url"] == os.sep or row["request_url"] == "/index.do?hash=DEADBEEF&activate=1": countme(MODUL,'sqliteid',row["id"],ECFG) continue # Prepair and collect Alert Data DATA = { "aid" : HONEYPOT["nodeid"], "timestamp" : row["time"], "sadr" : re.sub(":.*$","",row["source"]), "sipv" : "ipv" + ip4or6(re.sub(":.*$","",row["source"])), "sprot" : "tcp", "sport" : "", "tipv" : "ipv" + ip4or6(HONEYPOT["ip"]), "tadr" : HONEYPOT["ip"], "tprot" : "tcp", "tport" : "80", } REQUEST = { "description" : "WebHoneypot : Glastopf v3.1", "url" : urllib.quote(row["request_url"]) } if "request_raw" in row.keys() and len(row["request_raw"]) > 0: #REQUEST["raw"] = base64.standard_b64encode(row["request_raw"]) REQUEST["raw"] = base64.encodestring(row["request_raw"]) if "filename" in row.keys() and row["filename"] != None: error,malwarefile = malware(HONEYPOT["malwaredir"],row["filename"],ECFG["del_malware_after_send"]) if error == 0: REQUEST["binary"] = malwarefile else: logme(MODUL,"Mission Malwarefile %s" % row["filename"] ,("P1","LOG"),ECFG) # Collect additional Data ADATA = { "sqliteid" : row ["id"], } if "request_method" in row.keys(): ADATA["httpmethod"] = row["request_method"] if "request_raw" in row.keys(): m = re.search( r'Host: (\b.+\b)', row["request_raw"] , re.M) if m: ADATA["host"] = str(m.group(1)) if "request_header" in row.keys(): if 'Host' in json.loads(row["request_header"]): ADATA["host"] = str(json.loads(row["request_header"])["Host"]) if "request_body" in row.keys(): if len(row["request_body"]) > 0: ADATA["requestbody"] = row["request_body"] esm = buildews(esm,DATA,REQUEST,ADATA) jesm = buildjson(jesm,DATA,REQUEST,ADATA) countme(MODUL,'sqliteid',row["id"],ECFG) countme(MODUL,'daycounter', -2,ECFG) if ECFG["a.verbose"] is True: verbosemode(MODUL,DATA,REQUEST,ADATA) con.close() if int(esm.xpath('count(//Alert)')) > 0: sendews(esm) writejson(jesm) if y > 1: logme(MODUL,"%s EWS alert records send ..." % (x+y-1),("P2"),ECFG) return
def cowrie(): MODUL = "COWRIE" logme(MODUL, "Starting Cowrie Modul.", ("P1"), ECFG) # collect honeypot config dic ITEMS = ("cowrie", "nodeid", "logfile") HONEYPOT = readcfg(MODUL, ITEMS, ECFG["cfgfile"]) HONEYPOT["ip"] = readonecfg(MODUL, "ip", ECFG["cfgfile"]) if HONEYPOT["ip"].lower() == "false" or HONEYPOT["ip"].lower() == "null": HONEYPOT["ip"] = ECFG["ip"] # logfile file exists ? if os.path.isfile(HONEYPOT["logfile"]) is False: logme(MODUL, "[ERROR] Missing LogFile " + HONEYPOT["logfile"] + ". Skip !", ("P3", "LOG"), ECFG) # count limit imin = int(countme(MODUL, 'fileline', -1, ECFG)) if int(ECFG["sendlimit"]) > 0: logme( MODUL, "Send Limit is set to : " + str(ECFG["sendlimit"]) + ". Adapting to limit!", ("P1"), ECFG) I = 0 x = 0 y = 1 esm = ewsauth(ECFG["username"], ECFG["token"]) jesm = "" # dict to gather session information cowriesessions = {} sessionstosend = [] while True: x, y = viewcounter(MODUL, x, y) I += 1 if int(ECFG["sendlimit"]) > 0 and I > int(ECFG["sendlimit"]): break line = getline(HONEYPOT["logfile"], (imin + I)).rstrip() currentline = imin + I if len(line) == 0: break else: # parse json try: content = json.loads(line) except ValueError, e: logme( MODUL, "Invalid json entry found in line " + str(I) + ", skipping entry.", ("P3"), ECFG) countme(MODUL, 'fileline', -2, ECFG) countme(MODUL, 'daycounter', -2, ECFG) pass # invalid json else: # if new session is started, store session-related info if (content['eventid'] == "cowrie.session.connect"): # create empty session content: structure will be the same as kippo # | id | username | password | success | logintimestamp | session | sessionstarttime| sessionendtime | ip | cowrieip | version| src_port|dst_port cowriesessions[content["session"]] = [ I, '', '', '', '', content["session"], content["timestamp"], '', content["src_ip"], content["sensor"], '', content["src_port"], content["dst_port"] ] # store correponding ssh client version if (content['eventid'] == "cowrie.client.version"): if content["session"] in cowriesessions: cowriesessions[ content["session"]][10] = content["version"] # create successful login if (content['eventid'] == "cowrie.login.success"): if content["session"] in cowriesessions: cowriesessions[content["session"]][0] = currentline cowriesessions[content["session"]][3] = "Success" cowriesessions[ content["session"]][1] = content["username"] cowriesessions[ content["session"]][2] = content["password"] cowriesessions[ content["session"]][4] = content["timestamp"] sessionstosend.append( deepcopy(cowriesessions[content["session"]])) # create failed login elif (content['eventid'] == "cowrie.login.failed"): if content["session"] in cowriesessions: cowriesessions[content["session"]][0] = currentline cowriesessions[content["session"]][3] = "Fail" cowriesessions[ content["session"]][1] = content["username"] cowriesessions[ content["session"]][2] = content["password"] cowriesessions[ content["session"]][4] = content["timestamp"] sessionstosend.append( deepcopy(cowriesessions[content["session"]])) # store session close if (content['eventid'] == "cowrie.session.closed"): for n, i in enumerate(sessionstosend): if (i[5] == content["session"]): i[7] = content["timestamp"]
def ecfg(name, version): MODUL = "EINIT" ECFG = {} parser = argparse.ArgumentParser() parser.add_argument("-c", "--configpath", help="Load configuration file from Path") parser.add_argument("-v", "--verbose", help="set output verbosity", action="store_true") parser.add_argument("-d", "--debug", help="set output debug", action="store_true") parser.add_argument( "-l", "--loop", help="Go in endless loop. Set {xx} for seconds to wait for next loop", type=int, default=0, action="store") parser.add_argument("-m", "--modul", help="only send alerts for this modul", choices=[ 'glastopfv3', 'glastopfv2', 'kippo', 'dionaea', 'honeytrap', 'rdpdetect', 'emobility', 'conpot', 'cowrie', 'elasticpot', 'suricata', 'rdpy', 'mailoney', 'vnclowpot', 'heralding', 'ciscoasa', 'tanner', 'glutton' ], action="store") parser.add_argument("-s", "--silent", help="silent mode without output", action="store_true") parser.add_argument("-i", "--ignorecert", help="ignore certificate warnings", action="store_true") parser.add_argument("-S", "--sendonly", help="only send unsend alerts", action="store_true") parser.add_argument("-E", "--ewsonly", help="only generate ews alerts files", action="store_true") parser.add_argument("-dcr", "--daycounter", help="reset and log daycounters for all honeypots", action="store_true") parser.add_argument("-j", "--jsonpath", help="Write JSON output file to path") parser.add_argument( "-L", "--sendlimit", help="Set {xxx} for max alerts will send in one session", type=int, action="store") parser.add_argument("-V", "--version", help="show the EWS Poster Version", action="version", version=name + " " + version) args = parser.parse_args() if args.sendlimit: ECFG["sendlimit2"] = args.sendlimit else: ECFG["sendlimit2"] = "" if args.loop: ECFG["a.loop"] = args.loop else: ECFG["a.loop"] = 0 if args.verbose: ECFG["a.verbose"] = True else: ECFG["a.verbose"] = False if args.debug: ECFG["a.debug"] = True else: ECFG["a.debug"] = False if args.ignorecert: ECFG["a.ignorecert"] = True else: ECFG["a.ignorecert"] = False if args.silent: ECFG["a.silent"] = True else: ECFG["a.silent"] = False if args.daycounter: ECFG["a.daycounter"] = True else: ECFG["a.daycounter"] = False if args.sendonly: ECFG["a.sendonly"] = True else: ECFG["a.sendonly"] = False if args.ewsonly: ECFG["a.ewsonly"] = True else: ECFG["a.ewsonly"] = False if args.configpath: ECFG["path2"] = args.configpath if os.path.isdir(args.configpath) is not True: logme(MODUL, "ConfigPath %s did not exist. Abort !" % (args.configpath), ("P1", "EXIT"), ECFG) else: ECFG["path2"] = "" if args.modul and args.modul in [ 'glastopfv3', 'glastopfv2', 'kippo', 'dionaea', 'honeytrap', 'rdpdetect', 'emobility', 'conpot', 'cowrie', 'elasticpot', 'suricata', 'rdpy', 'mailoney', 'vnclowpot', 'heralding', 'ciscoasa', 'tanner', 'glutton' ]: ECFG["a.modul"] = args.modul else: ECFG["a.modul"] = "" if args.jsonpath: ECFG["a.jsondir"] = args.jsonpath if os.path.isdir(args.jsonpath) is not True: logme(MODUL, "JsonPath %s did not exist. Abort !" % (args.jsonpath), ("P1", "EXIT"), ECFG) else: ECFG["a.jsondir"] = "" # say hello logme( MODUL, name + " " + version + " (c) by Markus Schroer <*****@*****.**>\n", ("P0"), ECFG) # read EWSPoster Main Path ECFG["path"] = os.path.dirname(os.path.abspath(__file__)).replace( "/moduls", "") if ECFG["path2"] == "": ECFG["path2"] = ECFG["path"] if os.path.isfile(ECFG["path2"] + os.sep + "ews.cfg") is False: logme( MODUL, "Missing EWS Config %s. Abort !" % (ECFG["path2"] + os.sep + "ews.cfg"), ("P1", "EXIT"), ECFG) else: ECFG["cfgfile"] = ECFG["path2"] + os.sep + "ews.cfg" # Create IDX File if not exist if os.path.isfile(ECFG["path"] + os.sep + "ews.idx") is False: os.open(ECFG["path"] + os.sep + "ews.idx", os.O_RDWR | os.O_CREAT) logme(MODUL, "Create ews.idx counterfile", ("P1"), ECFG) # Read Main Config Parameter ITEMS = ("homedir", "spooldir", "logdir", "contact", "del_malware_after_send", "send_malware", "sendlimit") MCFG = readcfg("MAIN", ITEMS, ECFG["cfgfile"]) # IP Handling # try to determine the external IP MCFG["ip"] = getOwnExternalIP(ECFG) if not MCFG["ip"]: logme( MODUL, "External IP address cannot be determined. Set external IP in ews.cfg, ews.ip or env variable MY_EXTIP or allow external api request.. Abort !", ("P1", "EXIT"), ECFG) logme(MODUL, "Using external IP address " + str(MCFG["ip"]), ("P1", "Log"), ECFG) # sendlimit expect if ECFG["sendlimit2"] != "": MCFG["sendlimit"] = ECFG["sendlimit2"] if int(MCFG["sendlimit"]) > 500: logme( MODUL, "Error Sendlimit " + str(MCFG["sendlimit"]) + " to high. Max 500 ! ", ("P1", "EXIT"), ECFG) elif int(MCFG["sendlimit"]) < 1: logme( MODUL, "Error Sendlimit " + str(MCFG["sendlimit"]) + " to low. Min 1 ! ", ("P1", "EXIT"), ECFG) elif MCFG["sendlimit"] == "NULL" or str(MCFG["sendlimit"]) == "UNKNOW": logme( MODUL, "Error Sendlimit " + str(MCFG["sendlimit"]) + " Must set between 1 and 500. ", ("P1", "EXIT"), ECFG) # send_malware ? if MCFG["send_malware"].lower() == "true": MCFG["send_malware"] = True else: MCFG["send_malware"] = False # del_malware_after_send ? if MCFG["del_malware_after_send"].lower() == "true": MCFG["del_malware_after_send"] = True else: MCFG["del_malware_after_send"] = False # home dir available ? if os.path.isdir(MCFG["homedir"]) is not True: logme(MODUL, "Error missing homedir " + MCFG["homedir"] + " Abort !", ("P1", "EXIT"), ECFG) else: os.chdir(MCFG["homedir"]) # spool dir available ? if os.path.isdir(MCFG["spooldir"]) is not True: logme(MODUL, "Error missing spooldir " + MCFG["spooldir"] + " Abort !", ("P1", "EXIT"), ECFG) # log dir available ? MCFG["logdir"] = readonecfg("MAIN", "logdir", ECFG["cfgfile"]) if MCFG["logdir"] != "NULL" and MCFG[ "logdir"] != "FALSE" and os.path.isdir(MCFG["logdir"]) is True: MCFG["logfile"] = MCFG["logdir"] + os.sep + "ews.log" elif MCFG["logdir"] != "NULL" and MCFG[ "logdir"] != "FALSE" and os.path.isdir(MCFG["logdir"]) is True: logme(MODUL, "Error missing logdir " + MCFG["logdir"] + " Abort !", ("P1", "EXIT"), ECFG) else: MCFG["logfile"] = "/var/log" + os.sep + "ews.log" # Proxy Settings ? MCFG["proxy"] = readonecfg(MODUL, "proxy", ECFG["cfgfile"]) # Read EWS Config Parameter ITEMS = ("ews", "username", "token", "rhost_first", "rhost_second") EWSCFG = readcfg("EWS", ITEMS, ECFG["cfgfile"]) # Set ews real true or false if EWSCFG["ews"].lower() == "true": EWSCFG["ews"] = True else: EWSCFG["ews"] = False # ignore cert validation if ignorecert-parameter is set EWSCFGCERT = readonecfg("EWS", "ignorecert", ECFG["cfgfile"]) if EWSCFGCERT.lower() == "true": ECFG["a.ignorecert"] = True # Read HPFEED Config Parameter ITEMS = ("hpfeed", "host", "port", "channels", "ident", "secret") HCFG = readcfg("HPFEED", ITEMS, ECFG["cfgfile"]) if HCFG["hpfeed"].lower() == "true": HCFG["hpfeed"] = True else: HCFG["hpfeed"] = False # Read EWSJSON Config Parameter ITEMS = ("json", "jsondir") EWSJSON = readcfg("EWSJSON", ITEMS, ECFG["cfgfile"]) if EWSJSON["json"].lower() == "true": EWSJSON["json"] = True if os.path.isdir(EWSJSON["jsondir"]) is True: EWSJSON["jsondir"] = EWSJSON["jsondir"] + os.sep + "ews.json" else: logme(MODUL, "Error missing jsondir " + EWSJSON["jsondir"] + " Abort !", ("P1", "EXIT"), ECFG) else: EWSJSON["json"] = False if ECFG["a.jsondir"] != "" and os.path.isdir(ECFG["a.jsondir"]) is True: EWSJSON["json"] = True EWSJSON["jsondir"] = ECFG["a.jsondir"] + os.sep + "ews.json" ECFG.update(MCFG) ECFG.update(EWSCFG) ECFG.update(HCFG) ECFG.update(EWSJSON) return ECFG
def dionaea(): MODUL = "DIONAEA" logme(MODUL, "Starting Dionaea Modul.", ("P1"), ECFG) # collect honeypot config dic ITEMS = ("dionaea", "nodeid", "sqlitedb", "malwaredir") HONEYPOT = readcfg(MODUL, ITEMS, ECFG["cfgfile"]) # Malwaredir exist ? if os.path.isdir(HONEYPOT["malwaredir"]) is False: logme( MODUL, "[ERROR] Missing Malware Dir " + HONEYPOT["malwaredir"] + ". Abort !", ("P3", "LOG"), ECFG) # is sqlitedb exist ? if os.path.isfile(HONEYPOT["sqlitedb"]) is False: logme( MODUL, "[ERROR] Missing sqlitedb file " + HONEYPOT["sqlitedb"] + ". Abort !", ("P3", "LOG"), ECFG) return # open database con = sqlite3.connect(HONEYPOT["sqlitedb"], 30) con.row_factory = sqlite3.Row c = con.cursor() # calculate send limit c.execute("SELECT max(connection) from connections;") maxid = c.fetchone()["max(connection)"] if maxid is None: logme(MODUL, "[INFO] No entry's in Dionaea Database. Skip !", ("P2", "LOG"), ECFG) return imin, imax = calcminmax(MODUL, int(countme(MODUL, 'sqliteid', -1, ECFG)), int(maxid), ECFG) # read alerts from database c.execute( "SELECT * from connections where connection > ? and connection <= ?;", ( imin, imax, )) rows = c.fetchall() # counter inits x = 0 y = 1 esm = ewsauth(ECFG["username"], ECFG["token"]) jesm = "" for row in rows: x, y = viewcounter(MODUL, x, y) # filter empty remote_host if row["remote_host"] == "": countme(MODUL, 'sqliteid', row["connection"], ECFG) continue # Prepair and collect Alert Data DATA = { "aid": HONEYPOT["nodeid"], "timestamp": datetime.fromtimestamp(int( row["connection_timestamp"])).strftime('%Y-%m-%d %H:%M:%S'), "sadr": str(row["remote_host"]), "sipv": "ipv" + ip4or6(str(row["remote_host"])), "sprot": str(row["connection_type"]), "sport": str(row["remote_port"]), "tipv": "ipv" + ip4or6(str(row["local_host"])), "tadr": str(row["local_host"]), "tprot": str(row["connection_type"]), "tport": str(row["local_port"]), } REQUEST = { "description": "Network Honeyport Dionaea v0.1.0", } # Check for malware bin's c.execute( "SELECT download_md5_hash from downloads where connection = ?;", (str(row["connection"]), )) check = c.fetchone() if check is not None: error, malwarefile = malware(HONEYPOT["malwaredir"], check[0], ECFG["del_malware_after_send"]) if error == 0: REQUEST["binary"] = malwarefile else: logme(MODUL, "Mission Malwarefile %s" % check[0], ("P1", "LOG"), ECFG) # Collect additional Data ADATA = { "sqliteid": str(row["connection"]), } # generate template and send esm = buildews(esm, DATA, REQUEST, ADATA) jesm = buildjson(jesm, DATA, REQUEST, ADATA) countme(MODUL, 'sqliteid', row["connection"], ECFG) countme(MODUL, 'daycounter', -2, ECFG) if ECFG["a.verbose"] is True: verbosemode(MODUL, DATA, REQUEST, ADATA) con.close() if int(esm.xpath('count(//Alert)')) > 0: sendews(esm) writejson(jesm) if y > 1: logme(MODUL, "%s EWS alert records send ..." % (x + y - 1), ("P2"), ECFG) return
def emobility(): MODUL = "EMOBILITY" logme(MODUL,"Starting eMobility Modul.",("P1"),ECFG) # collect honeypot config dic ITEMS = ("eMobility","nodeid","logfile") HONEYPOT = readcfg(MODUL,ITEMS,ECFG["cfgfile"]) # logfile file exists ? if os.path.isfile(HONEYPOT["logfile"]) is False: logme(MODUL,"[ERROR] Missing LogFile " + HONEYPOT["logfile"] + ". Skip !",("P3","LOG"),ECFG) # count limit imin = int(countme(MODUL,'fileline',-1,ECFG)) if int(ECFG["sendlimit"]) > 0: logme(MODUL,"Send Limit is set to : " + str(ECFG["sendlimit"]) + ". Adapting to limit!",("P1"),ECFG) I = 0 ; x = 0 ; y = 1 esm = ewsauth(ECFG["username"],ECFG["token"]) jesm = "" while True: x,y = viewcounter(MODUL,x,y) I += 1 if int(ECFG["sendlimit"]) > 0 and I > int(ECFG["sendlimit"]): break line = getline(HONEYPOT["logfile"],(imin + I)).rstrip() if len(line) == 0: break else: # Prepair and collect Alert Data line = re.sub(r' ',r' ',re.sub(r'[\[\]\-\>]',r'',line)) srcipandport, dstipandport, url, dateandtime = line.split("|",3) DATA = { "aid" : HONEYPOT["nodeid"], "timestamp" : "%s-%s-%s %s" % (dateandtime[0:4], dateandtime[4:6], dateandtime[6:8], dateandtime[9:17]), "sadr" : "%s.%s.%s.%s" % (srcipandport.split(".")[0], srcipandport.split(".")[1], srcipandport.split(".")[2], srcipandport.split(".")[3]), "sipv" : "ipv4", "sprot" : "tcp", "sport" : srcipandport.split(".")[4], "tipv" : "ipv4", "tadr" : "%s.%s.%s.%s" % (dstipandport.split(".")[0], dstipandport.split(".")[1], dstipandport.split(".")[2], dstipandport.split(".")[3]), "tprot" : "tcp", "tport" : dstipandport.split(".")[4], } REQUEST = { "description" : "eMobility Honeypot", "url" : urllib.quote(url.encode('ascii', 'ignore')) } # Collect additional Data ADATA = { } # generate template and send esm = buildews(esm,DATA,REQUEST,ADATA) jesm = buildjson(jesm,DATA,REQUEST,ADATA) countme(MODUL,'fileline',-2,ECFG) countme(MODUL,'daycounter', -2,ECFG) if ECFG["a.verbose"] is True: verbosemode(MODUL,DATA,REQUEST,ADATA) # Cleaning linecache clearcache() if int(esm.xpath('count(//Alert)')) > 0: sendews(esm) writejson(jesm) if y > 1: logme(MODUL,"%s EWS alert records send ..." % (x+y-2),("P2"),ECFG) return