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

Reporter(options, verbose=False)
26    def __init__(self, options, verbose=False):
27        super(Reporter, self).__init__()
28        self.options = options
29        self.verbose = verbose
30        self.test_results = {}
options
verbose
test_results
def print_testing(self, msprotocol_rpc_instance):
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()
def print_info(self, message):
36    def print_info(self, message):
37        print("\x1b[1;92minfo\x1b[0m\x1b[1m]\x1b[0m %s" % message)
38        sys.stdout.flush()
def print_warn(self, message):
40    def print_warn(self, message):
41        print("\x1b[1;91mwarn\x1b[0m\x1b[1m]\x1b[0m %s" % message)
42        sys.stdout.flush()
def print_verbose(self, message):
44    def print_verbose(self, message):
45        print("[debug]",message)
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)