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 16from coercer.network.rpc import portmap_discover, is_port_open, can_bind_to_interface_on_port 17 18 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 if "dcerpc" in options.filter_transport_name: 31 if not options.dce_ports: 32 portmap = portmap_discover(target, options.dce_port) 33 else: 34 portmap = {} 35 tasks = {} 36 for method_type in available_methods.keys(): 37 for category in sorted(available_methods[method_type].keys()): 38 for method in sorted(available_methods[method_type][category].keys()): 39 instance = available_methods[method_type][category][method]["class"] 40 41 if filter.method_matches_filter(instance): 42 for access_type, access_methods in instance.access.items(): 43 if access_type not in tasks.keys(): 44 tasks[access_type] = {} 45 46 # Access through SMB named pipe 47 if access_type == "ncan_np": 48 for access_method in access_methods: 49 namedpipe, uuid, version = access_method["namedpipe"], access_method["uuid"], access_method["version"] 50 if namedpipe not in tasks[access_type].keys(): 51 tasks[access_type][namedpipe] = {} 52 53 if uuid not in tasks[access_type][namedpipe].keys(): 54 tasks[access_type][namedpipe][uuid] = {} 55 56 if version not in tasks[access_type][namedpipe][uuid].keys(): 57 tasks[access_type][namedpipe][uuid][version] = [] 58 59 if instance not in tasks[access_type][namedpipe][uuid][version]: 60 tasks[access_type][namedpipe][uuid][version].append(instance) 61 elif access_type == "ncacn_ip_tcp": 62 for access_method in access_methods: 63 uuid, version = access_method["uuid"], access_method["version"] 64 for port in options.dce_ports or portmap.get("ncacn_ip_tcp",{}).get("%s v%s"%(uuid.upper(),version),[]): 65 if port not in tasks[access_type].keys(): 66 tasks[access_type][port] = {} 67 68 if uuid not in tasks[access_type][port].keys(): 69 tasks[access_type][port][uuid] = {} 70 71 if version not in tasks[access_type][port][uuid].keys(): 72 tasks[access_type][port][uuid][version] = [] 73 74 if instance not in tasks[access_type][port][uuid][version]: 75 tasks[access_type][port][uuid][version].append(instance) 76 77 # Executing tasks ======================================================================================================================= 78 79 listening_ip = get_ip_addr_to_listen_on(target, options) 80 if options.verbose: 81 print("[+] Listening for authentications on '%s', SMB port %d" % (listening_ip, options.smb_port)) 82 83 # Processing ncan_np tasks 84 if len(tasks.keys()) == 0: 85 return None 86 if "dcerpc" in options.filter_transport_name: 87 ncacn_ip_tcp_tasks = tasks.get("ncacn_ip_tcp", {}) 88 for port in sorted(ncacn_ip_tcp_tasks.keys()): 89 if is_port_open(target, port): 90 print("[+] DCERPC port '\x1b[1;94m%d\x1b[0m' is \x1b[1;92maccessible\x1b[0m!" % port) 91 for uuid in sorted(ncacn_ip_tcp_tasks[port].keys()): 92 for version in sorted(ncacn_ip_tcp_tasks[port][uuid].keys()): 93 if can_bind_to_interface_on_port(target, port, credentials, uuid, version): 94 print(" [+] Successful bind to interface (%s, %s)!" % (uuid, version)) 95 for msprotocol_class in sorted(ncacn_ip_tcp_tasks[port][uuid][version], key=lambda x:x.function["name"]): 96 97 exploit_paths = msprotocol_class.generate_exploit_templates(desired_auth_type=options.auth_type) 98 99 stop_exploiting_this_function = False 100 for listener_type, exploitpath in exploit_paths: 101 if stop_exploiting_this_function == True: 102 # Got a nca_s_unk_if response, this function does not listen on the given interface 103 continue 104 if listener_type == "http": 105 http_listen_port = get_next_http_listener_port(current_value=http_listen_port, listen_ip=listening_ip, options=options) 106 107 exploitpath = generate_exploit_path_from_template( 108 template=exploitpath, 109 listener=listening_ip, 110 http_listen_port=options.http_port, 111 smb_listen_port=options.smb_port 112 ) 113 114 msprotocol_rpc_instance = msprotocol_class(path=exploitpath) 115 dcerpc = DCERPCSession(credentials=credentials, verbose=True) 116 dcerpc.connect_ncacn_ip_tcp(target=target, port=port) 117 118 if dcerpc.session is not None: 119 dcerpc.bind(interface_uuid=uuid, interface_version=version) 120 if dcerpc.session is not None: 121 reporter.print_testing(msprotocol_rpc_instance) 122 123 result = trigger_and_catch_authentication( 124 options=options, 125 dcerpc_session=dcerpc.session, 126 target=target, 127 method_trigger_function=msprotocol_rpc_instance.trigger, 128 listenertype=listener_type, 129 listen_ip=listening_ip, 130 http_port=http_listen_port 131 ) 132 133 reporter.report_test_result( 134 uuid=uuid, version=version, namedpipe=namedpipe, 135 msprotocol_rpc_instance=msprotocol_rpc_instance, 136 result=result, 137 exploitpath=exploitpath 138 ) 139 140 if result == TestResult.NCA_S_UNK_IF: 141 stop_exploiting_this_function = True 142 143 if options.delay is not None: 144 # Sleep between attempts 145 time.sleep(options.delay) 146 else: 147 if options.verbose: 148 print(" [!] Cannot bind to interface (%s, %s)!" % (uuid, version)) 149 else: 150 if options.verbose: 151 print("[!] DCERPC port '\x1b[1;94m%d\x1b[0m' is \x1b[1;91mclosed\x1b[0m!" % port) 152 153 if "msrpc" in options.filter_transport_name: 154 ncan_np_tasks = tasks["ncan_np"] 155 for namedpipe in sorted(ncan_np_tasks.keys()): 156 if can_connect_to_pipe(target, namedpipe, credentials): 157 print("[+] SMB named pipe '\x1b[1;94m%s\x1b[0m' is \x1b[1;92maccessible\x1b[0m!" % namedpipe) 158 for uuid in sorted(ncan_np_tasks[namedpipe].keys()): 159 for version in sorted(ncan_np_tasks[namedpipe][uuid].keys()): 160 if can_bind_to_interface(target, namedpipe, credentials, uuid, version): 161 print(" [+] Successful bind to interface (%s, %s)!" % (uuid, version)) 162 for msprotocol_class in sorted(ncan_np_tasks[namedpipe][uuid][version], key=lambda x:x.function["name"]): 163 164 exploit_paths = msprotocol_class.generate_exploit_templates(desired_auth_type=options.auth_type) 165 166 stop_exploiting_this_function = False 167 for listener_type, exploitpath in exploit_paths: 168 if stop_exploiting_this_function == True: 169 # Got a nca_s_unk_if response, this function does not listen on the given interface 170 continue 171 if listener_type == "http": 172 http_listen_port = get_next_http_listener_port(current_value=http_listen_port, listen_ip=listening_ip, options=options) 173 174 exploitpath = generate_exploit_path_from_template( 175 template=exploitpath, 176 listener=listening_ip, 177 http_listen_port=options.http_port, 178 smb_listen_port=options.smb_port 179 ) 180 181 msprotocol_rpc_instance = msprotocol_class(path=exploitpath) 182 dcerpc = DCERPCSession(credentials=credentials, verbose=True) 183 dcerpc.connect_ncacn_np(target=target, pipe=namedpipe) 184 185 if dcerpc.session is not None: 186 dcerpc.bind(interface_uuid=uuid, interface_version=version) 187 if dcerpc.session is not None: 188 reporter.print_testing(msprotocol_rpc_instance) 189 190 result = trigger_and_catch_authentication( 191 options=options, 192 dcerpc_session=dcerpc.session, 193 target=target, 194 method_trigger_function=msprotocol_rpc_instance.trigger, 195 listenertype=listener_type, 196 listen_ip=listening_ip, 197 http_port=http_listen_port 198 ) 199 200 reporter.report_test_result( 201 uuid=uuid, version=version, namedpipe=namedpipe, 202 msprotocol_rpc_instance=msprotocol_rpc_instance, 203 result=result, 204 exploitpath=exploitpath 205 ) 206 207 if result == TestResult.NCA_S_UNK_IF: 208 stop_exploiting_this_function = True 209 210 if options.delay is not None: 211 # Sleep between attempts 212 time.sleep(options.delay) 213 else: 214 if options.verbose: 215 print(" [!] Cannot bind to interface (%s, %s)!" % (uuid, version)) 216 else: 217 if options.verbose: 218 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):
20def action_scan(target, available_methods, options, credentials, reporter): 21 http_listen_port = 0 22 23 filter = Filter( 24 filter_method_name=options.filter_method_name, 25 filter_protocol_name=options.filter_protocol_name, 26 filter_pipe_name=options.filter_pipe_name 27 ) 28 29 # Preparing tasks ============================================================================================================== 30 31 if "dcerpc" in options.filter_transport_name: 32 if not options.dce_ports: 33 portmap = portmap_discover(target, options.dce_port) 34 else: 35 portmap = {} 36 tasks = {} 37 for method_type in available_methods.keys(): 38 for category in sorted(available_methods[method_type].keys()): 39 for method in sorted(available_methods[method_type][category].keys()): 40 instance = available_methods[method_type][category][method]["class"] 41 42 if filter.method_matches_filter(instance): 43 for access_type, access_methods in instance.access.items(): 44 if access_type not in tasks.keys(): 45 tasks[access_type] = {} 46 47 # Access through SMB named pipe 48 if access_type == "ncan_np": 49 for access_method in access_methods: 50 namedpipe, uuid, version = access_method["namedpipe"], access_method["uuid"], access_method["version"] 51 if namedpipe not in tasks[access_type].keys(): 52 tasks[access_type][namedpipe] = {} 53 54 if uuid not in tasks[access_type][namedpipe].keys(): 55 tasks[access_type][namedpipe][uuid] = {} 56 57 if version not in tasks[access_type][namedpipe][uuid].keys(): 58 tasks[access_type][namedpipe][uuid][version] = [] 59 60 if instance not in tasks[access_type][namedpipe][uuid][version]: 61 tasks[access_type][namedpipe][uuid][version].append(instance) 62 elif access_type == "ncacn_ip_tcp": 63 for access_method in access_methods: 64 uuid, version = access_method["uuid"], access_method["version"] 65 for port in options.dce_ports or portmap.get("ncacn_ip_tcp",{}).get("%s v%s"%(uuid.upper(),version),[]): 66 if port not in tasks[access_type].keys(): 67 tasks[access_type][port] = {} 68 69 if uuid not in tasks[access_type][port].keys(): 70 tasks[access_type][port][uuid] = {} 71 72 if version not in tasks[access_type][port][uuid].keys(): 73 tasks[access_type][port][uuid][version] = [] 74 75 if instance not in tasks[access_type][port][uuid][version]: 76 tasks[access_type][port][uuid][version].append(instance) 77 78 # Executing tasks ======================================================================================================================= 79 80 listening_ip = get_ip_addr_to_listen_on(target, options) 81 if options.verbose: 82 print("[+] Listening for authentications on '%s', SMB port %d" % (listening_ip, options.smb_port)) 83 84 # Processing ncan_np tasks 85 if len(tasks.keys()) == 0: 86 return None 87 if "dcerpc" in options.filter_transport_name: 88 ncacn_ip_tcp_tasks = tasks.get("ncacn_ip_tcp", {}) 89 for port in sorted(ncacn_ip_tcp_tasks.keys()): 90 if is_port_open(target, port): 91 print("[+] DCERPC port '\x1b[1;94m%d\x1b[0m' is \x1b[1;92maccessible\x1b[0m!" % port) 92 for uuid in sorted(ncacn_ip_tcp_tasks[port].keys()): 93 for version in sorted(ncacn_ip_tcp_tasks[port][uuid].keys()): 94 if can_bind_to_interface_on_port(target, port, credentials, uuid, version): 95 print(" [+] Successful bind to interface (%s, %s)!" % (uuid, version)) 96 for msprotocol_class in sorted(ncacn_ip_tcp_tasks[port][uuid][version], key=lambda x:x.function["name"]): 97 98 exploit_paths = msprotocol_class.generate_exploit_templates(desired_auth_type=options.auth_type) 99 100 stop_exploiting_this_function = False 101 for listener_type, exploitpath in exploit_paths: 102 if stop_exploiting_this_function == True: 103 # Got a nca_s_unk_if response, this function does not listen on the given interface 104 continue 105 if listener_type == "http": 106 http_listen_port = get_next_http_listener_port(current_value=http_listen_port, listen_ip=listening_ip, options=options) 107 108 exploitpath = generate_exploit_path_from_template( 109 template=exploitpath, 110 listener=listening_ip, 111 http_listen_port=options.http_port, 112 smb_listen_port=options.smb_port 113 ) 114 115 msprotocol_rpc_instance = msprotocol_class(path=exploitpath) 116 dcerpc = DCERPCSession(credentials=credentials, verbose=True) 117 dcerpc.connect_ncacn_ip_tcp(target=target, port=port) 118 119 if dcerpc.session is not None: 120 dcerpc.bind(interface_uuid=uuid, interface_version=version) 121 if dcerpc.session is not None: 122 reporter.print_testing(msprotocol_rpc_instance) 123 124 result = trigger_and_catch_authentication( 125 options=options, 126 dcerpc_session=dcerpc.session, 127 target=target, 128 method_trigger_function=msprotocol_rpc_instance.trigger, 129 listenertype=listener_type, 130 listen_ip=listening_ip, 131 http_port=http_listen_port 132 ) 133 134 reporter.report_test_result( 135 uuid=uuid, version=version, namedpipe=namedpipe, 136 msprotocol_rpc_instance=msprotocol_rpc_instance, 137 result=result, 138 exploitpath=exploitpath 139 ) 140 141 if result == TestResult.NCA_S_UNK_IF: 142 stop_exploiting_this_function = True 143 144 if options.delay is not None: 145 # Sleep between attempts 146 time.sleep(options.delay) 147 else: 148 if options.verbose: 149 print(" [!] Cannot bind to interface (%s, %s)!" % (uuid, version)) 150 else: 151 if options.verbose: 152 print("[!] DCERPC port '\x1b[1;94m%d\x1b[0m' is \x1b[1;91mclosed\x1b[0m!" % port) 153 154 if "msrpc" in options.filter_transport_name: 155 ncan_np_tasks = tasks["ncan_np"] 156 for namedpipe in sorted(ncan_np_tasks.keys()): 157 if can_connect_to_pipe(target, namedpipe, credentials): 158 print("[+] SMB named pipe '\x1b[1;94m%s\x1b[0m' is \x1b[1;92maccessible\x1b[0m!" % namedpipe) 159 for uuid in sorted(ncan_np_tasks[namedpipe].keys()): 160 for version in sorted(ncan_np_tasks[namedpipe][uuid].keys()): 161 if can_bind_to_interface(target, namedpipe, credentials, uuid, version): 162 print(" [+] Successful bind to interface (%s, %s)!" % (uuid, version)) 163 for msprotocol_class in sorted(ncan_np_tasks[namedpipe][uuid][version], key=lambda x:x.function["name"]): 164 165 exploit_paths = msprotocol_class.generate_exploit_templates(desired_auth_type=options.auth_type) 166 167 stop_exploiting_this_function = False 168 for listener_type, exploitpath in exploit_paths: 169 if stop_exploiting_this_function == True: 170 # Got a nca_s_unk_if response, this function does not listen on the given interface 171 continue 172 if listener_type == "http": 173 http_listen_port = get_next_http_listener_port(current_value=http_listen_port, listen_ip=listening_ip, options=options) 174 175 exploitpath = generate_exploit_path_from_template( 176 template=exploitpath, 177 listener=listening_ip, 178 http_listen_port=options.http_port, 179 smb_listen_port=options.smb_port 180 ) 181 182 msprotocol_rpc_instance = msprotocol_class(path=exploitpath) 183 dcerpc = DCERPCSession(credentials=credentials, verbose=True) 184 dcerpc.connect_ncacn_np(target=target, pipe=namedpipe) 185 186 if dcerpc.session is not None: 187 dcerpc.bind(interface_uuid=uuid, interface_version=version) 188 if dcerpc.session is not None: 189 reporter.print_testing(msprotocol_rpc_instance) 190 191 result = trigger_and_catch_authentication( 192 options=options, 193 dcerpc_session=dcerpc.session, 194 target=target, 195 method_trigger_function=msprotocol_rpc_instance.trigger, 196 listenertype=listener_type, 197 listen_ip=listening_ip, 198 http_port=http_listen_port 199 ) 200 201 reporter.report_test_result( 202 uuid=uuid, version=version, namedpipe=namedpipe, 203 msprotocol_rpc_instance=msprotocol_rpc_instance, 204 result=result, 205 exploitpath=exploitpath 206 ) 207 208 if result == TestResult.NCA_S_UNK_IF: 209 stop_exploiting_this_function = True 210 211 if options.delay is not None: 212 # Sleep between attempts 213 time.sleep(options.delay) 214 else: 215 if options.verbose: 216 print(" [!] Cannot bind to interface (%s, %s)!" % (uuid, version)) 217 else: 218 if options.verbose: 219 print("[!] SMB named pipe '\x1b[1;94m%s\x1b[0m' is \x1b[1;91mnot accessible\x1b[0m!" % namedpipe)