Exemple #1
0
class SocksProxyConnection:
    """
	Generic asynchronous TCP socket class, nothing SMB related.
	Creates the connection and channels incoming/outgoing bytes via asynchonous queues.
	"""
    def __init__(self, target=None, socket=None):
        self.target = target
        self.socket = socket  #for future, if we want a custom soscket

        self.client = None
        self.proxy_task = None

        self.out_queue = None  #asyncio.Queue()
        self.in_queue = None  #asyncio.Queue()

    async def disconnect(self):
        """
		Disconnects from the socket.
		Stops the reader and writer streams.
		"""
        self.proxy_task.cancel()

    async def connect(self):
        self.out_queue = asyncio.Queue()
        self.in_queue = asyncio.Queue()
        comms = SocksQueueComms(self.out_queue, self.in_queue)

        self.target.proxy.target.endpoint_ip = self.target.ip
        self.target.proxy.target.endpoint_port = int(self.target.port)

        self.client = SOCKSClient(comms, self.target.proxy.target,
                                  self.target.proxy.auth)
        self.proxy_task = asyncio.create_task(self.client.run())
        return
class AIOKerberosClientSocksSocket:
	def __init__(self, target):
		self.target = target
		self.out_queue = None
		self.in_queue = None

		self.proxy_client = None
		self.proxy_task = None
		
	def get_addr_str(self):
		return '%s:%d' % (self.target.ip, self.target.port)

	async def sendrecv(self, data):
		self.out_queue = asyncio.Queue()
		self.in_queue = asyncio.Queue()
		comms = SocksQueueComms(self.out_queue, self.in_queue)

		self.client = SOCKSClient(comms, self.target.proxy.target)
		self.proxy_task = asyncio.create_task(self.client.run())

		length = len(data).to_bytes(4, byteorder = 'big', signed = False)
		await self.out_queue.put(length+data)

		resp_data = b''
		resp_data_len = -1
		while True:
			data, err = await self.in_queue.get()
			if data is None:
				break
			if err is not None:
				raise err
			resp_data += data
			if resp_data_len == -1:
				if len(resp_data) > 4:
					resp_data_len = int.from_bytes(resp_data[:4], byteorder = 'big', signed = False)
					if resp_data_len == 0:
						raise Exception('Returned data length is 0! This means the server did not understand our message')
			
			if resp_data_len != -1:
				if len(resp_data) == resp_data_len + 4:
					resp_data = resp_data[4:]
					break
				elif len(resp_data) > resp_data_len + 4:
					raise Exception('Got too much data somehow')
				else:
					continue
		
		await self.out_queue.put(None)
		if resp_data == b'':
			raise Exception('Connection returned no data!')
		
		krb_message = KerberosResponse.load(resp_data)
		return krb_message

		
	def __str__(self):
		t = '===AIOKerberosClientProxySocket AIO===\r\n'
		t += 'target: %s\r\n' % self.target
		
		return t
Exemple #3
0
def main():
	import argparse

	parser = argparse.ArgumentParser(description='Transparent TCP tunnel for SOCKS unaware clients.')
	parser.add_argument('proxy_connection_string', help='connection string decribing the socks5 proxy server connection properties')
	parser.add_argument('dst_ip', help='IP address of the desination server')
	parser.add_argument('dst_port', type = int, help='port number of the desination service')
	parser.add_argument('-l', '--listen-ip', default = '127.0.0.1',  help='Listener IP address to bind to')
	parser.add_argument('-p', '--listen-port', type = int, default = 11111, help='Listener port number to bind to')
	parser.add_argument('-t', '--timeout', type = int, default = None, help='Endpoint timeout')
	parser.add_argument('-v', '--verbose', action='count', default=0)

	args = parser.parse_args()

	if args.verbose >=1:
		logger.setLevel(logging.DEBUG)
		

	elif args.verbose > 2:
		logger.setLevel(1)

	comms = SocksLitenerComms(args.listen_ip, args.listen_port)

	url = SocksClientURL.from_url(args.proxy_connection_string)
	url.endpoint_ip = args.dst_ip
	url.endpoint_port = args.dst_port
	url.endpoint_timeout = args.timeout

	target = url.get_target()
	credentials = url.get_creds()

	if args.verbose >=1:
		print(str(target))

	print(__banner__)
	layout = """Connection layout
	
	CLIENT --->|
	CLIENT --->|(LISTENER) %s:%s  |--->| (%s) %s:%s |--->| (FINAL DST) %s:%s
	CLIENT --->|
	
	""" % (args.listen_ip, args.listen_port, target.version.name.upper() ,target.server_ip, target.server_port, args.dst_ip, args.dst_port)

	print(layout)

	client = SOCKSClient(comms, target, credentials)

	print('Waiting for incoming connections')
	asyncio.run(client.run())
Exemple #4
0
class RDNS:
	def __init__(self, server = '8.8.8.8', protocol = 'TCP', cache = True, timeout = 1, proxy:List[str] = None):
		self.server = server
		self.protocol = protocol
		self.port = 53
		self.cache = {}
		self.timeout = timeout
		self.proxy:List[str] = proxy
		self.proxyobj = None
		self.proxy_task = None
		self.in_q = None
		self.out_q = None

	async def setup(self):
		try:
			if self.proxy is None:
				# no need for additional setup
				return None, None
			
			self.in_q = asyncio.Queue()
			self.out_q = asyncio.Queue()
			comms = SocksQueueComms(self.in_q, self.out_q)
			proxies = SocksClientURL.from_urls(self.proxy, self.server, self.port)
			self.proxyobj = SOCKSClient(comms, proxies)
			self.proxy_task = asyncio.create_task(self.proxyobj.run())
			return None, None
		except Exception as e:
			return None, e



	async def lookup(self, hostname, dnstype = DNSType.A):
		_, err = await self.setup()
		if err is not None:
			return None, err
		try:
			question = DNSQuestion.construct(str(hostname), dnstype, DNSClass.IN, qu = False)
			if self.proxyobj is None:
				if self.protocol == 'TCP':
					reader, writer = await asyncio.wait_for(asyncio.open_connection(self.server, self.port), self.timeout)
			
					packet = DNSPacket.construct(
						TID = os.urandom(2), 
						flags = DNSFlags.RD,
						response = DNSResponse.REQUEST, 
						opcode = DNSOpcode.QUERY, 
						rcode = DNSResponseCode.NOERR, 
						questions= [question], 
						proto = socket.SOCK_STREAM
					)
					
					writer.write(packet.to_bytes())
					await writer.drain()
					
					data = await DNSPacket.from_streamreader(reader, proto = socket.SOCK_STREAM)
					writer.close()
					return data.Answers[0].ipaddress, None
				else:
					raise NotImplementedError()
			else:
				if self.protocol == 'TCP':
					packet = DNSPacket.construct(
						TID = os.urandom(2), 
						flags = DNSFlags.RD,
						response = DNSResponse.REQUEST, 
						opcode = DNSOpcode.QUERY, 
						rcode = DNSResponseCode.NOERR, 
						questions= [question], 
						proto = socket.SOCK_STREAM
					)

					await self.in_q.put(packet.to_bytes())
					x = await DNSPacket.from_queue(self.out_q, b'', proto = socket.SOCK_STREAM)
					packet, rem = x
					if len(packet.Answers) == 0:
						raise Exception("No answer found in packet")
					return packet.Answers[0].ipaddress, None
				
				else:
					raise NotImplementedError()


		except Exception as e:
			return None, e
		finally:
			if self.proxyobj is not None:
				await self.proxyobj.terminate()


	async def resolve(self, ip):
		try:
			if ip in self.cache:
				return self.cache[ip]
			ip = ipaddress.ip_address(ip).reverse_pointer
			tid = os.urandom(2)
			question = DNSQuestion.construct(ip, DNSType.PTR, DNSClass.IN, qu = False)
				
						
			if self.protocol == 'TCP':
				reader, writer = await asyncio.wait_for(asyncio.open_connection(self.server, self.port), self.timeout)
		
				packet = DNSPacket.construct(
					TID = tid,
					flags = DNSFlags.RD,
					response = DNSResponse.REQUEST,
					opcode = DNSOpcode.QUERY,
					rcode = DNSResponseCode.NOERR,
					questions= [question],
					proto = socket.SOCK_STREAM
				)
				
				writer.write(packet.to_bytes())
				await writer.drain()
				
				data = await DNSPacket.from_streamreader(reader, proto = socket.SOCK_STREAM)
				self.cache[ip] = data.Answers[0].domainname
				writer.close()
				return data.Answers[0].domainname, None
			else:
				cli = UDPClient((self.server, self.port))
				
				packet = DNSPacket.construct(
					TID = tid, 
					flags = DNSFlags.RD,
					response = DNSResponse.REQUEST,
					opcode = DNSOpcode.QUERY,
					rcode = DNSResponseCode.NOERR,
					questions= [question],
					proto = socket.SOCK_DGRAM
				)
						
				reader, writer = await cli.run(packet.to_bytes())	
				data = await DNSPacket.from_streamreader(reader)
				self.cache[ip] = data.Answers[0].domainname
				return data.Answers[0].domainname, None
		
		except Exception as e:
			return None, e
		finally:
			if self.proxyobj is not None:
				await self.proxyobj.terminate()
Exemple #5
0
class SocksProxyConnection:
    """
	Generic asynchronous TCP socket class, nothing SMB related.
	Creates the connection and channels incoming/outgoing bytes via asynchonous queues.
	"""
    def __init__(self, target):
        self.target = target

        self.client = None
        self.proxy_task = None
        self.handle_in_task = None

        self.out_queue = None  #asyncio.Queue()
        self.in_queue = None  #asyncio.Queue()

        self.proxy_in_queue = None  #asyncio.Queue()
        self.is_plain_msg = True

    async def disconnect(self):
        """
		Disconnects from the socket.
		Stops the reader and writer streams.
		"""
        self.proxy_task.cancel()
        self.handle_in_task.cancel()

    def get_peer_certificate(self):
        raise Exception(
            'Not yet implemented! SSL implementation on socks is missing!')
        return self.writer.get_extra_info('socket').getpeercert(True)

    def get_one_message(self, data):
        if len(data) < 6:
            return None

        if self.is_plain_msg is True:
            dl = calcualte_length(data[:6])
        else:
            dl = int.from_bytes(data[:4], byteorder='big', signed=False)
            dl = dl + 4

        #print(dl)
        if len(data) >= dl:
            return data[:dl]

    async def handle_in_q(self):
        try:
            data = b''
            while True:
                while True:
                    msg_data = self.get_one_message(data)
                    if msg_data is None:
                        break

                    await self.in_queue.put((msg_data, None))
                    data = data[len(msg_data):]

                temp, err = await self.proxy_in_queue.get()
                #print(temp)
                if err is not None:
                    raise err

                if temp == b'' or temp is None:
                    logger.debug('Server finished!')
                    return

                data += temp
                continue

        except asyncio.CancelledError:
            return
        except Exception as e:
            logger.exception('handle_in_q')
            await self.in_queue.put((None, e))

        finally:
            self.proxy_task.cancel()

    async def run(self):
        """
		
		"""
        try:
            self.out_queue = asyncio.Queue()
            self.in_queue = asyncio.Queue()

            self.proxy_in_queue = asyncio.Queue()
            comms = SocksQueueComms(self.out_queue, self.proxy_in_queue)

            self.target.proxy.target.endpoint_ip = self.target.host
            self.target.proxy.target.endpoint_port = int(self.target.port)

            self.client = SOCKSClient(comms, self.target.proxy.target,
                                      self.target.proxy.auth)
            self.proxy_task = asyncio.create_task(self.client.run())
            self.handle_in_task = asyncio.create_task(self.handle_in_q())
            return True, None
        except Exception as e:
            return False, e