Esempio n. 1
0
	async def scan_host(self, target):
		try:
			#spneg = AuthenticatorBuilder.to_spnego_cred(self.credential, target)
			connection = self.smb_mgr.create_connection_newtarget(target)
			async with connection:
				await connection.login()
				machine = SMBMachine(connection)

				if 'all' in self.gather or 'shares' in self.gather:
					async for smbshare, err in machine.list_shares():
						if err is not None:
							await self.out_q.coro_put((connection.target, None, 'Failed to list shares. Reason: %s' % format_exc(err)))
							continue
						share = NetShare()
						share.ip = connection.target.get_ip()
						share.netname = smbshare.name
						share.type = smbshare.type
						share.remark = smbshare.remark

						await self.out_q.coro_put((connection.target, share, None))
					
				
				if 'all' in self.gather or 'sessions' in self.gather:
					async for session, err in machine.list_sessions():
						if err is not None:
							await self.out_q.coro_put((connection.target, None, 'Failed to get sessions. Reason: %s' % format_exc(err)))
							continue

						sess = NetSession()
						sess.source = connection.target.get_ip()
						sess.ip = session.ip_addr.replace('\\','').strip()
						sess.username = session.username

						await self.out_q.coro_put((connection.target, sess, None))

				if 'all' in self.gather or 'localgroups' in self.gather:
					for group_name in self.localgroups:
						async for domain_name, user_name, sid, err in machine.list_group_members(domain_name, group_name):
							if err is not None:
								await self.out_q.coro_put((connection.target, None, 'Failed to connect to poll group memeberships. Reason: %s' % format_exc(err)))
								continue

							lg = LocalGroup()
							lg.ip = connection.target.get_ip()
							lg.hostname = connection.target.get_hostname()
							lg.sid = sid
							lg.groupname = group_name
							lg.domain = domain_name
							lg.username = user_name
							await self.out_q.coro_put((connection.target, lg, None))
		
		except Exception as e:
			await self.out_q.coro_put((connection.target, None, 'Failed to connect to host. Reason: %s' % format_exc(e)))
			return

		finally:
			await self.out_q.coro_put((connection.target, None, None)) #target finished
Esempio n. 2
0
    async def scan_host(self, atarget):
        try:
            tid, target = atarget
            #spneg = AuthenticatorBuilder.to_spnego_cred(self.credential, target)
            connection = self.smb_mgr.create_connection_newtarget(target)
            async with connection:
                await connection.login()

                extra_info = connection.get_extra_info()
                if extra_info is not None:
                    try:
                        f = SMBFinger.from_extra_info(tid, extra_info)
                        await self.out_q.put((tid, connection.target, f, None))
                    except:
                        traceback.print_exc()

                machine = SMBMachine(connection)

                if 'all' in self.gather or 'shares' in self.gather:
                    async for smbshare, err in machine.list_shares():
                        if err is not None:
                            await self.out_q.put(
                                (tid, connection.target, None,
                                 'Failed to list shares. Reason: %s' %
                                 format_exc(err)))
                            continue
                        share = NetShare()
                        share.machine_sid = tid
                        share.ip = connection.target.get_ip()
                        share.netname = smbshare.name
                        share.type = smbshare.type
                        r = None
                        try:
                            r = smbshare.remark.decode()
                        except:
                            r = smbshare.remark
                        share.remark = r

                        await self.out_q.put(
                            (tid, connection.target, share, None))

                if 'all' in self.gather or 'sessions' in self.gather:
                    async for session, err in machine.list_sessions():
                        if err is not None:
                            await self.out_q.put(
                                (tid, connection.target, None,
                                 'Failed to get sessions. Reason: %s' %
                                 format_exc(err)))
                            continue

                        sess = NetSession()
                        sess.machine_sid = tid
                        sess.source = connection.target.get_ip()
                        sess.ip = session.ip_addr.replace('\\', '').strip()
                        sess.username = session.username

                        await self.out_q.put(
                            (tid, connection.target, sess, None))

                if 'all' in self.gather or 'localgroups' in self.gather:
                    for group_name in self.localgroups:
                        async for domain_name, user_name, sid, err in machine.list_group_members(
                                'Builtin', group_name):
                            if err is not None:
                                await self.out_q.put((
                                    tid, connection.target, None,
                                    'Failed to connect to poll group memeberships. Reason: %s'
                                    % format_exc(err)))
                                continue

                            lg = LocalGroup()
                            lg.machine_sid = tid
                            lg.ip = connection.target.get_ip()
                            lg.hostname = connection.target.get_hostname()
                            lg.sid = sid
                            lg.groupname = group_name
                            lg.domain = domain_name
                            lg.username = user_name
                            await self.out_q.put(
                                (tid, connection.target, lg, None))

        except asyncio.CancelledError:
            return

        except Exception as e:
            await self.out_q.put(
                (tid, connection.target, None,
                 'Failed to connect to host. Reason: %s' % format_exc(e)))
            return

        finally:
            await self.out_q.put(
                (tid, connection.target, None, None))  #target finished
Esempio n. 3
0
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
Esempio n. 4
0
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()
Esempio n. 5
0
    async def scan_host(self, atarget):
        try:
            tid, target = atarget

            try:
                if 'all' in self.gather or 'protocols' in self.gather:
                    for protocol in self.protocols:
                        connection = self.smb_mgr.create_connection_newtarget(
                            target)
                        res, _, _, _, err = await connection.protocol_test(
                            [protocol])
                        if err is not None:
                            raise err
                        if res is True:
                            pr = SMBProtocols()
                            pr.machine_sid = tid
                            pr.protocol = protocol.name if protocol != NegotiateDialects.WILDCARD else 'SMB1'
                            await self.out_q.put(
                                (tid, connection.target, pr, None))
            except Exception as e:
                await self.out_q.put(
                    (tid, connection.target, None,
                     'Failed to enumerate supported protocols. Reason: %s' %
                     format_exc(e)))

            connection = self.smb_mgr.create_connection_newtarget(target)
            async with connection:
                _, err = await connection.login()
                if err is not None:
                    raise err

                try:
                    extra_info = connection.get_extra_info()
                    if extra_info is not None:
                        f = SMBFinger.from_extra_info(tid, extra_info)
                        await self.out_q.put((tid, connection.target, f, None))
                except Exception as e:
                    await self.out_q.put(
                        (tid, connection.target, None,
                         'Failed to get finger data. Reason: %s' %
                         format_exc(e)))

                machine = SMBMachine(connection)

                if 'all' in self.gather or 'shares' in self.gather:
                    async for smbshare, err in machine.list_shares():
                        if err is not None:
                            await self.out_q.put(
                                (tid, connection.target, None,
                                 'Failed to list shares. Reason: %s' %
                                 format_exc(err)))
                            break
                        else:
                            share = NetShare()
                            share.machine_sid = tid
                            share.ip = connection.target.get_ip()
                            share.netname = smbshare.name
                            share.type = smbshare.type
                            #share.remark = smbshare.remark
                            #if smbshare.remark is not None:
                            #	r = None
                            #	try:
                            #		r = smbshare.remark.decode('utf-16-le')
                            #	except:
                            #		try:
                            #			r = smbshare.remark.decode('latin-1')
                            #		except:
                            #			try:
                            #				r = smbshare.remark.decode('utf-8')
                            #			except:
                            #				r = smbshare.remark
                            #
                            #	if isinstance(r, str):
                            #		r = r.replace('\x00','')
                            #		share.remark = r

                            await self.out_q.put(
                                (tid, connection.target, share, None))

                if 'all' in self.gather or 'sessions' in self.gather:
                    async for session, err in machine.list_sessions():
                        if err is not None:
                            await self.out_q.put(
                                (tid, connection.target, None,
                                 'Failed to get sessions. Reason: %s' %
                                 format_exc(err)))
                            break
                        else:
                            try:
                                sess = NetSession()
                                sess.machine_sid = tid
                                sess.source = connection.target.get_ip()
                                sess.ip = session.ip_addr.replace('\\',
                                                                  '').strip()
                                sess.username = session.username

                                await self.out_q.put(
                                    (tid, connection.target, sess, None))
                            except Exception as e:
                                await self.out_q.put(
                                    (tid, connection.target, None,
                                     'Failed to format session. Reason: %s' %
                                     format_exc(e)))

                if 'all' in self.gather or 'localgroups' in self.gather:
                    for group_name in self.localgroups:
                        async for domain_name, user_name, sid, err in machine.list_group_members(
                                'Builtin', group_name):
                            if err is not None:
                                await self.out_q.put((
                                    tid, connection.target, None,
                                    'Failed to connect to poll group memeberships. Reason: %s'
                                    % format_exc(err)))
                                break
                            else:
                                lg = LocalGroup()
                                lg.machine_sid = tid
                                lg.ip = connection.target.get_ip()
                                lg.hostname = connection.target.get_hostname()
                                lg.sid = sid
                                lg.groupname = group_name
                                lg.domain = domain_name
                                lg.username = user_name
                                await self.out_q.put(
                                    (tid, connection.target, lg, None))

        except asyncio.CancelledError:
            return

        except Exception as e:
            await self.out_q.put(
                (tid, connection.target, None,
                 'Failed to connect to host. Reason: %s' % format_exc(e)))
            return

        finally:
            await self.out_q.put(
                (tid, connection.target, None, None))  #target finished
Esempio n. 6
0
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()
Esempio n. 7
0
    async def scan_host(self, atarget):
        try:
            tid, target = atarget
            connection = self.smb_mgr.create_connection_newtarget(target)
            async with connection:
                _, err = await connection.login()
                if err is not None:
                    raise err

                machine = SMBMachine(connection)

                if 'all' in self.gather or 'shares' in self.gather:
                    async for smbshare, err in machine.list_shares():
                        if err is not None:
                            await self.out_q.put(
                                (tid, connection.target, None,
                                 'Failed to list shares. Reason: %s' %
                                 format_exc(err)))
                            break
                        else:
                            share = NetShare()
                            share.machine_sid = tid
                            share.ip = connection.target.get_ip()
                            share.netname = smbshare.name
                            share.type = smbshare.type
                            await self.out_q.put(
                                (tid, connection.target, share, None))

                if 'all' in self.gather or 'sessions' in self.gather:
                    async for session, err in machine.list_sessions():
                        if err is not None:
                            await self.out_q.put(
                                (tid, connection.target, None,
                                 'Failed to get sessions. Reason: %s' %
                                 format_exc(err)))
                            break
                        else:
                            try:
                                sess = NetSession()
                                sess.machine_sid = tid
                                sess.source = connection.target.get_ip()
                                sess.ip = session.ip_addr.replace('\\',
                                                                  '').strip()
                                sess.username = session.username

                                await self.out_q.put(
                                    (tid, connection.target, sess, None))
                            except Exception as e:
                                await self.out_q.put(
                                    (tid, connection.target, None,
                                     'Failed to format session. Reason: %s' %
                                     format_exc(e)))
                if 'all' in self.gather or 'localgroups' in self.gather:
                    for group_name in self.localgroups:
                        async for domain_name, user_name, sid, err in machine.list_group_members(
                                'Builtin', group_name):
                            if err is not None:
                                await self.out_q.put((
                                    tid, connection.target, None,
                                    'Failed to poll group memeberships. Reason: %s'
                                    % format_exc(err)))
                                break
                            else:
                                lg = LocalGroup()
                                lg.machine_sid = tid
                                lg.ip = connection.target.get_ip()
                                lg.hostname = connection.target.get_hostname()
                                lg.sid = sid
                                lg.groupname = group_name
                                lg.domain = domain_name
                                lg.username = user_name
                                await self.out_q.put(
                                    (tid, connection.target, lg, None))

                if 'all' in self.gather or 'regsessions' in self.gather:
                    users, err = await machine.reg_list_users()
                    if err is not None:
                        await self.out_q.put(
                            (tid, connection.target, None,
                             'Failed to get sessions. Reason: %s' %
                             format_exc(err)))

                    else:
                        try:
                            for usersid in users:
                                if usersid in self.regusers_filter:
                                    continue
                                if usersid.find('_') != -1:
                                    continue
                                sess = RegSession()
                                sess.machine_sid = tid
                                sess.user_sid = usersid

                                await self.out_q.put(
                                    (tid, connection.target, sess, None))
                        except Exception as e:
                            await self.out_q.put(
                                (tid, connection.target, None,
                                 'Failed to format session. Reason: %s' %
                                 format_exc(e)))

                if 'all' in self.gather or 'interfaces' in self.gather:
                    interfaces, err = await machine.list_interfaces()
                    if err is not None:
                        await self.out_q.put(
                            (tid, connection.target, None,
                             'Failed to get interfaces. Reason: %s' %
                             format_exc(err)))

                    else:
                        try:
                            for interface in interfaces:
                                iface = SMBInterface()
                                iface.machine_sid = tid
                                iface.address = interface['address']

                                await self.out_q.put(
                                    (tid, connection.target, iface, None))
                        except Exception as e:
                            await self.out_q.put(
                                (tid, connection.target, None,
                                 'Failed to format interface. Reason: %s' %
                                 format_exc(e)))

                if 'all' in self.gather or 'share_1' in self.gather:
                    ctr = self.share_max_files
                    maxerr = 10
                    async for obj, otype, err in machine.enum_all_recursively(
                            depth=1, fetch_share_sd=False, fetch_dir_sd=True):
                        otype = otype.lower()
                        ctr -= 1
                        if ctr == 0:
                            break

                        if err is not None:
                            await self.out_q.put((
                                tid, connection.target, None,
                                'Failed to perform first-level file enum. Reason: %s'
                                % format_exc(err)))
                            break

                        else:
                            try:
                                if otype == 'share':
                                    continue
                                if otype in ['file', 'dir']:
                                    sf = SMBFile()
                                    sf.machine_sid = tid
                                    sf.unc = obj.unc_path
                                    sf.otype = otype
                                    sf.creation_time = obj.creation_time
                                    sf.last_access_time = obj.last_access_time
                                    sf.last_write_time = obj.last_write_time
                                    sf.change_time = obj.change_time
                                    if obj.security_descriptor is not None and obj.security_descriptor != '':
                                        sf.sddl = obj.security_descriptor.to_sddl(
                                        )
                                    if otype == 'file':
                                        sf.size = obj.size
                                        sf.size_ext = sizeof_fmt(sf.size)

                                    await self.out_q.put(
                                        (tid, connection.target, sf, None))
                            except Exception as e:
                                maxerr -= 1
                                await self.out_q.put(
                                    (tid, connection.target, None,
                                     'Failed to format file result. Reason: %s'
                                     % format_exc(e)))
                                if maxerr == 0:
                                    await self.out_q.put((
                                        tid, connection.target, None,
                                        'File Results too many errors. Reason: %s'
                                        % format_exc(e)))
                                    break

            try:
                if 'all' in self.gather or 'finger' in self.gather:
                    connection = self.smb_mgr.create_connection_newtarget(
                        target)
                    extra_info, err = await connection.fake_login()
                    if extra_info is not None:
                        f = SMBFinger.from_fake_login(tid,
                                                      extra_info.to_dict())
                        await self.out_q.put((tid, connection.target, f, None))
            except Exception as e:
                await self.out_q.put(
                    (tid, connection.target, None,
                     'Failed to get finger data. Reason: %s' % format_exc(e)))

            try:
                if 'all' in self.gather or 'protocols' in self.gather:
                    for protocol in self.protocols:
                        connection = self.smb_mgr.create_connection_newtarget(
                            target)
                        res, _, _, _, err = await connection.protocol_test(
                            [protocol])
                        if err is not None:
                            raise err
                        if res is True:
                            pr = SMBProtocols()
                            pr.machine_sid = tid
                            pr.protocol = protocol.name if protocol != NegotiateDialects.WILDCARD else 'SMB1'
                            await self.out_q.put(
                                (tid, connection.target, pr, None))
            except Exception as e:
                await self.out_q.put(
                    (tid, connection.target, None,
                     'Failed to enumerate supported protocols. Reason: %s' %
                     format_exc(e)))

        except asyncio.CancelledError:
            return

        except Exception as e:
            await self.out_q.put(
                (tid, connection.target, None,
                 'Failed to connect to host. Reason: %s' % format_exc(e)))
            return

        finally:
            await self.out_q.put(
                (tid, connection.target, None, None))  #target finished