patches socket to tunnel through a tor server either by socks4a or socks5 (tor-resolve required for socks5), being careful not to leak dns requests
pyconstruct required, http://construct.wikispaces.com/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | from construct import *
import socket
import sys
import subprocess
import logging
# monkeys were here
# currently only works with AF_INET and SOCK_STREAM due
# to my shitty understanding of patching getaddrinfo
# but at least it doesn't leak DNS resolves
TORIP="127.0.0.1"
TORPORT=9050
PROTO="socks4a" # or socks5, dependent on tor-resolve
USERID="anonymous" # for 4a only
log = logging.getLogger("torSocket")
class IpAddressAdapter(Adapter):
def _encode(self, obj, context):
return "".join(chr(int(b)) for b in obj.split("."))
def _decode(self, obj, context):
return ".".join(str(ord(b)) for b in obj)
def IpAddress(name):
return IpAddressAdapter(Bytes(name, 4))
class SocksException(Exception):
pass
class TorSocket():
def __init__(self, *args, **kwargs):
self._sock = oldSocket(socket.AF_INET, socket.SOCK_STREAM)
self.connect = getattr(self, "%sconnect" % PROTO)
self._sock.connect((TORIP, TORPORT))
def socks5connect(self, address):
log.debug("using socks5")
connect = Struct("connect",
Byte("ver"),
Byte("nmethods"),
Byte("methods"),
)
connectResponse = Struct("response",
Byte("ver"),
Byte("method"),
)
p = Container(
ver=5,
nmethods=1,
methods=0
)
self._sock.send(connect.build(p))
data = self._sock.recv(1024)
response = connectResponse.parse(data)
if response.method == 255:
raise SocksException
request = Struct("request",
Byte("ver"),
Byte("cmd"),
Byte("rsv"),
Byte("atyp"),
IpAddress("dstaddr"),
UBInt16("dstport")
)
requestResponse = Struct("requestResponse",
Byte("ver"),
Byte("rep"),
Byte("rsv"),
Byte("atyp"),
UBInt16("bndport")
)
p = Container(
ver=5,
cmd=1,
rsv=0,
atyp=1,
dstaddr=address[0],
dstport=address[1]
)
self._sock.send(request.build(p))
data = self._sock.recv(1024)
response = requestResponse.parse(data)
if response.rep != 0:
raise SocksException
def socks4aconnect(self, address):
log.debug("using socks4a")
connect = Struct("connect",
Byte("ver"),
Byte("cd"),
UBInt16("dstport"),
IpAddress("dstip"),
CString("userid"),
CString("domain")
)
connectResponse = Struct("response",
Byte("ver"),
Byte("cd"),
UBInt16("dstport"),
IpAddress("dstip")
)
p = Container(
ver=4,
cd=1,
dstport=address[1],
dstip="0.0.0.1",
userid=USERID,
domain=address[0]
)
self._sock.send(connect.build(p))
data = self._sock.recv(1024)
response = connectResponse.parse(data)
if response.cd != 90:
raise SocksException
def connect(self, address):
raise NotImplementedError
def makefile(self, *args):
return self._sock.makefile(*args)
def sendall(self, *args):
self._sock.sendall(*args)
def send(self, *args):
self._sock.send(*args)
def recv(self, *args):
return self._sock.recv(*args)
def close(self):
self._sock.close()
def torResolve(name):
log.debug("resolving %s with tor-resolve" % name)
p = subprocess.Popen(['tor-resolve', name], stdout=subprocess.PIPE)
ip = p.stdout.read().strip()
return ip
def getaddrinfo(*args):
if PROTO == "socks4a":
return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0], args[1]))]
elif PROTO == "socks5":
ip = torResolve(args[0])
return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (ip, args[1]))]
else:
raise SocksException
oldSocket = socket.socket
oldAddrInfo = socket.getaddrinfo
socket.socket = TorSocket
socket.getaddrinfo = getaddrinfo
socket.gethostbyname = torResolve
sys.modules['socket'] = socket
|
for anonymity. import the module before any other modules that are dependent on socket and use as normal
Tags: network