[tor-dev] Obfsproxy Address Translation
Alfredo Palhares
masterkorp at masterkorp.net
Fri Jan 23 12:36:57 UTC 2015
Hello,
Sorry for the delay, I finnally set on the quest to understand obfsproxy.
So with the help of pdb and a few questions here and there I got to some
places, and with a lot of more questions to ask.
## Studying the client
The client launches a connection on obfsproxy/pyofsproxypy do_external_mode() the
launch_transport.launch_transport_listener method is where the socks listeners is set.
Right after that the Twisted library reactor module is initiated with reactor.run() on
line 107 of the file obfsproxy/pyobfsproxy.py
After that the Twisted event loop is started and it will listen to events that
are set on methods like listenTCP() the wiki page about servers[1]
I've set a pdb.set_trace() on the buildProtocol() method in the file
obfsproxy/network/socks.py and the backtrace looks like.
(Pdb) bt
/usr/lib/python2.7/runpy.py(162)_run_module_as_main()
-> "__main__", fname, loader, pkg_name)
/usr/lib/python2.7/runpy.py(72)_run_code()
-> exec code in run_globals
/usr/lib/python2.7/pdb.py(1338)<module>()
-> pdb.main()
/usr/lib/python2.7/pdb.py(1314)main()
-> pdb._runscript(mainpyfile)
/usr/lib/python2.7/pdb.py(1233)_runscript()
-> self.run(statement)
/usr/lib/python2.7/bdb.py(400)run()
-> exec cmd in globals, locals
<string>(1)<module>()
/home/masterkorp/Public/obfsproxy/bin/obfsproxy(16)<module>()
-> run()
/home/masterkorp/Public/obfsproxy/obfsproxy/pyobfsproxy.py(207)run()
-> pyobfsproxy()
/home/masterkorp/Public/obfsproxy/obfsproxy/pyobfsproxy.py(189)pyobfsproxy()
-> do_external_mode(args)
/home/masterkorp/Public/obfsproxy/obfsproxy/pyobfsproxy.py(108)do_external_mode()
-> reactor.run()
/usr/lib/python2.7/site-packages/twisted/internet/base.py(1192)run()
-> self.mainLoop()
/usr/lib/python2.7/site-packages/twisted/internet/base.py(1204)mainLoop()
-> self.doIteration(t)
/usr/lib/python2.7/site-packages/twisted/internet/epollreactor.py(396)doPoll()
-> log.callWithLogger(selectable, _drdw, selectable, fd, event)
/usr/lib/python2.7/site-packages/twisted/python/log.py(88)callWithLogger()
-> return callWithContext({"system": lp}, func, *args, **kw)
/usr/lib/python2.7/site-packages/twisted/python/log.py(73)callWithContext()
-> return context.call({ILogContext: newCtx}, func, *args, **kw)
/usr/lib/python2.7/site-packages/twisted/python/context.py(118)callWithContext()
-> return self.currentContext().callWithContext(ctx, func, *args, **kw)
/usr/lib/python2.7/site-packages/twisted/python/context.py(81)callWithContext()
-> return func(*args,**kw)
/usr/lib/python2.7/site-packages/twisted/internet/posixbase.py(614)_doReadOrWrite()
-> why = selectable.doRead()
/usr/lib/python2.7/site-packages/twisted/internet/tcp.py(1062)doRead()
-> protocol = self.factory.buildProtocol(self._buildAddr(addr))
/home/masterkorp/Public/obfsproxy/obfsproxy/network/socks.py(183)buildProtocol()
-> circuit = network.Circuit(self.transport_class())
It goes directly to this method from Twistedm, which confirms that all the SOCKS
is set. This creates a new Circuit. And the like the documentation says a Circuit
is a pair of connections between and the obfsproxy client and openvpn client (in
this case) or obfsproxy server and OpenVPN server.
Then I set a pdb.set_trace() dataReceived() on obfsproxy/network/network.py well
because of the name. And a backtrace looks like:
(Pdb) bt
/usr/lib/python2.7/runpy.py(162)_run_module_as_main()
-> "__main__", fname, loader, pkg_name)
/usr/lib/python2.7/runpy.py(72)_run_code()
-> exec code in run_globals
/usr/lib/python2.7/pdb.py(1338)<module>()
-> pdb.main()
/usr/lib/python2.7/pdb.py(1314)main()
-> pdb._runscript(mainpyfile)
/usr/lib/python2.7/pdb.py(1233)_runscript()
-> self.run(statement)
/usr/lib/python2.7/bdb.py(400)run()
-> exec cmd in globals, locals
<string>(1)<module>()
/home/masterkorp/Public/obfsproxy/bin/obfsproxy(3)<module>()
-> import sys, os
/home/masterkorp/Public/obfsproxy/obfsproxy/pyobfsproxy.py(205)run()
-> pyobfsproxy()
/home/masterkorp/Public/obfsproxy/obfsproxy/pyobfsproxy.py(187)pyobfsproxy()
-> do_external_mode(args)
/home/masterkorp/Public/obfsproxy/obfsproxy/pyobfsproxy.py(106)do_external_mode()
-> reactor.run()
/usr/lib/python2.7/site-packages/twisted/internet/base.py(1192)run()
-> self.mainLoop()
/usr/lib/python2.7/site-packages/twisted/internet/base.py(1204)mainLoop()
-> self.doIteration(t)
/usr/lib/python2.7/site-packages/twisted/internet/epollreactor.py(396)doPoll()
-> log.callWithLogger(selectable, _drdw, selectable,fd, event)
/usr/lib/python2.7/site-packages/twisted/python/log.py(88)callWithLogger()
-> return callWithContext({"system": lp}, func,*args, **kw)
/usr/lib/python2.7/site-packages/twisted/python/log.py(73)callWithContext()
-> return context.call({ILogContext: newCtx},func, *args, **kw)
/usr/lib/python2.7/site-packages/twisted/python/context.py(118)callWithContext()
-> return self.currentContext().callWithContext(ctx,func, *args, **kw)
/usr/lib/python2.7/site-packages/twisted/python/context.py(81)callWithContext()
-> return func(*args,**kw)
/usr/lib/python2.7/site-packages/twisted/internet/posixbase.py(614)_doReadOrWrite()
-> why = selectable.doRead()
/usr/lib/python2.7/site-packages/twisted/internet/tcp.py(214)doRead()
-> return self._dataReceived(data)
/usr/lib/python2.7/site-packages/twisted/internet/tcp.py(220)_dataReceived()
-> rval = self.protocol.dataReceived(data)
/home/masterkorp/Public/obfsproxy/obfsproxy/network/socks5.py(163)dataReceived()
-> self.processEstablishedData(data)
/home/masterkorp/Public/obfsproxy/obfsproxy/network/socks.py(107)processEstablishedData()
-> self.circuit.dataReceived(self.buffer, self)
/home/masterkorp/Public/obfsproxy/obfsproxy/network/network.py(152)dataReceived()
-> if self.closed:
Its not too far away for the previous backtrace
Inside the method I try to see what the heck is going on.
(Pdb) print self
<obfsproxy.network.network.Circuit instance at 0x7fbbec1c3758>
This is the circuit itself, passing self seems a into the methods seems a
print self common thing to do. I verihave no idea why.
(Pdb) print conn
<obfsproxy.network.socks.OBFSSOCKSv5Protocol object at 0x7fbbec1b75d0>
Conn is a socks connections. I wonder how can I extract the source IP from it.
(Pdb) print data
<obfsproxy.network.buffer.Buffer object at 0x7fbbec1b7510>
data is butter object. Apparently is a First In First Out data container. Not
sure where this object was initially created.
I've tried to use the peek method, whiting pdb.
(Pdb) print data.peek(n=100)
8£öä¢ÂZ
Passing n=<whatever> always shows that same string. Maybe that is just it, kinda
like an initial hanshake ?
Just a few steps foward here. there is a log.debug
2015-01-22 17:25:35,162 [DEBUG] circ_0x7fbbec1c3758: upstream: Received 16bytes.
Ok I think I am on the right path.
Then the receivedUpstream() on obfsproxy/network/transports/scramblesuit/scramblesuit.py
A few steps forward in:
if self.protoState == const.ST_CONNECTED:
Where the const.ST_CONNECTED comes from ? printing shows an value of "2" which
on this case its equal to self.protoState, that I think it means that obfsproxy
client is connected to obfsproxy Server correct me if I am wrong
Then the data send to sendRemote. which obfsucates the data itself and reads
from the Buffer object.
In here I could not get info about the SOCKS client Ip address. Wich is weird.
Can you shed some light ?
Thanks in advance?
[1] https://twistedmatrix.com/documents/current/core/howto/servers.html
--
Regards,
Alfredo Palhares
More information about the tor-dev
mailing list