Esempio n. 1
0
    async def handle_incoming(self):
        """
		Reads data bytes from the socket and dispatches it to the incoming queue
		"""
        try:
            while not self.disconnected.is_set(
            ) or not self.shutdown_evt.is_set():
                try:
                    msg_data = b''
                    data = await self.reader.readexactly(24)
                    msg_data += data
                    response_header = MSRPCRespHeader(msg_data)

                    data = await self.reader.readexactly(
                        response_header['frag_len'] - 24)
                    msg_data += data
                    await self.in_queue.put((msg_data, None))
                except Exception as e:
                    await self.in_queue.put((None, e))
                    return

        except asyncio.CancelledError:
            #the SMB connection is terminating
            return

        except Exception as e:
            logger.exception('[DCERPCTCPConnection] handle_incoming %s' %
                             str(e))
            await self.in_queue.put((None, e))
            await self.disconnect()
Esempio n. 2
0
	async def handle_outgoing(self):
		"""
		Reads SMBv1/2 outgoing message data bytes from out_queue, wraps them in NetBIOS object, then serializes them, then sends them to socket_out_queue
		"""
		try:
			while True:
				smb_msg_data = await self.out_queue.get()
				if smb_msg_data is None:
					return
				data  = b'\x00'
				data += len(smb_msg_data).to_bytes(3, byteorder='big', signed = False)
				data += smb_msg_data
				await self.socket_out_queue.put(data)
		
		except asyncio.CancelledError:
			#the SMB connection is terminating
			return
		
		except Exception as e:
			logger.exception('NetBIOSTransport handle_outgoing')
			await self.stop()
		
		finally:
			await self.stop()
			self.out_task_finished.set()
			
Esempio n. 3
0
    async def __handle_incoming(self):
        try:
            data = b''
            while True:
                x, err = await self.connection.in_queue.get()
                if err is not None:
                    raise err
                data += x
                if len(data) >= 24:  #MSRPCRespHeader._SIZE
                    response_header = MSRPCRespHeader(data)
                    while len(data) < response_header['frag_len']:
                        x, err = await self.connection.in_queue.get()
                        if err is not None:
                            raise err
                        data += x

                    response_data = data[:response_header['frag_len']]
                    data = data[response_header['frag_len']:]

                    await self.msg_in_queue.put(response_data)

        except asyncio.CancelledError:
            self.exception_evt.set()
            return
        except Exception as e:
            logger.exception('__handle_incoming')
            self.exception_evt.set()
            return
Esempio n. 4
0
    async def worker(self):
        try:
            while True:
                indata = await self.task_q.get()
                if indata is None:
                    return

                tid, target = indata
                try:
                    await asyncio.wait_for(self.__executor(tid, target),
                                           timeout=self.max_runtime)
                except asyncio.CancelledError:
                    return
                except asyncio.TimeoutError as e:
                    await self.res_q.put(
                        EnumResult(tid,
                                   target,
                                   None,
                                   error=e,
                                   status=EnumResultStatus.ERROR))
                    await self.res_q.put(
                        EnumResult(tid,
                                   target,
                                   None,
                                   status=EnumResultStatus.FINISHED))
                    continue
                except Exception as e:
                    logger.exception('worker')
                    continue
        except asyncio.CancelledError:
            return

        except Exception as e:
            return e
Esempio n. 5
0
    async def dcsync(self, target_domain=None, target_users=[]):

        if target_domain is None:
            logger.debug('No domain defined, fetching it from SAMR')

            logger.debug('Fetching domains...')
            async for domain in self.samr.list_domains():
                if domain == 'Builtin':
                    continue
                if target_domain is None:  #using th first available
                    target_domain = domain
                    logger.debug('Domain available: %s' % domain)

        async with SMBDRSUAPI(self.connection, target_domain) as drsuapi:
            try:
                await drsuapi.connect()
                await drsuapi.open()
            except Exception as e:
                logger.exception('Failed to connect to DRSUAPI!')
                raise e

            logger.debug('Using domain: %s' % target_domain)
            if len(target_users) > 0:
                for username in target_users:
                    secrets = await drsuapi.get_user_secrets(username)
                    yield secrets

            else:
                domain_sid = await self.samr.get_domain_sid(target_domain)
                domain_handle = await self.samr.open_domain(domain_sid)
                async for username, user_sid in self.samr.list_domain_users(
                        domain_handle):
                    secrets = await drsuapi.get_user_secrets(username)
                    yield secrets
Esempio n. 6
0
    async def connect(self):
        """
		Main function to be called, connects to the target specified in settings, and starts reading/writing.
		"""

        #self.settings = settings

        con = asyncio.open_connection(self.settings.get_ip(),
                                      self.settings.get_port())

        try:
            self.reader, self.writer = await asyncio.wait_for(
                con, int(self.settings.timeout))
        except asyncio.TimeoutError:
            logger.debug('[TCPSocket] Connection timeout')
            raise SMBConnectionTimeoutException()

        except ConnectionRefusedError:
            logger.debug('[TCPSocket] Connection refused')
            raise SMBConnectionRefusedException()

        except asyncio.CancelledError:
            #the SMB connection is terminating
            raise asyncio.CancelledError

        except Exception as e:
            logger.exception('[TCPSocket] connect generic exception')
            raise e

        self.incoming_task = asyncio.create_task(self.handle_incoming())
        self.outgoing_task = asyncio.create_task(self.handle_outgoing())

        return
Esempio n. 7
0
    async def handle_incoming(self):
        """
		Reads data bytes from the socket and dispatches it to the incoming queue
		"""
        try:
            lasterror = None
            while not self.disconnected.is_set():
                try:
                    data = await self.reader.read(10240)
                    await self.in_queue.put((data, None))

                except asyncio.CancelledError as e:
                    lasterror = e
                    break
                except Exception as e:
                    logger.exception('[TCPSocket] handle_incoming %s' % str(e))
                    lasterror = e
                    break

        except asyncio.CancelledError:
            return

        except Exception as e:
            lasterror = e

        finally:
            if self.in_queue is not None:
                await self.in_queue.put((None, lasterror))
            await self.disconnect()
Esempio n. 8
0
    async def dcsync(self, target_domain=None, target_users=[]):
        try:
            if isinstance(target_users, str):
                target_users = [target_users]
            if self.samr is None:
                await self.connect_rpc('SAMR')

            if target_domain is None:
                logger.debug('No domain defined, fetching it from SAMR')

                logger.debug('Fetching domains...')
                async for domain, err in self.samr.list_domains():
                    if err is not None:
                        raise err
                    if domain == 'Builtin':
                        continue
                    if target_domain is None:  #using th first available
                        target_domain = domain
                        logger.debug('Domain available: %s' % domain)

            async with SMBDRSUAPI(self.connection, target_domain) as drsuapi:
                try:
                    _, err = await drsuapi.connect()
                    if err is not None:
                        raise err
                    _, err = await drsuapi.open()
                    if err is not None:
                        raise err
                except Exception as e:
                    logger.exception('Failed to connect to DRSUAPI!')
                    raise e

                logger.debug('Using domain: %s' % target_domain)
                if len(target_users) > 0:
                    for username in target_users:
                        secrets, err = await drsuapi.get_user_secrets(username)
                        yield secrets, err

                else:

                    domain_sid, _ = await self.samr.get_domain_sid(
                        target_domain)
                    domain_handle, _ = await self.samr.open_domain(domain_sid)
                    async for username, user_sid, err in self.samr.list_domain_users(
                            domain_handle):
                        if err is not None:
                            yield None, err
                            return
                        logger.debug('username: %s' % username)
                        secrets, err = await drsuapi.get_user_secrets(username)
                        if err is not None:
                            yield None, err
                            return
                        logger.debug('secrets: %s' % secrets)
                        yield secrets, None

        except Exception as e:
            yield None, e
            return
Esempio n. 9
0
    async def __handle_smb_in(self):
        """
		Waits from SMB messages from the NetBIOSTransport in_queue, and fills the connection table.
		This function started automatically when calling connect.
		"""
        try:
            while True:
                msg, err = await self.netbios_transport.in_queue.get()
                self.activity_at = datetime.datetime.utcnow()
                if err is not None:
                    logger.error(
                        '__handle_smb_in got error from transport layer %s' %
                        err)
                    #setting all outstanding events to finished
                    for mid in self.OutstandingResponsesEvent:
                        self.OutstandingResponses[mid] = None
                        self.OutstandingResponsesEvent[mid].set()

                    await self.terminate()
                    return

                logger.log(
                    1, '__handle_smb_in got new message with Id %s' %
                    msg.header.MessageId)

                if isinstance(msg, SMB2Transform):
                    #message is encrypted
                    #this point we should decrypt it and only store the decrypted part in the OutstandingResponses table
                    #but for now we just thropw exception bc encryption is not implemented
                    raise Exception(
                        'Encrypted SMBv2 message recieved, but encryption is not yet supported!'
                    )

                if msg.header.Status == NTStatus.PENDING:
                    self.pending_table[msg.header.MessageId] = SMBPendingMsg(
                        msg.header.MessageId, self.OutstandingResponses,
                        self.OutstandingResponsesEvent)
                    await self.pending_table[msg.header.MessageId].run()
                    continue

                if msg.header.MessageId in self.pending_table:
                    await self.pending_table[msg.header.MessageId].stop()
                    del self.pending_table[msg.header.MessageId]

                self.OutstandingResponses[msg.header.MessageId] = msg
                if msg.header.MessageId in self.OutstandingResponsesEvent:
                    self.OutstandingResponsesEvent[msg.header.MessageId].set()
                else:

                    #here we are loosing messages, the functionality for "PENDING" and "SHARING_VIOLATION" should be implemented
                    continue
        except asyncio.CancelledError:
            #the SMB connection is terminating
            return
        except:
            logger.exception('__handle_smb_in')
Esempio n. 10
0
	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
Esempio n. 11
0
	async def close(self):
		if self.dce:
			if self.handle:
				for hive_name in self.hive_handles:
					try:
						await rrp.hBaseRegCloseKey(self.dce, self.hive_handles[hive_name])
					except Exception as e:
						logger.exception('reg close 1')
						pass
			
				try:
					await rrp.hBaseRegCloseKey(self.dce, self.handle)
				except Exception as e:
					logger.exception('reg close 2')
					pass
			try:
				await self.dce.disconnect()
			except Exception as e:
				logger.exception('reg close 3')
				pass
				
		if self.service_manager:
			try:
				await self.service_manager.close()
			except Exception as e:
				logger.exception('reg close 4')
				pass
				
		return True, None
Esempio n. 12
0
	async def run(self):
		try:
			_, err = await self.setup()
			if err is not None:
				raise err
			
			gen_task = asyncio.create_task(self.__generate_targets())
			
			await asyncio.gather(*self.workers)
			await self.result_processing_task
			return True, None
		except Exception as e:
			logger.exception('run')
			return None, e
Esempio n. 13
0
    async def close(self):
        if self.dce:
            for hid in self.policy_handles:
                try:
                    await lsad.hLsarClose(self.dce, self.policy_handles[hid])
                except:
                    logger.exception()
                    pass

            try:
                await self.dce.disconnect()
            except:
                pass
            return
Esempio n. 14
0
    async def handle_outgoing(self, client):
        """
		Reads data bytes from the outgoing queue and dispatches it to the socket
		"""
        try:
            while not self.shutdown_evt.is_set():
                data = await client.out_queue.get()
                client.writer.write(data)
                await client.writer.drain()
        except asyncio.CancelledError:
            #the SMB connection is terminating
            return

        except Exception as e:
            logger.exception('[TCPSocket] handle_outgoing %s' % str(e))
Esempio n. 15
0
 async def __handle_incoming(self):
     try:
         while True:
             data, res = await self.connection.in_queue.get()
             if data is None:
                 self.__last_exception = res
                 self.exception_evt.set()
                 return
             self.buffer += data
             self.data_in_evt.set()
     except asyncio.CancelledError:
         return
     except Exception as e:
         logger.exception('__handle_incoming')
         return
Esempio n. 16
0
    async def handle_outgoing(self):
        """
		Reads data bytes from the outgoing queue and dispatches it to the socket
		"""
        try:
            while not self.disconnected.is_set():
                data = await self.out_queue.get()
                print('SOCKS5 data out %s' % data)
                self.writer.write(data)
                await self.writer.drain()
        except asyncio.CancelledError:
            #the SMB connection is terminating
            return

        except Exception as e:
            logger.exception('[TCPSocket] handle_outgoing %s' % str(e))
            await self.disconnect()
Esempio n. 17
0
    async def handle_incoming(self):
        """
		Reads data bytes from the socket and dispatches it to the incoming queue
		"""
        try:
            while not self.disconnected.is_set(
            ) or not self.shutdown_evt.is_set():
                data = await self.reader.read(4096)
                await self.in_queue.put(data)

        except asyncio.CancelledError:
            #the SMB connection is terminating
            return

        except Exception as e:
            logger.exception('[TCPSocket] handle_incoming %s' % str(e))
            await self.disconnect()
Esempio n. 18
0
    async def handle_incoming(self, client):
        """
		Reads data bytes from the socket and dispatches it to the incoming queue
		"""
        while not self.shutdown_evt.is_set():
            data = await asyncio.gather(*[client.reader.read(4096)],
                                        return_exceptions=True)
            if isinstance(data[0], bytes):
                await client.in_queue.put(data[0])

            elif isinstance(data[0], asyncio.CancelledError):
                return

            elif isinstance(data[0], Exception):
                logger.exception('[TCPSocket] handle_incoming %s' %
                                 str(data[0]))
                return
Esempio n. 19
0
    async def connect(self):
        try:
            con = asyncio.open_connection(self.ip, self.port)
            self.reader, self.writer = await asyncio.wait_for(con, None)
        except asyncio.TimeoutError:
            logger.debug('[DCERPCTCPConnection] Connection timeout')
            return None, SMBConnectionTimeoutException()
        except ConnectionRefusedError:
            logger.debug('[DCERPCTCPConnection] Connection refused')
            return None, SMBConnectionRefusedException()
        except Exception as e:
            logger.exception('[DCERPCTCPConnection] connect generic exception')
            return None, e

        self.__incoming_task = asyncio.create_task(self.handle_incoming())
        self.__outgoing_task = asyncio.create_task(self.handle_outgoing())

        return True, None
Esempio n. 20
0
    async def run(self):
        try:
            _, err = await self.setup()
            if err is not None:
                raise err

            gen_task = asyncio.create_task(self.__generate_targets())

            await asyncio.gather(*self.workers)
            await self.result_processing_task
            return True, None
        except Exception as e:
            logger.exception('run')
            return None, e
        finally:
            if self.ext_result_q is not None:
                await self.ext_result_q.put(
                    EnumResultFinal(None, 'finished', None, None, None))
Esempio n. 21
0
    async def __generate_targets(self):
        try:
            for target_gen in self.target_gens:
                async for uid, target, err in target_gen.generate():
                    if err is not None:
                        print('Target gen error! %s' % err)
                        break

                    if target in self.exclude_target:
                        continue

                    self.__total_targets += 1
                    await self.task_q.put((uid, target))
                    await asyncio.sleep(0)

            self.__gens_finished = True
        except Exception as e:
            logger.exception('targetgen')
Esempio n. 22
0
    async def handle_outgoing(self):
        """
		Reads data bytes from the outgoing queue and dispatches it to the socket
		"""
        try:
            while not self.disconnected.is_set(
            ) or not self.shutdown_evt.is_set():
                data = await self.out_queue.get()
                self.writer.write(data)
                await self.writer.drain()
        except asyncio.CancelledError:
            #the connection is terminating
            return

        except Exception as e:
            logger.exception('[DCERPCTCPConnection] handle_outgoing %s' %
                             str(e))
            await self.disconnect()
Esempio n. 23
0
    async def handle_incoming(self):
        """
		Reads data bytes from the socket and dispatches it to the incoming queue
		"""
        try:
            timeout = int(self.target.proxy.timeout)
            while not self.disconnected.is_set():
                data = await asyncio.gather(
                    *[asyncio.wait_for(self.reader.read(4096), timeout)],
                    return_exceptions=True)
                if isinstance(data[0], bytes):
                    if data[0] == b'':
                        await self.in_queue.put(
                            (None,
                             Exception(
                                 'Socks5 server terminated the connection!')))
                        await self.disconnect()
                    #print('%s : %s' % (self.writer.get_extra_info('peername')[0], data[0]))
                    #print('SOCKS5 data in %s' % data[0])
                    await self.in_queue.put((data[0], None))

                elif isinstance(data[0], asyncio.CancelledError):
                    #print('SOCKS5 data in CANCELLED')
                    return

                elif isinstance(data[0], Exception):
                    #print('SOCKS5 data in exception')
                    logger.exception('[SOCKS5] handle_incoming %s' %
                                     str(data[0]))
                    await self.in_queue.put((None, data[0]))
                    await self.disconnect()
                    return

            #print('SOCKS5 data in EXITING')
        except asyncio.CancelledError:
            await self.in_queue.put((None, asyncio.CancelledError))
            return

        except Exception as e:
            import traceback
            traceback.print_exc()
            #print('SOCKS5 data in ERROR!')
            await self.in_queue.put((None, e))
            return
Esempio n. 24
0
    async def handle_incoming(self):
        """
		Reads data bytes from the socket_in_queue and parses the NetBIOS messages and the SMBv1/2 messages.
		Dispatches the SMBv1/2 message objects.
		"""
        try:
            buffer = b''
            while not self.shutdown_evt.is_set() or not self.stop_evt.is_set():
                data = await self.socket_in_queue.get()
                #parse
                buffer += data
                buffer = await self.parse_buffer(buffer)
        except asyncio.CancelledError:
            #the SMB connection is terminating
            return

        except Exception as e:
            logger.exception('NetBIOSTransport handle_incoming')
            await self.stop()
Esempio n. 25
0
    async def handle_incoming(self):
        """
		Reads data bytes from the socket and dispatches it to the incoming queue
		"""
        while not self.disconnected.is_set():
            data = await asyncio.gather(*[self.reader.read(4096)],
                                        return_exceptions=True)
            if isinstance(data[0], bytes):
                #print('%s : %s' % (self.writer.get_extra_info('peername')[0], data[0]))
                await self.in_queue.put((data[0], None))

            elif isinstance(data[0], asyncio.CancelledError):
                return

            elif isinstance(data[0], Exception):
                logger.exception('[TCPSocket] handle_incoming %s' %
                                 str(data[0]))
                await self.in_queue.put((None, data[0]))
                await self.disconnect()
                return
Esempio n. 26
0
	async def worker(self):
		try:
			while True:
				indata = await self.task_q.get()
				if indata is None:
					return
				
				tid, target = indata
				try:
					await asyncio.wait_for(self.__executor(tid, target), timeout=60)
				except asyncio.CancelledError:
					return
				except Exception as e:
					logger.exception('worker')
					continue
		except asyncio.CancelledError:
			return
				
		except Exception as e:
			return e
Esempio n. 27
0
	async def result_processing(self):
		try:

			out_buffer = []
			final_iter = False
			while True:
				try:
					if len(out_buffer) >= 10000 or final_iter:
						out_data = '\r\n'.join(out_buffer)
						out_buffer = []
						if self.out_file is not None:
							with open(self.out_file, 'a+', newline = '') as f:
								f.write(out_data)
						else:
							print(out_data)
					if final_iter:
						asyncio.create_task(self.terminate())
						return
					er = await self.res_q.get()
					if er.status == EnumResultStatus.FINISHED:
						self.__total_finished += 1
						out_buffer.append('[P][%s/%s][%s]' % (self.__total_targets, self.__total_finished, str(self.__gens_finished)))
						if self.__total_finished == self.__total_targets and self.__gens_finished is True:
							final_iter = True
							continue
							
					if er.result is not None:
						obj, otype, err = er.result
						if otype is not None:
							out_buffer.append('[%s] %s' % (otype[0].upper(), obj.unc_path))							
						if err is not None:
							out_buffer.append('[E] %s %s' % (err, obj.unc_path))
				except asyncio.CancelledError:
					return
				except Exception as e:
					logger.exception('result_processing inner')
					continue
		except asyncio.CancelledError:
			return
		except Exception as e:
			logger.exception('result_processing')
Esempio n. 28
0
    async def connect(self):
        con = asyncio.open_connection(self.ip, self.port)

        try:
            self.reader, self.writer = await asyncio.wait_for(
                con, int(self.timeout))
        except asyncio.TimeoutError:
            logger.debug('[DCERPCTCPConnection] Connection timeout')
            raise SMBConnectionTimeoutException()
        except ConnectionRefusedError:
            logger.debug('[DCERPCTCPConnection] Connection refused')
            raise SMBConnectionRefusedException()
        except asyncio.CancelledError:
            #the SMB connection is terminating
            return
        except Exception as e:
            logger.exception('[DCERPCTCPConnection] connect generic exception')
            raise e

        asyncio.ensure_future(self.handle_incoming())
        asyncio.ensure_future(self.handle_outgoing())
        return
Esempio n. 29
0
	async def handle_incoming(self):
		"""
		Reads data bytes from the socket_in_queue and parses the NetBIOS messages and the SMBv1/2 messages.
		Dispatches the SMBv1/2 message objects.
		"""
		try:
			buffer = b''
			while True:
				data, err = await self.socket_in_queue.get()
				if err is not None:
					raise err
				#parse
				buffer += data
				buffer = await self.parse_buffer(buffer)

		except asyncio.CancelledError:
			#the SMB connection is terminating
			return
			
		except Exception as e:
			logger.exception('NetBIOSTransport handle_incoming error')
			await self.in_queue.put( (None, e) )
			await self.stop()
Esempio n. 30
0
    async def handle_outgoing(self):
        """
		Reads SMBv1/2 outgoing message objects from out_queue, wraps them in NetBIOS object, then serializes them, then sends them to socket_out_queue
		"""
        try:
            while not self.shutdown_evt.is_set() or not self.stop_evt.is_set():
                smb_msg = await self.out_queue.get()
                #print(smb_msg)
                smb_msg_data = smb_msg.to_bytes()
                data = b'\x00'
                data += len(smb_msg_data).to_bytes(3,
                                                   byteorder='big',
                                                   signed=False)
                data += smb_msg_data
                await self.socket_out_queue.put(data)

        except asyncio.CancelledError:
            #the SMB connection is terminating
            return

        except Exception as e:
            logger.exception('NetBIOSTransport handle_outgoing')
            await self.stop()