diff --git a/OfflineReportGenerator.py b/OfflineReportGenerator.py new file mode 100644 index 0000000..7519b2f --- /dev/null +++ b/OfflineReportGenerator.py @@ -0,0 +1,427 @@ +#!/usr/bin/env python + + +import sqlite3, re, subprocess, time, cgi, os, sys +import pandas as pd + +# Configurable Setting +ReportsDirectory = "./" +# End + +if not os.path.exists(ReportsDirectory): + os.makedirs(ReportsDirectory) + +DB = "" + +try: + DB = sys.argv[1] +except IndexError: + DB = "" + +if len(DB) < 1: + print "Usage: python OfflineReportGenerator.py PowershellC2.SQLite" + exit() + +if not os.path.exists(DB): + print "%s Does not exist" % DB + exit() + +# Main program +def replace_tabs(s): + s = s.replace("\t", " ") + return s + + HostnameIP = "1.1.1.1" + ServerTAG = "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nPoshC2 Server\\n%s" % HostnameIP + GV = GV.replace("POSHSERVER",ServerTAG) + + implants = get_implants_all_db() + hosts = "" + daisyhosts = "" + + for i in implants: + if "Daisy" not in i[15]: + if i[3] not in hosts: + hostname = i[11].replace("\\","\\\\") + hosts += "\"%s\" -> \"%s \\n %s\\n\\n\\n\\n \"; \n" % (ServerTAG,hostname,i[3]) + + for i in implants: + if "Daisy" in i[15]: + hostname = i[11].replace("\\","\\\\") + if "\"%s\\n\\n\\n\\n \" -> \"%s \\n %s\\n\\n\\n\\n \"; \n" % (i[9].replace('\x00','').replace("\\","\\\\").replace('@',' \\n '),hostname,i[3]) not in daisyhosts: + daisyhosts += "\"%s\\n\\n\\n\\n \" -> \"%s \\n %s\\n\\n\\n\\n \"; \n" % (i[9].replace('\x00','').replace("\\","\\\\").replace('@',' \\n '),hostname,i[3]) + + GV = GV.replace("DAISYHOSTS",daisyhosts) + GV = GV.replace("IMPLANTHOSTS",hosts) + +def get_implants_all_db(): + conn = sqlite3.connect(DB) + conn.row_factory = sqlite3.Row + c = conn.cursor() + c.execute("SELECT * FROM Implants") + result = c.fetchall() + if result: + return result + else: + return None + +def get_htmlimplant( randomuri ): + conn = sqlite3.connect(DB) + conn.row_factory = sqlite3.Row + c = conn.cursor() + c.execute("SELECT * FROM Implants WHERE RandomURI=?",(randomuri,)) + result = c.fetchone() + if result: + return result + else: + return None + +def generate_table(table): + HTMLPre = """ + + + +
+__________ .__. _________ ________ +\_______ \____ _____| |__ \_ ___ \ \_____ \ +| ___/ _ \/ ___/ | \ / \ \/ / ____/ +| | ( <_> )___ \| Y \ \ \____/ \ +|____| \____/____ >___| / \______ /\_______ + \/ \/ \/ \/ +================= www.PoshC2.co.uk =============== ++""" + + if table == "CompletedTasks": + HTMLPre += """ + + +""" + + if table == "Implants": + HTMLPre += """ + + +""" + conn = sqlite3.connect(DB) + pd.set_option('display.max_colwidth', -1) + pd.options.mode.chained_assignment = None + frame = pd.read_sql_query("SELECT * FROM %s" % table, conn) + + # encode the Output column + if table == "CompletedTasks": + for index, row in frame.iterrows(): + frame.loc[index, "Command"] = replace_tabs(cgi.escape(row["Command"])) + frame.loc[index, "Output"] = replace_tabs(cgi.escape(row["Output"])) + + # convert the random uri to original hostname + if table == "CompletedTasks": + framelen = frame['RandomURI'].count() + for x in range(0, framelen): + try: + frame['RandomURI'][x] + a = get_htmlimplant(str(frame['RandomURI'][x])) + frame['RandomURI'][x] = a[2] + " @ " + a[3] + except Exception as e: + print e + a = "None" + + reportname = "%s%s.html" % (ReportsDirectory,table) + output_file = open(reportname, 'w') + HTMLPost = (frame.to_html(classes='table',index=False,escape=False)).replace("\\r\\n","") + HTMLPost = HTMLPost.replace("\\n","") + HTMLPost = re.sub(u'\x00', '', HTMLPost) + HTMLPost = HTMLPost.replace("
CompletedTaskID | ","ID | ") + HTMLPost = HTMLPost.replace("ID | ","ID | ") + HTMLPost = HTMLPost.replace("TaskID | ","TaskID | ") + HTMLPost = HTMLPost.replace("RandomURI | ","RandomURI | ") + HTMLPost = HTMLPost.replace("Command | ","Command | ") + HTMLPost = HTMLPost.replace("Output | ","Output | ") + HTMLPost = HTMLPost.replace("Prompt | ","Prompt | ") + HTMLPost = HTMLPost.replace("ImplantID | ","ImplantID | ") + HTMLPost = HTMLPost.replace("User | ","User | ") + HTMLPost = HTMLPost.replace("Hostname | ","Hostname | ") + HTMLPost = HTMLPost.replace("IpAddress | ","IpAddress | ") + HTMLPost = HTMLPost.replace("Key | ","Key | ") + HTMLPost = HTMLPost.replace("FirstSeen | ","FirstSeen | ") + HTMLPost = HTMLPost.replace("LastSeen | ","LastSeen | ") + HTMLPost = HTMLPost.replace("PID | ","PID | ") + HTMLPost = HTMLPost.replace("Proxy | ","Proxy | ") + HTMLPost = HTMLPost.replace("Arch | ","Arch | ") + HTMLPost = HTMLPost.replace("Domain | ","Domain | ") + HTMLPost = HTMLPost.replace("Alive | ","Alive | ") + HTMLPost = HTMLPost.replace("Sleep | ","Sleep | ") + HTMLPost = HTMLPost.replace("ModsLoaded | ","ModsLoaded | ") + HTMLPost = HTMLPost.replace("Pivot | ","Pivot | ") + HTMLPost = HTMLPost + """ +""" + output_file.write("%s%s" % (HTMLPre.encode('utf-8'),HTMLPost.encode('utf-8'))) + output_file.close() + print reportname + +generate_table("CompletedTasks") +generate_table("C2Server") +generate_table("Creds") +generate_table("Implants")
---|