async def do_taskregister(self, template_file, task_name = None): """Registers a new scheduled task""" try: with open(template_file, 'r') as f: template = f.read() res, err = await self.machine.tasks_register(template, task_name = task_name) if err is not None: logger.info('[!] Failed to register new task!') raise err return True, None except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) return None, e except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) return None, e except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) return None, e except Exception as e: traceback.print_exc() return None, e
async def check_service_status(self, service_name): if not self.handle: await self.open() if service_name not in self.service_handles: await self.open_service(service_name) # Let's check its status ans = await scmr.hRQueryServiceStatus( self.dce, self.service_handles[service_name]) if ans['lpServiceStatus']['dwCurrentState'] == scmr.SERVICE_STOPPED: logger.info('Service %s is in stopped state' % service_name) # Let's check its configuration if service is stopped, maybe it's disabled :s ans = await scmr.hRQueryServiceConfigW(self.__scmr, self.__serviceHandle) if ans['lpServiceConfig']['dwStartType'] == 0x4: logger.info('Service %s is disabled' % service_name) return SMBRemoteServiceStatus.DISABLED else: return SMBRemoteServiceStatus.STOPPED elif ans['lpServiceStatus']['dwCurrentState'] == scmr.SERVICE_RUNNING: logger.debug('Service %s is already running' % service_name) return SMBRemoteServiceStatus.RUNNING else: raise Exception('Unknown service state 0x%x - Aborting' % ans['CurrentState'])
async def listen(self): server = await asyncio.start_server(self.handle_client, self.ip, self.port) addr = server.sockets[0].getsockname() async with server: logger.info('TCP Server in listening state') await server.serve_forever() logger.info('TCP server terminated')
async def run(self): try: self.task_q = asyncio.Queue() self.target_gen_task = asyncio.create_task(self.__target_gen()) while True: t = await self.task_q.get() if t is None: return True, None tid, target = t unc = PureWindowsPath(target) file_name = unc.name print() connection = self.smb_mgr.create_connection_newtarget( target.replace('\\\\', '').split('\\')[0]) async with connection: _, err = await connection.login() if err is not None: raise err print(target) smbfile = SMBFile.from_uncpath(target) _, err = await smbfile.open(connection, 'r') if err is not None: logger.info('Error Downloading file %s' % target) continue if self.show_progress is True: pbar = tqdm.tqdm(desc='Downloading %s' % file_name, total=smbfile.size, unit='B', unit_scale=True, unit_divisor=1024) with open(file_name, 'wb') as f: async for data, err in smbfile.read_chunked(): if err is not None: logger.info('Error Downloading file %s' % target) continue if data is None: break f.write(data) if self.show_progress is True: pbar.update(len(data)) return True, None except Exception as e: return False, e
async def handle_client(self, reader, writer): raddr, rport = writer.get_extra_info('peername') logger.info('TCP client connected from %s:%s' % (raddr, rport)) client = TCPClient(raddr, rport, reader, writer) asyncio.ensure_future(self.handle_outgoing(client)) asyncio.ensure_future(self.handle_incoming(client)) nbtransport = NetBIOSTransport(client) server = SMBServerConnection(copy.deepcopy(self.server_settings), nbtransport) await nbtransport.run() await server.run() logger.info('SMB server terminated, closing client! %s:%s' % (raddr, rport))
async def main(self): logger.info('SMB Server starting') logger.info('SMB Server creating NB transport reader task') asyncio.ensure_future(self.__handle_smb_in()) logger.info('SMB Server running') while True: if self.status == SMBConnectionStatus.NEGOTIATING: await self.negotiate() if self.status == SMBConnectionStatus.SESSIONSETUP: await self.session_setup() else: raise Exception('Not implemented!')
async def connect(self): """ Main function to be called, connects to the target specified in target, and starts reading/writing. """ con = asyncio.open_connection(self.target.proxy.ip, self.target.proxy.port) try: self.proxy_reader, self.proxy_writer = await asyncio.wait_for( con, int(self.target.proxy.timeout)) except asyncio.TimeoutError: logger.debug('[Socks5Proxy] Proxy Connection timeout') raise SMBConnectionTimeoutException() except ConnectionRefusedError: logger.debug('[Socks5Proxy] Proxy Connection refused') raise SMBConnectionRefusedException() except asyncio.CancelledError: #the SMB connection is terminating raise asyncio.CancelledError except Exception as e: logger.debug('[Socks5Proxy] connect generic exception') raise e #logger.info('Establishing proxy connection %s => %s' % (server.get_paddr(), target.get_paddr())) authmethods = [SOCKS5Method.NOAUTH] if self.target.proxy.username is not None: authmethods.append(SOCKS5Method.PLAIN) #logger.debug('Sending negotiation command to %s:%d' % proxy_writer.get_extra_info('peername')) self.proxy_writer.write(SOCKS5Nego.construct(authmethods).to_bytes()) await asyncio.wait_for(self.proxy_writer.drain(), timeout=int(self.target.proxy.timeout)) rep_nego = await asyncio.wait_for( SOCKS5NegoReply.from_streamreader(self.proxy_reader), timeout=int(self.target.proxy.timeout)) logger.debug( 'Got negotiation reply from %s: %s' % (self.proxy_writer.get_extra_info('peername'), repr(rep_nego))) if rep_nego.METHOD == SOCKS5Method.PLAIN: logger.debug('Preforming plaintext auth to %s:%d' % self.proxy_writer.get_extra_info('peername')) self.proxy_writer.write( SOCKS5PlainAuth.construct(self.target.proxy.username, self.target.proxy.secret).to_bytes()) await asyncio.wait_for(self.proxy_writer.drain(), timeout=int(self.target.proxy.timeout)) rep_auth_nego = await asyncio.wait_for( SOCKS5NegoReply.from_streamreader(self.proxy_reader), timeout=int(self.target.proxy.timeout)) if rep_auth_nego.METHOD != SOCKS5Method.NOAUTH: raise Exception( 'Failed to connect to proxy %s:%d! Authentication failed!' % self.proxy_writer.get_extra_info('peername')) logger.debug('Sending connect request to %s:%d' % self.proxy_writer.get_extra_info('peername')) self.proxy_writer.write( SOCKS5Request.construct(SOCKS5Command.CONNECT, self.target.get_hostname_or_ip(), self.target.port).to_bytes()) await asyncio.wait_for(self.proxy_writer.drain(), timeout=int(self.target.proxy.timeout)) rep = await asyncio.wait_for(SOCKS5Reply.from_streamreader( self.proxy_reader), timeout=int(self.target.proxy.timeout)) if rep.REP != SOCKS5ReplyType.SUCCEEDED: logger.info( 'Failed to connect to proxy %s! Server replied: %s' % (self.proxy_writer.get_extra_info('peername'), repr(rep.REP))) raise Exception('Authentication failure!') logger.debug('Server reply from %s : %s' % (self.proxy_writer.get_extra_info('peername'), repr(rep))) if rep.BIND_ADDR == ipaddress.IPv6Address( '::') or rep.BIND_ADDR == ipaddress.IPv4Address( '0.0.0.0' ) or rep.BIND_PORT == self.proxy_writer.get_extra_info( 'peername')[1]: logger.debug('Same socket can be used now on %s:%d' % (self.proxy_writer.get_extra_info('peername'))) #this means that the communication can continue on the same socket! logger.info('Proxy connection succeeded') self.reader = self.proxy_reader self.writer = self.proxy_writer else: #this case, the server created the socket, but expects a second connection to a different ip/port con = asyncio.open_connection(str(rep.BIND_ADDR), rep.BIND_PORT) try: self.reader, self.writer = await asyncio.wait_for( con, int(self.target.proxy.timeout)) except asyncio.TimeoutError: logger.debug('[Socks5Proxy] Proxy Connection timeout') raise SMBConnectionTimeoutException() except ConnectionRefusedError: logger.debug('[Socks5Proxy] Proxy Connection refused') raise SMBConnectionRefusedException() except asyncio.CancelledError: #the SMB connection is terminating raise asyncio.CancelledError except Exception as e: logger.debug('[Socks5Proxy] connect generic exception') raise e self.incoming_task = asyncio.create_task(self.handle_incoming()) self.outgoing_task = asyncio.create_task(self.handle_outgoing()) return
async def amain(): import argparse import sys import logging parser = argparse.ArgumentParser( description='Registry manipulation via SMB') SMBConnectionParams.extend_parser(parser) parser.add_argument('-v', '--verbose', action='count', default=0) parser.add_argument( 'url', help= 'Connection URL base, target can be set to anything. Owerrides all parameter based connection settings! Example: "smb2+ntlm-password://TEST\\victim@test"' ) parser.add_argument( 'commands', nargs='*', help= 'Commands in the following format: "r:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest:Negotiate"' ) args = parser.parse_args() if args.verbose >= 1: logger.setLevel(logging.DEBUG) if args.verbose > 2: print('setting deepdebug') logger.setLevel(1) #enabling deep debug asyncio.get_event_loop().set_debug(True) logging.basicConfig(level=logging.DEBUG) commands = [] smb_url = None if args.url is not None: smb_url = args.url else: try: smb_url = SMBConnectionParams.parse_args(args) except Exception as e: print( 'Either URL or all connection parameters must be set! Error: %s' % str(e)) sys.exit(1) #pre-parsing commands for cmd in args.commands: c, path = cmd.split(':', 1) c = SMBREG_COMMAND(c.upper()) commands.append((c, path)) connection = SMBConnectionURL(smb_url).get_connection() _, err = await connection.login() if err is not None: print('Login failed! Reason: %s' % str(err)) return machine = SMBMachine(connection) #async for srv, err in machine.list_services(): # if err is not None: # print(err) # return # print(srv) registry_srv_status, err = await machine.check_service_status( "RemoteRegistry") if err is not None: print('Check service status error! %s' % err) return if registry_srv_status != SMBServiceStatus.RUNNING: logger.info('RemoteRegistry is not running! Starting it now..') res, err = await machine.enable_service("RemoteRegistry") if err is not None: print(err) return await asyncio.sleep(5) #waiting for service to start up reg_api, err = await machine.get_regapi() if err is not None: print(err) return ## do stuff for cmd, target in commands: if cmd == SMBREG_COMMAND.READ: regpath, name = target.split(':', 1) hkey, err = await reg_api.OpenRegPath(regpath) if err is not None: print(err) continue val_type, value, err = await reg_api.QueryValue(hkey, name) if err is not None: print(err) continue print(value) elif cmd == SMBREG_COMMAND.ENUMVALUE: hkey, err = await reg_api.OpenRegPath(target) if err is not None: print(err) continue i = 0 while True: value_name, value_type, value_data, err = await reg_api.EnumValue( hkey, i) i += 1 if err is not None: print(err) break print(value_name) print(value_type) print(value_data) elif cmd == SMBREG_COMMAND.ENUMKEY: hkey, err = await reg_api.OpenRegPath(target) if err is not None: print(err) continue i = 0 while True: res, err = await reg_api.EnumKey(hkey, i) i += 1 if err is not None: print(err) break print(res)