I had a need for a simple way of running some HTTP queries through SOCKS5 (think OpenSSH -D) proxy. All the examples I could find on the internet required usage of external libraries, I prefer to just use the standard ones, makes things simpler in the end.
Here is the code I come up with, I borrowed some code from a different tool that I wrote sometime ago. Gist can be found here.
#!/usr/bin/env python3 import http.client import socket from struct import pack, unpack class HTTPSocks5(http.client.HTTPConnection): def setsocksproxy(self, host, port): self.socks5host = host self.socks5port = port def connect(self): if hasattr(self, "socks5host") and self.socks5host: self.sock = self._create_connection( (self.socks5host,self.socks5port), self.timeout, self.source_address) error = ["succeeded", "general SOCKS server failure",\ "connection not allowed by ruleset", "Network unreachable",\ "Host unreachable", "Connection refused", "TTL expired",\ "Command not supported", "Address type not supported", "unassigned"] data = pack('!3B',5,1,0) # lets connect to socks5 server self.sock.send(data) data = self.sock.recv(2) auth = unpack('2B',data)[1] # do we need to authenticate if auth != 255: nport = pack('!H',self.port) try: if ":" in self.host: # we most likely have IPv6 here data = pack('!4B',5,1,0,4)+\ socket.inet_pton(socket.AF_INET6,self.host)+nport else: # IPv4 data = pack('!4B',5,1,0,1)+\ socket.inet_pton(socket.AF_INET,self.host)+nport except socket.error: # or just a hostname to resolve by the SOCKS srv data = pack('!5B',5,1,0,3,len(self.host))+\ bytearray(self.host,'UTF-8')+nport self.sock.send(data) data = self.sock.recv(256) # getting the status code try: code = unpack('BBB',data[:3])[1] except: raise("socks server sent a wrong replay") if code != 0: if code > 9: code = 9 raise("socks server sent an error: %s" % (error[code],)) else: raise("socks server requires authentication") else: self.sock = self._create_connection( (self.host,self.port), self.timeout, self.source_address)
No comments:
Post a Comment