Last active
March 27, 2017 20:46
-
-
Save mmmonk/1bbeebbdf1a4a6df38e248641f6d8c38 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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) | |
if __name__ == "__main__": | |
# example usage | |
c = HTTPSocks5("www.google.com", 80) | |
c.setsocksproxy("127.0.0.1", 1081) | |
c.request("GET", "/") | |
r = c.getresponse() | |
print("%s" % (r.read().decode('utf-8'),)) | |
c.close() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment