coercer.core.Reporter
1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# File name : Reporter.py 4# Author : Podalirius (@podalirius_) 5# Date created : 17 Jul 2022 6 7import sqlite3 8import os 9import json 10import xlsxwriter 11import sys 12from coercer.structures.ReportingLevel import ReportingLevel 13from coercer.structures.TestResult import TestResult 14 15 16CURSOR_UP_ONE = '\x1b[1A' 17ERASE_LINE = '\x1b[2K' 18 19 20class Reporter(object): 21 """ 22 Documentation for class Reporter 23 """ 24 25 def __init__(self, options, verbose=False): 26 super(Reporter, self).__init__() 27 self.options = options 28 self.verbose = verbose 29 self.test_results = {} 30 31 def print_testing(self, msprotocol_rpc_instance): 32 print(" [>] (\x1b[93m%s\x1b[0m) %s " % ("-testing-", str(msprotocol_rpc_instance))) 33 sys.stdout.flush() 34 35 def print_info(self, message): 36 print("\x1b[1;92minfo\x1b[0m\x1b[1m]\x1b[0m %s" % message) 37 sys.stdout.flush() 38 39 def print_warn(self, message): 40 print("\x1b[1;91mwarn\x1b[0m\x1b[1m]\x1b[0m %s" % message) 41 sys.stdout.flush() 42 43 def print_verbose(self, message): 44 print("[debug]",message) 45 46 def report_test_result(self, uuid, version, namedpipe, msprotocol_rpc_instance, result, exploitpath): 47 function_name = msprotocol_rpc_instance.function["name"] 48 if uuid not in self.test_results.keys(): 49 self.test_results[uuid] = {} 50 if version not in self.test_results[uuid].keys(): 51 self.test_results[uuid][version] = {} 52 if function_name not in self.test_results[uuid][version].keys(): 53 self.test_results[uuid][version][function_name] = {} 54 if namedpipe not in self.test_results[uuid][version][function_name].keys(): 55 self.test_results[uuid][version][function_name][namedpipe] = [] 56 57 # Save result to database 58 self.test_results[uuid][version][function_name][namedpipe].append({ 59 "function": msprotocol_rpc_instance.function, 60 "protocol": msprotocol_rpc_instance.protocol, 61 "testresult": result.name, 62 "exploitpath": exploitpath 63 }) 64 65 sys.stdout.write(CURSOR_UP_ONE) 66 sys.stdout.write(ERASE_LINE) 67 if self.options.mode in ["scan", "fuzz"]: 68 if result == TestResult.SMB_AUTH_RECEIVED: 69 print(" [\x1b[1;92m+\x1b[0m] (\x1b[1;92m%s\x1b[0m) %s " % ("SMB Auth", str(msprotocol_rpc_instance))) 70 sys.stdout.flush() 71 elif result == TestResult.HTTP_AUTH_RECEIVED: 72 print(" [\x1b[1;92m+\x1b[0m] (\x1b[1;92m%s\x1b[0m) %s " % ("HTTP Auth", str(msprotocol_rpc_instance))) 73 sys.stdout.flush() 74 elif result == TestResult.NCA_S_UNK_IF: 75 print(" [\x1b[1;95m-\x1b[0m] (\x1b[1;95m%s\x1b[0m) %s " % ("-No Func-", str(msprotocol_rpc_instance))) 76 sys.stdout.flush() 77 else: 78 if self.verbose: 79 print(" [\x1b[1;91m!\x1b[0m] (\x1b[1;91m%s\x1b[0m) %s " % (result.name, str(msprotocol_rpc_instance))) 80 sys.stdout.flush() 81 elif self.options.mode in ["coerce"]: 82 if result == TestResult.ERROR_BAD_NETPATH: 83 print(" [\x1b[1;92m+\x1b[0m] (\x1b[1;92m%s\x1b[0m) %s " % ("ERROR_BAD_NETPATH", str(msprotocol_rpc_instance))) 84 sys.stdout.flush() 85 else: 86 if self.verbose: 87 print(" [\x1b[1;91m!\x1b[0m] (\x1b[1;91m%s\x1b[0m) %s " % (result.name, str(msprotocol_rpc_instance))) 88 sys.stdout.flush() 89 90 def exportXLSX(self, filename): 91 basepath = os.path.dirname(filename) 92 filename = os.path.basename(filename) 93 if basepath not in [".", ""]: 94 if not os.path.exists(basepath): 95 os.makedirs(basepath) 96 path_to_file = basepath + os.path.sep + filename 97 else: 98 path_to_file = filename 99 # export 100 101 workbook = xlsxwriter.Workbook(path_to_file) 102 worksheet = workbook.add_worksheet() 103 104 header_format = workbook.add_format({'bold': 1}) 105 header_fields = ["Interface UUID", "Interface version", "SMB named pipe", "Protocol long name", "Protocol short name", "RPC function name", "Operation number", "Result", "Working path"] 106 for k in range(len(header_fields)): 107 worksheet.set_column(k, k + 1, len(header_fields[k]) + 3) 108 worksheet.set_row(0, 60, header_format) 109 worksheet.write_row(0, 0, header_fields) 110 111 row_id = 1 112 for uuid in self.test_results.keys(): 113 for version in self.test_results[uuid].keys(): 114 for function_name in self.test_results[uuid][version].keys(): 115 for namedpipe in self.test_results[uuid][version][function_name].keys(): 116 for test_result in self.test_results[uuid][version][function_name][namedpipe]: 117 data = [uuid, version, namedpipe, test_result["protocol"]["longname"], test_result["protocol"]["shortname"], test_result["function"]["name"], test_result["function"]["opnum"], test_result["testresult"], test_result["exploitpath"]] 118 worksheet.write_row(row_id, 0, data) 119 row_id += 1 120 worksheet.autofilter(0, 0, row_id, len(header_fields) - 1) 121 workbook.close() 122 self.print_info("Results exported to XLSX in '%s'" % path_to_file) 123 124 def exportJSON(self, filename): 125 basepath = os.path.dirname(filename) 126 filename = os.path.basename(filename) 127 if basepath not in [".", ""]: 128 if not os.path.exists(basepath): 129 os.makedirs(basepath) 130 path_to_file = basepath + os.path.sep + filename 131 else: 132 path_to_file = filename 133 # export 134 f = open(path_to_file, "w") 135 f.write(json.dumps(self.test_results, indent=4)) 136 f.close() 137 self.print_info("Results exported to JSON in '%s'" % path_to_file) 138 139 def exportSQLITE(self, target, filename): 140 basepath = os.path.dirname(filename) 141 filename = os.path.basename(filename) 142 if basepath not in [".", ""]: 143 if not os.path.exists(basepath): 144 os.makedirs(basepath) 145 path_to_file = basepath + os.path.sep + filename 146 else: 147 path_to_file = filename 148 # Exporting results 149 # Connecting to sqlite 150 conn = sqlite3.connect(path_to_file) 151 # Creating a cursor object using the cursor() method 152 cursor = conn.cursor() 153 cursor.execute("CREATE TABLE IF NOT EXISTS results(target VARCHAR(255), uuid VARCHAR(255), version VARCHAR(255), named_pipe VARCHAR(255), protocol_shortname VARCHAR(255), protocol_longname VARCHAR(512), function_name VARCHAR(255), result VARCHAR(255), path VARCHAR(512));") 154 for uuid in self.test_results.keys(): 155 for version in self.test_results[uuid].keys(): 156 for function_name in self.test_results[uuid][version].keys(): 157 for named_pipe in self.test_results[uuid][version][function_name].keys(): 158 for test_result in self.test_results[uuid][version][function_name][named_pipe]: 159 cursor.execute("INSERT INTO results VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", ( 160 target, 161 uuid, 162 version, 163 named_pipe, 164 test_result["protocol"]["shortname"], 165 test_result["protocol"]["longname"], 166 function_name, 167 test_result["testresult"], 168 str(bytes(test_result["exploitpath"], 'utf-8'))[2:-1].replace('\\\\', '\\') 169 ) 170 ) 171 # Commit your changes in the database 172 conn.commit() 173 # Closing the connection 174 conn.close() 175 self.print_info("Results exported to SQLITE3 db in '%s'" % path_to_file)
CURSOR_UP_ONE =
'\x1b[1A'
ERASE_LINE =
'\x1b[2K'
class
Reporter:
21class Reporter(object): 22 """ 23 Documentation for class Reporter 24 """ 25 26 def __init__(self, options, verbose=False): 27 super(Reporter, self).__init__() 28 self.options = options 29 self.verbose = verbose 30 self.test_results = {} 31 32 def print_testing(self, msprotocol_rpc_instance): 33 print(" [>] (\x1b[93m%s\x1b[0m) %s " % ("-testing-", str(msprotocol_rpc_instance))) 34 sys.stdout.flush() 35 36 def print_info(self, message): 37 print("\x1b[1;92minfo\x1b[0m\x1b[1m]\x1b[0m %s" % message) 38 sys.stdout.flush() 39 40 def print_warn(self, message): 41 print("\x1b[1;91mwarn\x1b[0m\x1b[1m]\x1b[0m %s" % message) 42 sys.stdout.flush() 43 44 def print_verbose(self, message): 45 print("[debug]",message) 46 47 def report_test_result(self, uuid, version, namedpipe, msprotocol_rpc_instance, result, exploitpath): 48 function_name = msprotocol_rpc_instance.function["name"] 49 if uuid not in self.test_results.keys(): 50 self.test_results[uuid] = {} 51 if version not in self.test_results[uuid].keys(): 52 self.test_results[uuid][version] = {} 53 if function_name not in self.test_results[uuid][version].keys(): 54 self.test_results[uuid][version][function_name] = {} 55 if namedpipe not in self.test_results[uuid][version][function_name].keys(): 56 self.test_results[uuid][version][function_name][namedpipe] = [] 57 58 # Save result to database 59 self.test_results[uuid][version][function_name][namedpipe].append({ 60 "function": msprotocol_rpc_instance.function, 61 "protocol": msprotocol_rpc_instance.protocol, 62 "testresult": result.name, 63 "exploitpath": exploitpath 64 }) 65 66 sys.stdout.write(CURSOR_UP_ONE) 67 sys.stdout.write(ERASE_LINE) 68 if self.options.mode in ["scan", "fuzz"]: 69 if result == TestResult.SMB_AUTH_RECEIVED: 70 print(" [\x1b[1;92m+\x1b[0m] (\x1b[1;92m%s\x1b[0m) %s " % ("SMB Auth", str(msprotocol_rpc_instance))) 71 sys.stdout.flush() 72 elif result == TestResult.HTTP_AUTH_RECEIVED: 73 print(" [\x1b[1;92m+\x1b[0m] (\x1b[1;92m%s\x1b[0m) %s " % ("HTTP Auth", str(msprotocol_rpc_instance))) 74 sys.stdout.flush() 75 elif result == TestResult.NCA_S_UNK_IF: 76 print(" [\x1b[1;95m-\x1b[0m] (\x1b[1;95m%s\x1b[0m) %s " % ("-No Func-", str(msprotocol_rpc_instance))) 77 sys.stdout.flush() 78 else: 79 if self.verbose: 80 print(" [\x1b[1;91m!\x1b[0m] (\x1b[1;91m%s\x1b[0m) %s " % (result.name, str(msprotocol_rpc_instance))) 81 sys.stdout.flush() 82 elif self.options.mode in ["coerce"]: 83 if result == TestResult.ERROR_BAD_NETPATH: 84 print(" [\x1b[1;92m+\x1b[0m] (\x1b[1;92m%s\x1b[0m) %s " % ("ERROR_BAD_NETPATH", str(msprotocol_rpc_instance))) 85 sys.stdout.flush() 86 else: 87 if self.verbose: 88 print(" [\x1b[1;91m!\x1b[0m] (\x1b[1;91m%s\x1b[0m) %s " % (result.name, str(msprotocol_rpc_instance))) 89 sys.stdout.flush() 90 91 def exportXLSX(self, filename): 92 basepath = os.path.dirname(filename) 93 filename = os.path.basename(filename) 94 if basepath not in [".", ""]: 95 if not os.path.exists(basepath): 96 os.makedirs(basepath) 97 path_to_file = basepath + os.path.sep + filename 98 else: 99 path_to_file = filename 100 # export 101 102 workbook = xlsxwriter.Workbook(path_to_file) 103 worksheet = workbook.add_worksheet() 104 105 header_format = workbook.add_format({'bold': 1}) 106 header_fields = ["Interface UUID", "Interface version", "SMB named pipe", "Protocol long name", "Protocol short name", "RPC function name", "Operation number", "Result", "Working path"] 107 for k in range(len(header_fields)): 108 worksheet.set_column(k, k + 1, len(header_fields[k]) + 3) 109 worksheet.set_row(0, 60, header_format) 110 worksheet.write_row(0, 0, header_fields) 111 112 row_id = 1 113 for uuid in self.test_results.keys(): 114 for version in self.test_results[uuid].keys(): 115 for function_name in self.test_results[uuid][version].keys(): 116 for namedpipe in self.test_results[uuid][version][function_name].keys(): 117 for test_result in self.test_results[uuid][version][function_name][namedpipe]: 118 data = [uuid, version, namedpipe, test_result["protocol"]["longname"], test_result["protocol"]["shortname"], test_result["function"]["name"], test_result["function"]["opnum"], test_result["testresult"], test_result["exploitpath"]] 119 worksheet.write_row(row_id, 0, data) 120 row_id += 1 121 worksheet.autofilter(0, 0, row_id, len(header_fields) - 1) 122 workbook.close() 123 self.print_info("Results exported to XLSX in '%s'" % path_to_file) 124 125 def exportJSON(self, filename): 126 basepath = os.path.dirname(filename) 127 filename = os.path.basename(filename) 128 if basepath not in [".", ""]: 129 if not os.path.exists(basepath): 130 os.makedirs(basepath) 131 path_to_file = basepath + os.path.sep + filename 132 else: 133 path_to_file = filename 134 # export 135 f = open(path_to_file, "w") 136 f.write(json.dumps(self.test_results, indent=4)) 137 f.close() 138 self.print_info("Results exported to JSON in '%s'" % path_to_file) 139 140 def exportSQLITE(self, target, filename): 141 basepath = os.path.dirname(filename) 142 filename = os.path.basename(filename) 143 if basepath not in [".", ""]: 144 if not os.path.exists(basepath): 145 os.makedirs(basepath) 146 path_to_file = basepath + os.path.sep + filename 147 else: 148 path_to_file = filename 149 # Exporting results 150 # Connecting to sqlite 151 conn = sqlite3.connect(path_to_file) 152 # Creating a cursor object using the cursor() method 153 cursor = conn.cursor() 154 cursor.execute("CREATE TABLE IF NOT EXISTS results(target VARCHAR(255), uuid VARCHAR(255), version VARCHAR(255), named_pipe VARCHAR(255), protocol_shortname VARCHAR(255), protocol_longname VARCHAR(512), function_name VARCHAR(255), result VARCHAR(255), path VARCHAR(512));") 155 for uuid in self.test_results.keys(): 156 for version in self.test_results[uuid].keys(): 157 for function_name in self.test_results[uuid][version].keys(): 158 for named_pipe in self.test_results[uuid][version][function_name].keys(): 159 for test_result in self.test_results[uuid][version][function_name][named_pipe]: 160 cursor.execute("INSERT INTO results VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", ( 161 target, 162 uuid, 163 version, 164 named_pipe, 165 test_result["protocol"]["shortname"], 166 test_result["protocol"]["longname"], 167 function_name, 168 test_result["testresult"], 169 str(bytes(test_result["exploitpath"], 'utf-8'))[2:-1].replace('\\\\', '\\') 170 ) 171 ) 172 # Commit your changes in the database 173 conn.commit() 174 # Closing the connection 175 conn.close() 176 self.print_info("Results exported to SQLITE3 db in '%s'" % path_to_file)
Documentation for class Reporter
def
report_test_result( self, uuid, version, namedpipe, msprotocol_rpc_instance, result, exploitpath):
47 def report_test_result(self, uuid, version, namedpipe, msprotocol_rpc_instance, result, exploitpath): 48 function_name = msprotocol_rpc_instance.function["name"] 49 if uuid not in self.test_results.keys(): 50 self.test_results[uuid] = {} 51 if version not in self.test_results[uuid].keys(): 52 self.test_results[uuid][version] = {} 53 if function_name not in self.test_results[uuid][version].keys(): 54 self.test_results[uuid][version][function_name] = {} 55 if namedpipe not in self.test_results[uuid][version][function_name].keys(): 56 self.test_results[uuid][version][function_name][namedpipe] = [] 57 58 # Save result to database 59 self.test_results[uuid][version][function_name][namedpipe].append({ 60 "function": msprotocol_rpc_instance.function, 61 "protocol": msprotocol_rpc_instance.protocol, 62 "testresult": result.name, 63 "exploitpath": exploitpath 64 }) 65 66 sys.stdout.write(CURSOR_UP_ONE) 67 sys.stdout.write(ERASE_LINE) 68 if self.options.mode in ["scan", "fuzz"]: 69 if result == TestResult.SMB_AUTH_RECEIVED: 70 print(" [\x1b[1;92m+\x1b[0m] (\x1b[1;92m%s\x1b[0m) %s " % ("SMB Auth", str(msprotocol_rpc_instance))) 71 sys.stdout.flush() 72 elif result == TestResult.HTTP_AUTH_RECEIVED: 73 print(" [\x1b[1;92m+\x1b[0m] (\x1b[1;92m%s\x1b[0m) %s " % ("HTTP Auth", str(msprotocol_rpc_instance))) 74 sys.stdout.flush() 75 elif result == TestResult.NCA_S_UNK_IF: 76 print(" [\x1b[1;95m-\x1b[0m] (\x1b[1;95m%s\x1b[0m) %s " % ("-No Func-", str(msprotocol_rpc_instance))) 77 sys.stdout.flush() 78 else: 79 if self.verbose: 80 print(" [\x1b[1;91m!\x1b[0m] (\x1b[1;91m%s\x1b[0m) %s " % (result.name, str(msprotocol_rpc_instance))) 81 sys.stdout.flush() 82 elif self.options.mode in ["coerce"]: 83 if result == TestResult.ERROR_BAD_NETPATH: 84 print(" [\x1b[1;92m+\x1b[0m] (\x1b[1;92m%s\x1b[0m) %s " % ("ERROR_BAD_NETPATH", str(msprotocol_rpc_instance))) 85 sys.stdout.flush() 86 else: 87 if self.verbose: 88 print(" [\x1b[1;91m!\x1b[0m] (\x1b[1;91m%s\x1b[0m) %s " % (result.name, str(msprotocol_rpc_instance))) 89 sys.stdout.flush()
def
exportXLSX(self, filename):
91 def exportXLSX(self, filename): 92 basepath = os.path.dirname(filename) 93 filename = os.path.basename(filename) 94 if basepath not in [".", ""]: 95 if not os.path.exists(basepath): 96 os.makedirs(basepath) 97 path_to_file = basepath + os.path.sep + filename 98 else: 99 path_to_file = filename 100 # export 101 102 workbook = xlsxwriter.Workbook(path_to_file) 103 worksheet = workbook.add_worksheet() 104 105 header_format = workbook.add_format({'bold': 1}) 106 header_fields = ["Interface UUID", "Interface version", "SMB named pipe", "Protocol long name", "Protocol short name", "RPC function name", "Operation number", "Result", "Working path"] 107 for k in range(len(header_fields)): 108 worksheet.set_column(k, k + 1, len(header_fields[k]) + 3) 109 worksheet.set_row(0, 60, header_format) 110 worksheet.write_row(0, 0, header_fields) 111 112 row_id = 1 113 for uuid in self.test_results.keys(): 114 for version in self.test_results[uuid].keys(): 115 for function_name in self.test_results[uuid][version].keys(): 116 for namedpipe in self.test_results[uuid][version][function_name].keys(): 117 for test_result in self.test_results[uuid][version][function_name][namedpipe]: 118 data = [uuid, version, namedpipe, test_result["protocol"]["longname"], test_result["protocol"]["shortname"], test_result["function"]["name"], test_result["function"]["opnum"], test_result["testresult"], test_result["exploitpath"]] 119 worksheet.write_row(row_id, 0, data) 120 row_id += 1 121 worksheet.autofilter(0, 0, row_id, len(header_fields) - 1) 122 workbook.close() 123 self.print_info("Results exported to XLSX in '%s'" % path_to_file)
def
exportJSON(self, filename):
125 def exportJSON(self, filename): 126 basepath = os.path.dirname(filename) 127 filename = os.path.basename(filename) 128 if basepath not in [".", ""]: 129 if not os.path.exists(basepath): 130 os.makedirs(basepath) 131 path_to_file = basepath + os.path.sep + filename 132 else: 133 path_to_file = filename 134 # export 135 f = open(path_to_file, "w") 136 f.write(json.dumps(self.test_results, indent=4)) 137 f.close() 138 self.print_info("Results exported to JSON in '%s'" % path_to_file)
def
exportSQLITE(self, target, filename):
140 def exportSQLITE(self, target, filename): 141 basepath = os.path.dirname(filename) 142 filename = os.path.basename(filename) 143 if basepath not in [".", ""]: 144 if not os.path.exists(basepath): 145 os.makedirs(basepath) 146 path_to_file = basepath + os.path.sep + filename 147 else: 148 path_to_file = filename 149 # Exporting results 150 # Connecting to sqlite 151 conn = sqlite3.connect(path_to_file) 152 # Creating a cursor object using the cursor() method 153 cursor = conn.cursor() 154 cursor.execute("CREATE TABLE IF NOT EXISTS results(target VARCHAR(255), uuid VARCHAR(255), version VARCHAR(255), named_pipe VARCHAR(255), protocol_shortname VARCHAR(255), protocol_longname VARCHAR(512), function_name VARCHAR(255), result VARCHAR(255), path VARCHAR(512));") 155 for uuid in self.test_results.keys(): 156 for version in self.test_results[uuid].keys(): 157 for function_name in self.test_results[uuid][version].keys(): 158 for named_pipe in self.test_results[uuid][version][function_name].keys(): 159 for test_result in self.test_results[uuid][version][function_name][named_pipe]: 160 cursor.execute("INSERT INTO results VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", ( 161 target, 162 uuid, 163 version, 164 named_pipe, 165 test_result["protocol"]["shortname"], 166 test_result["protocol"]["longname"], 167 function_name, 168 test_result["testresult"], 169 str(bytes(test_result["exploitpath"], 'utf-8'))[2:-1].replace('\\\\', '\\') 170 ) 171 ) 172 # Commit your changes in the database 173 conn.commit() 174 # Closing the connection 175 conn.close() 176 self.print_info("Results exported to SQLITE3 db in '%s'" % path_to_file)