async def open(self, filename, mode = 'r'): self.mode = mode if 'p' in self.mode: self.is_pipe = True if isinstance(filename, str): #then it's a string path, we need to create an SMBFile if filename.startswith('\\\\') != True: raise Exception('Filename as a string MUST be in \\\\<server>\\<share>\\....\\file format!') server_name, t , file_path = filename[2:].split('\\',2) share_name = '\\\\' + server_name + '\\' + t self.share = SMBShare() self.share.fullpath = share_name self.file = SMBFile() self.file.parent_share = self.share self.fullpath = file_path elif isinstance(filename, SMBFile): #this arrived from somewhere else if filename.parent_share.fullpath is None: raise Exception('Parent share MUST be speicfied if open is called with SMBFile object as filename!') #otherwise noone knows the treeid to connect to... self.share = SMBShare() self.share.fullpath = filename.parent_share.fullpath self.file = SMBFile() self.file.fullpath = filename.fullpath else: raise Exception('Filename MUST be either SMBFile or a full path string to the file') #first, connecting to the share. we create a new treeid regardless of it already exists one for this share or not await self.__connect_share(self.share) #then connect to file if 'r' in mode and 'w' in mode: raise ValueError('must have exactly one of read/write mode') if 'r' in mode: desired_access = FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_READ_ATTRIBUTES share_mode = ShareAccess.FILE_SHARE_READ create_options = CreateOptions.FILE_NON_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT file_attrs = 0 create_disposition = CreateDisposition.FILE_OPEN self.file.file_id, smb_reply = await self.connection.create(self.share.tree_id, self.fullpath, desired_access, share_mode, create_options, create_disposition, file_attrs, return_reply = True) self.file.size = smb_reply.EndofFile elif 'w' in mode: desired_access = FileAccessMask.GENERIC_READ | FileAccessMask.GENERIC_WRITE share_mode = ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE create_options = CreateOptions.FILE_NON_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT file_attrs = 0 create_disposition = CreateDisposition.FILE_OPEN_IF #FILE_OPEN ? might cause an issue? self.file.file_id, smb_reply = await self.connection.create(self.share.tree_id, self.fullpath, desired_access, share_mode, create_options, create_disposition, file_attrs, return_reply = True) self.file.size = smb_reply.EndofFile else: raise Exception('ONLY read and write is supported at the moment!')
async def __executor(self, tid, target): try: connection = self.smb_mgr.create_connection_newtarget(target) async with connection: _, err = await connection.login() if err is not None: raise err res = EnumResult(tid, target) share = SMBShare( name = 'ADMIN$', fullpath = '\\\\%s\\%s' % (connection.target.get_hostname_or_ip(), 'ADMIN$') ) _, err = await share.connect(connection) res.share = True if err is None else False rrp = RRP(connection) _, err = await rrp.connect() res.registry = True if err is None else False srvmgr = SMBRemoteServieManager(connection) _, err = await srvmgr.connect() res.servicemgr = True if err is None else False await self.res_q.put(res) except asyncio.CancelledError: return except Exception as e: await self.res_q.put(EnumResult(tid, target, error = e, status = EnumResultStatus.ERROR)) finally: await self.res_q.put(EnumResult(tid, target, status = EnumResultStatus.FINISHED))
def generate_targets(self): session = get_session(self.db_conn) qry = session.query( JackDawADMachine.sAMAccountName, NetShare.id, NetShare.netname).filter( JackDawADMachine.ad_id == self.settings_base.ad_id).filter( JackDawADMachine.id == NetShare.machine_id) for mname, shareid, sharename in qry.all(): if sharename in self.exclude_shares: continue target = mname if mname[-1] != '$' else mname[:-1] fullpath = '\\\\%s\\%s' % (target, sharename) smbshare = SMBShare(fullpath=fullpath) #print(target) #print(fullpath) #print(smbshare) settings = copy.deepcopy(self.settings_base) settings.share_id = shareid settings.target = target settings.share = smbshare self.in_q.put((SMBShareGathererCmd.START, settings)) session.close() self.in_q.put((SMBShareGathererCmd.END, None))
async def list_shares(self): async for name, share_type, remark, _ in rr_gen(self.srvs.list_shares()): share = SMBShare( name = name, stype = share_type, remark = remark, fullpath = '\\\\%s\\%s' % (self.connection.target.get_hostname_or_ip(), name) ) #self.shares.append(share) yield share, None
async def list_shares(self): try: async for name, share_type, remark, err in self.srvs.list_shares(): if err is not None: yield None, err return share = SMBShare( name=name, stype=share_type, remark=remark, fullpath='\\\\%s\\%s' % (self.connection.target.get_hostname_or_ip(), name)) yield share, None except Exception as e: yield None, e
async def do_use(self, share_name): """selects share to be used""" try: if self.is_anon is False: #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 list_shares(self, fetch_share_sd=False): try: _, err = await self.connect_rpc('SRVS') if err is not None: raise err async for name, share_type, remark, err in self.named_rpcs[ 'SRVS'].list_shares(): if err is not None: yield None, err return share = SMBShare( name=name, stype=share_type, remark=remark, fullpath='\\\\%s\\%s' % (self.connection.target.get_hostname_or_ip(), name)) if fetch_share_sd is True: await share.get_security_descriptor(self.connection) yield share, None except Exception as e: yield None, e