def daycounterreset(lock,ECFG): if lock == False: logme("ARGCHK","Lock Socket is busy ...",("P1"),ECFG) logme("ARGCHK","Waiting 300 seconds for getting lock socket.",("P1"),ECFG) for i in range(6000): if locksocket() == False: time.sleep(0.1) else: break if locksocket() == False: logme("daycounterreset","Daycounterreset fails. Socket over 300 sec busy",("P1","LOG"),ECFG) sys.exit(0) z = ConfigParser.RawConfigParser() z.read(ECFG["homedir"] + os.sep + "ews.idx") for i in z.sections(): if z.has_option(i,"daycounter") == True: logme("daycounterreset","Daycounter " + i + " : " + z.get(i,"daycounter") + " alerts send." ,("LOG"),ECFG) z.set(i,"daycounter",0) with open(ECFG["homedir"] + os.sep + "ews.idx", 'wb') as countfile: z.write(countfile) countfile.close logme("daycounterreset","Daycounters successfull reset.",("P1"),ECFG) sys.exit(0)
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 daycounterreset(lock, ECFG): if lock == False: logme("ARGCHK", "Lock Socket is busy ...", ("P1"), ECFG) logme("ARGCHK", "Waiting 300 seconds for getting lock socket.", ("P1"), ECFG) for i in range(6000): if locksocket() == False: time.sleep(0.1) else: break if locksocket() == False: logme("daycounterreset", "Daycounterreset fails. Socket over 300 sec busy", ("P1", "LOG"), ECFG) sys.exit(0) z = ConfigParser.RawConfigParser() z.read(ECFG["homedir"] + os.sep + "ews.idx") for i in z.sections(): if z.has_option(i, "daycounter") == True: logme( "daycounterreset", "Daycounter " + i + " : " + z.get(i, "daycounter") + " alerts send.", ("LOG"), ECFG) z.set(i, "daycounter", 0) with open(ECFG["homedir"] + os.sep + "ews.idx", 'wb') as countfile: z.write(countfile) countfile.close logme("daycounterreset", "Daycounters successfull reset.", ("P1"), ECFG) sys.exit(0)
def mysqldb(): try: con = MySQLdb.connect(host=HONEYPOT["mysqlhost"], user=HONEYPOT["mysqluser"], passwd=HONEYPOT["mysqlpw"], db=HONEYPOT["mysqldb"], cursorclass=MySQLdb.cursors.DictCursor) except MySQLdb.Error as e: logme(MODUL, "[ERROR] %s" % (str(e)), ("P3", "LOG"), ECFG) return c = con.cursor() # calculate send limit c.execute("SELECT max(id) from log") 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)), int(maxid), ECFG) # read alerts from database c.execute("SELECT * from log where id > %s and id <= %s;", (imin, imax)) rows = c.fetchall()
def filelist(DIR): if os.path.isdir(DIR) is not True: logme(MODUL, "Error missing dir " + DIR + " Abort !", ("P1", "EXIT"), ECFG) else: return os.listdir(DIR)
def calcminmax(MODUL,imin,imax,ECFG): if (imax - imin) > int(ECFG["sendlimit"]): logme(MODUL,"Need to send : " + str(imax -imin) + " limit is : " + str(ECFG["sendlimit"]) + ". Adapting to limit!",("P1"),ECFG) imax = imin + int(ECFG["sendlimit"]) return imin,imax
def del_job(DIR,MODUL): FILEIN = filelist(DIR) for files in FILEIN: fpart = files.split('.') if len(fpart) == 3 and int(fpart[1]) > 4: logme(MODUL, "Cleaning spooler dir: %s delete file: %s reached max transmit counter !" % (DIR, files),("LOG"),ECFG) os.remove(DIR + os.sep + files)
def clean_dir(DIR,MODUL): FILEIN = filelist(DIR) for files in FILEIN: if not ".ews" in files: os.remove(DIR + os.sep + files) logme(MODUL, "Cleaning spooler dir: %s delete file: %s" % (DIR, files),("LOG"),ECFG) return()
def hpfeedsend(esm): try: hpc = hpfeeds.new(ECFG["host"],int(ECFG["port"]),ECFG["ident"],ECFG["secret"]) logme("hpfeedsend","Connect to (%s)" % format(hpc.brokername) ,("P3","VERBOSE"),ECFG) except hpfeeds.FeedException, e: logme("hpfeedsend","HPFeeds Error (%s)" % format(e) ,("LOG","VERBOSE"),ECFG) return False
def check_job(DIR,MODUL): FILEIN = filelist(DIR) if len(FILEIN) < 1: logme(MODUL, "Sender : No Jobs to send in %s" % (DIR),("P1"),ECFG) return False else: logme(MODUL, "Sender : There are %s jobs to send in %s" %(str(len(FILEIN)),DIR),("P1"),ECFG) return True
def calcminmax(MODUL, imin, imax, ECFG): if (imax - imin) > int(ECFG["sendlimit"]): logme( MODUL, "Need to send : " + str(imax - imin) + " limit is : " + str(ECFG["sendlimit"]) + ". Adapting to limit!", ("P1"), ECFG) imax = imin + int(ECFG["sendlimit"]) return imin, imax
def viewcounter(MODUL, x, y): if y == 100: x += 100 # Inform every 100 send records logme(MODUL, str(x) + " EWS alert records sent ...", ("P2"), ECFG) y = 1 else: y += 1 return x, y
def viewcounter(MODUL,x,y): if y == 100: x += 100 # Inform every 100 send records logme(MODUL,str(x) +" EWS alert records sent ...",("P2"),ECFG) y = 1 else: y += 1 return x,y
def clean_dir(DIR, MODUL): FILEIN = filelist(DIR) for files in FILEIN: if not ".ews" in files: os.remove(DIR + os.sep + files) logme( MODUL, "Cleaning spooler dir: %s delete file: %s" % (DIR, files), ("LOG"), ECFG) return ()
def del_job(DIR, MODUL): FILEIN = filelist(DIR) for files in FILEIN: fpart = files.split('.') if len(fpart) == 3 and int(fpart[1]) > 4: logme( MODUL, "Cleaning spooler dir: %s delete file: %s reached max transmit counter !" % (DIR, files), ("LOG"), ECFG) os.remove(DIR + os.sep + files)
def mysqldb(): 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) return
def hpfeedsend(esm): try: hpc = hpfeeds.new(ECFG["host"], int(ECFG["port"]), ECFG["ident"], ECFG["secret"]) logme("hpfeedsend", "Connect to (%s)" % format(hpc.brokername), ("P3", "VERBOSE"), ECFG) except hpfeeds.FeedException, e: logme("hpfeedsend", "HPFeeds Error (%s)" % format(e), ("LOG", "VERBOSE"), ECFG) return False
def check_job(DIR, MODUL): FILEIN = filelist(DIR) if len(FILEIN) < 1: logme(MODUL, "Sender : No Jobs to send in %s" % (DIR), ("P1"), ECFG) return False else: logme( MODUL, "Sender : There are %s jobs to send in %s" % (str(len(FILEIN)), DIR), ("P1"), ECFG) return True
def mysqldb(): 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) return
def sqlitedb(MODUL, DBPATH, ECFG): rows = [] # is sqlitedb exist ? if os.path.isfile(DBPATH) == False: logme(MODUL, "[ERROR] Missing sqlitedb file " + DBPATH + ". Abort !", ("P3", "LOG"), ECFG) return 1, rows # open database try: con = sqlite3.connect(DBPATH, 30) con.row_factory = sqlite3.Row cur = con.cursor() except sqlite.Error, e: logme(MODUL, "[ERROR] Sqlite Error : %s . Abort !" % e.args[0], ("P3", "LOG"), ECFG) return 1, rows
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 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
cur = con.cursor() except sqlite.Error, e: logme(MODUL, "[ERROR] Sqlite Error : %s . Abort !" % e.args[0], ("P3", "LOG"), ECFG) return 1, rows # calculate max alerts if MODUL == "GLASTOPFV3": cur.execute("SELECT max(id) from events") maxid = cur.fetchone()["max(id)"] elif MODUL == "DIONAEA": cur.execute("SELECT max(connection) from connections;") maxid = cur.fetchone()["max(connection)"] else: logme(MODUL, "[ERROR] Unknow Modul for Sqlite Database Access. Abort!", ("P2", "LOG"), ECFG) return 1, rows if maxid is None: logme(MODUL, "[ERROR] No entry's in Database %s. Abort!" % DBPATH, ("P2", "LOG"), ECFG) return 1, rows imin, imax = calcminmax(MODUL, int(countme(MODUL, "sqliteid", -1, ECFG)), int(maxid), ECFG) # read alerts from database if MODUL == "GLASTOPFV3": cur.execute("SELECT * from events where id > ? and id <= ?;", (imin, imax)) elif MODUL == "DIONAEA": cur.execute("SELECT * from connections where connection > ? and connection <= ?;", (imin, imax)) else:
def ewswebservice(ems): MODUL = "ewswebservice" headers = { 'User-Agent' : name + " " + version, 'Content-type' : 'text/xml', 'SOAPAction' : '', 'charset' : 'UTF-8', 'Connection' : 'close' } host = random.choice([ ECFG["rhost_first"] , ECFG["rhost_second"] ]) if ECFG["proxy"] != "NULL" and ECFG["proxy"] != "FALSE": proxydic = { "https" : ECFG["proxy"] } else: proxydic = {} try: if not "https" in proxydic: webservice = requests.post(host, data=ems, headers=headers, allow_redirects=True, timeout=60, verify=True ) else: webservice = requests.post(host, data=ems, headers=headers, allow_redirects=True, proxies=proxydic, timeout=60, verify=True ) webservice.raise_for_status() xmlresult = re.search('<StatusCode>(.*)</StatusCode>', webservice.text).groups()[0] if xmlresult != "OK": logme(MODUL,"XML Result != ok ( %s) (%s)" % (xmlresult,webservice.text) ,("LOG","VERBOSE"),ECFG) return False if ECFG["a.verbose"] is True: logme(MODUL,"---- Webservice Report ----" ,("VERBOSE"),ECFG) logme(MODUL,"HOST : %s" % (host) ,("VERBOSE"),ECFG) logme(MODUL,"XML Result : %s" % (xmlresult) ,("VERBOSE"),ECFG) logme(MODUL,"Statuscode : %s" % (webservice.status_code) ,("VERBOSE"),ECFG) logme(MODUL,"Header : %s" % (webservice.headers) ,("VERBOSE"),ECFG) logme(MODUL,"Body : %s" % (webservice.text) ,("VERBOSE"),ECFG) logme(MODUL,"",("VERBOSE"),ECFG) return True except requests.exceptions.Timeout, e: logme(MODUL,"Timeout to remote host %s (%s)" % (host , str(e)) ,("LOG","VERBOSE"),ECFG) return False
logme(MODUL,"---- Webservice Report ----" ,("VERBOSE"),ECFG) logme(MODUL,"HOST : %s" % (host) ,("VERBOSE"),ECFG) logme(MODUL,"XML Result : %s" % (xmlresult) ,("VERBOSE"),ECFG) logme(MODUL,"Statuscode : %s" % (webservice.status_code) ,("VERBOSE"),ECFG) logme(MODUL,"Header : %s" % (webservice.headers) ,("VERBOSE"),ECFG) logme(MODUL,"Body : %s" % (webservice.text) ,("VERBOSE"),ECFG) logme(MODUL,"",("VERBOSE"),ECFG) return True except requests.exceptions.Timeout, e: logme(MODUL,"Timeout to remote host %s (%s)" % (host , str(e)) ,("LOG","VERBOSE"),ECFG) return False except requests.exceptions.ConnectionError, e: logme(MODUL,"Remote host %s didn't answers ! (%s)" % (host , str(e)) ,("LOG","VERBOSE"),ECFG) return False except requests.exceptions.HTTPError, e: logme(MODUL,"HTTP Errorcode != 200 (%s)" % (str(e)) ,("LOG","VERBOSE"),ECFG) return False def viewcounter(MODUL,x,y): if y == 100: x += 100 # Inform every 100 send records logme(MODUL,str(x) +" EWS alert records sent ...",("P2"),ECFG) y = 1 else: y += 1
def verbosemode(MODUL, DATA, REQUEST, ADATA): logme(MODUL, "---- " + MODUL + " ----", ("VERBOSE"), ECFG) logme(MODUL, "Nodeid : %s" % DATA["aid"], ("VERBOSE"), ECFG) logme(MODUL, "Timestamp : %s" % DATA["timestamp"], ("VERBOSE"), ECFG) logme(MODUL, "", ("VERBOSE"), ECFG) logme(MODUL, "Source IP : %s" % DATA["sadr"], ("VERBOSE"), ECFG) logme(MODUL, "Source IPv : %s" % DATA["sipv"], ("VERBOSE"), ECFG) logme(MODUL, "Source Port : %s" % DATA["sport"], ("VERBOSE"), ECFG) logme(MODUL, "Source Protocol : %s" % DATA["sprot"], ("VERBOSE"), ECFG) logme(MODUL, "Target IP : %s" % DATA["tadr"], ("VERBOSE"), ECFG) logme(MODUL, "Target IPv : %s" % DATA["tipv"], ("VERBOSE"), ECFG) logme(MODUL, "Target Port : %s" % DATA["tport"], ("VERBOSE"), ECFG) logme(MODUL, "Target Protocol : %s" % DATA["tprot"], ("VERBOSE"), ECFG) for key, value in ADATA.items(): logme(MODUL, "%s : %s" % (key, value), ("VERBOSE"), ECFG) logme(MODUL, "", ("VERBOSE"), ECFG) return
def ewswebservice(ems): MODUL = "ewswebservice" headers = { 'User-Agent': name + " " + version, 'Content-type': 'text/xml', 'SOAPAction': '', 'charset': 'UTF-8', 'Connection': 'close' } host = random.choice([ECFG["rhost_first"], ECFG["rhost_second"]]) if ECFG["proxy"] != "NULL" and ECFG["proxy"] != "FALSE": proxydic = {"https": ECFG["proxy"]} else: proxydic = {} try: if not "https" in proxydic: webservice = requests.post(host, data=ems, headers=headers, allow_redirects=True, timeout=60, verify=not ECFG["a.ignorecert"]) else: webservice = requests.post(host, data=ems, headers=headers, allow_redirects=True, proxies=proxydic, timeout=60, verify=not ECFG["a.ignorecert"]) webservice.raise_for_status() xmlresult = re.search('<StatusCode>(.*)</StatusCode>', webservice.text).groups()[0] if xmlresult != "OK": logme(MODUL, "XML Result != ok ( %s) (%s)" % (xmlresult, webservice.text), ("LOG", "VERBOSE"), ECFG) return False if ECFG["a.verbose"] is True: logme(MODUL, "---- Webservice Report ----", ("VERBOSE"), ECFG) logme(MODUL, "HOST : %s" % (host), ("VERBOSE"), ECFG) logme(MODUL, "XML Result : %s" % (xmlresult), ("VERBOSE"), ECFG) logme(MODUL, "Statuscode : %s" % (webservice.status_code), ("VERBOSE"), ECFG) logme(MODUL, "Header : %s" % (webservice.headers), ("VERBOSE"), ECFG) logme(MODUL, "Body : %s" % (webservice.text), ("VERBOSE"), ECFG) logme(MODUL, "", ("VERBOSE"), ECFG) return True except requests.exceptions.Timeout, e: logme(MODUL, "Timeout to remote host %s (%s)" % (host, str(e)), ("LOG", "VERBOSE"), ECFG) return False
def verbosemode(MODUL,DATA,REQUEST,ADATA): logme(MODUL,"---- " + MODUL + " ----" ,("VERBOSE"),ECFG) logme(MODUL,"Nodeid : %s" % DATA["aid"],("VERBOSE"),ECFG) logme(MODUL,"Timestamp : %s" % DATA["timestamp"],("VERBOSE"),ECFG) logme(MODUL,"" ,("VERBOSE"),ECFG) logme(MODUL,"Source IP : %s" % DATA["sadr"],("VERBOSE"),ECFG) logme(MODUL,"Source IPv : %s" % DATA["sipv"],("VERBOSE"),ECFG) logme(MODUL,"Source Port : %s" % DATA["sport"],("VERBOSE"),ECFG) logme(MODUL,"Source Protocol : %s" % DATA["sprot"],("VERBOSE"),ECFG) logme(MODUL,"Target IP : %s" % DATA["tadr"],("VERBOSE"),ECFG) logme(MODUL,"Target IPv : %s" % DATA["tipv"],("VERBOSE"),ECFG) logme(MODUL,"Target Port : %s" % DATA["tport"],("VERBOSE"),ECFG) logme(MODUL,"Target Protocol : %s" % DATA["tprot"],("VERBOSE"),ECFG) for key,value in ADATA.items(): logme(MODUL,"%s : %s" %(key,value) ,("VERBOSE"),ECFG) logme(MODUL,"" ,("VERBOSE"),ECFG) return
except sqlite.Error, e: logme(MODUL, "[ERROR] Sqlite Error : %s . Abort !" % e.args[0], ("P3", "LOG"), ECFG) return 1, rows # calculate max alerts if MODUL == "GLASTOPFV3": cur.execute("SELECT max(id) from events") maxid = cur.fetchone()["max(id)"] elif MODUL == "DIONAEA": cur.execute("SELECT max(connection) from connections;") maxid = cur.fetchone()["max(connection)"] else: logme(MODUL, "[ERROR] Unknow Modul for Sqlite Database Access. Abort!", ("P2", "LOG"), ECFG) return 1, rows if maxid is None: logme(MODUL, "[ERROR] No entry's in Database %s. Abort!" % DBPATH, ("P2", "LOG"), ECFG) return 1, rows imin, imax = calcminmax(MODUL, int(countme(MODUL, 'sqliteid', -1, ECFG)), int(maxid), ECFG) # read alerts from database if MODUL == "GLASTOPFV3": cur.execute("SELECT * from events where id > ? and id <= ?;", ( imin,
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 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 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 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)
("VERBOSE"), ECFG) logme(MODUL, "Header : %s" % (webservice.headers), ("VERBOSE"), ECFG) logme(MODUL, "Body : %s" % (webservice.text), ("VERBOSE"), ECFG) logme(MODUL, "", ("VERBOSE"), ECFG) return True except requests.exceptions.Timeout, e: logme(MODUL, "Timeout to remote host %s (%s)" % (host, str(e)), ("LOG", "VERBOSE"), ECFG) return False except requests.exceptions.ConnectionError, e: logme(MODUL, "Remote host %s didn't answers ! (%s)" % (host, str(e)), ("LOG", "VERBOSE"), ECFG) return False except requests.exceptions.HTTPError, e: logme(MODUL, "HTTP Errorcode != 200 (%s)" % (str(e)), ("LOG", "VERBOSE"), ECFG) return False except OpenSSL.SSL.WantWriteError, e: logme(MODUL, "OpenSSL Write Buffer too small", ("LOG", "VERBOSE"), ECFG) return False def viewcounter(MODUL, x, y):
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 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 getOwnExternalIP(ECFG): # try from env variable try: if os.environ.get('MY_EXTIP') is not None: if ipaddress.ip_address(str(os.environ.get('MY_EXTIP'))).is_global: return os.environ.get('MY_EXTIP') else: logme( "Main", "[ERROR] Environment variable MY_EXTIP is not a public IP", ("P1", "Log"), ECFG) pass else: logme("Main", "[INFO] Environment variable MY_EXTIP not set", ("P1", "Log"), ECFG) except: logme("Main", "[ERROR] Environment variable MY_EXTIP contains no IP address", ("P1", "Log"), ECFG) # try ews.ip file ewsip = ECFG["path2"] + os.sep + "ews.ip" if os.path.isfile(ewsip): pubipfile = readonecfg("MAIN", "ip", ewsip) if pubipfile.lower() == "null" or pubipfile.lower( ) == "false" or pubipfile.lower() == "unknown": logme( "Main", "[ERROR] ews.ip contained no ip section or empty value for ip. ", ("P1", "Log"), ECFG) pass else: try: if ipaddress.ip_address(str(pubipfile)).is_global: return pubipfile else: logme("Main", "[ERROR] IP address in ews.ip is not a public IP", ("P1", "Log"), ECFG) pass except: logme("Main", "[ERROR] ews.ip contains no IP address", ("P1", "Log"), ECFG) # try the IP from ews.cfg configip = readonecfg("MAIN", "ip", ECFG["cfgfile"]) try: if ipaddress.ip_address(str(configip)).is_global: return configip else: logme("Main", "[ERROR] IP address in ews.cfg is not a public IP", ("P1", "Log"), ECFG) pass except: logme("Main", "[ERROR]] ews.cfg contains no IP address", ("P1", "Log"), ECFG) # try from public service try: extip = get('https://api.ipify.org', timeout=5).text if ipaddress.ip_address(str(extip)).is_global: return extip else: logme( "Main", "[ERROR] IP address returned from external service is not a public IP, this should never happen...", ("P1", "Log"), ECFG) pass except: logme( "Main", "[ERROR] Could not determine a valid public IP using external service", ("P1", "Log"), ECFG) return False
def filelist(DIR): if os.path.isdir(DIR) is not True: logme(MODUL,"Error missing dir " + DIR + " Abort !",("P1","EXIT"),ECFG) else: return os.listdir(DIR)
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 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 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 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 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 sqlitedb(MODUL, DBPATH, ECFG): rows = [] # is sqlitedb exist ? if os.path.isfile(DBPATH) == False: logme(MODUL, "[ERROR] Missing sqlitedb file " + DBPATH + ". Abort !", ("P3", "LOG"), ECFG) return 1, rows # open database try: con = sqlite3.connect(DBPATH, 30) con.row_factory = sqlite3.Row cur = con.cursor() except sqlite.Error as e: logme(MODUL, "[ERROR] Sqlite Error : %s . Abort !" % e.args[0], ("P3", "LOG"), ECFG) return 1, rows # calculate max alerts if MODUL == "GLASTOPFV3": cur.execute("SELECT max(id) from events") maxid = cur.fetchone()["max(id)"] elif MODUL == "DIONAEA": cur.execute("SELECT max(connection) from connections;") maxid = cur.fetchone()["max(connection)"] else: logme(MODUL, "[ERROR] Unknow Modul for Sqlite Database Access. Abort!", ("P2", "LOG"), ECFG) return 1, rows if maxid is None: logme(MODUL, "[ERROR] No entry's in Database %s. Abort!" % DBPATH, ("P2", "LOG"), ECFG) return 1, rows imin, imax = calcminmax(MODUL, int(countme(MODUL, 'sqliteid', -1, ECFG)), int(maxid), ECFG) # read alerts from database if MODUL == "GLASTOPFV3": cur.execute("SELECT * from events where id > ? and id <= ?;", ( imin, imax, )) elif MODUL == "DIONAEA": cur.execute( "SELECT * from connections where connection > ? and connection <= ?;", ( imin, imax, )) else: logme(MODUL, "[ERROR] Unknow Modul for Sqlite Database Access. Abort!", ("P2", "LOG"), ECFG) return 1, rows rows = cur.fetchall() con.close() return 0, rows