Shortly after having my new fibre broadband installed, I discovered a method to permanently compromise the security of the BrightBox router provided by EE. After a brief period of traffic analysis, something I do to all new devices on my network, I had found that it is incredibly easy to access sensitive information. This includes the md5 hash of the device admin password and my ISP user credentials, amongst other sensitive data. Allowing me to pass account security over the phone with EE, this not only leads to a total compromise of the device, but gives an attacker control of your account too.


ee

Introduction

The BrightBox router is issued as the standard equipment for broadband and fibre packages taken out with EE. It was also previously issued by Orange for their broadband packages too. At the time of writing, ISPreview state that EE has around 714,000 subscribers in the UK and I just became one of them. The engineer came out and connected my fibre broadband (FTTC) and as with all new devices on my network, I decided to take a closer look at the traffic going to and from the device. It became apparent that the device leaks access to all kinds of sensitive data to clients on the network and there's also the possibility to exploit this remotely. It discloses the password of the EE account holder so I can call EE and pass account security, leaving me in a position to go as far as cancelling someone else's broadband package altogether. In this blog I'm going to cover the various weaknesses present in the EE BrightBox and demonstrate how they can be exploited. Throughout the blog you will find many links to files or pages hosted on the BrightBox. These links will work assuming you are on the same network as a BrightBox router and that it has the standard IP of 192.168.1.1, otherwise they will likely result in an error.



Logging In

First up was to see what happens during the login process. The login page doesn't run any transport layer security so we can expect to see the credentials zipping over the wire in plain text. Here is what Fiddler saw when I submitted the login form.



The call to login.cgi grabbed my attention and sure enough, there are my user credentials.



Interestingly, the username and password appear twice in the data and the first occurrence of the password looks like an md5 hash. Could we consider this to be a good indication of how the password is stored on the device? Either way, at this point we're sniffing plain text traffic which is nothing special, so, on we go.


Exposing Configuration Variables

There's an awful lot of JS files loaded when you login and the first few turned out to be nothing much interesting really. Once I got down to the /cgi/ folder though, things changed somewhat drastically. Navigating to the cgi_status.js file manually, I was greeted with an awful lot of information.



I couldn't really give a much bigger view of the page as it starts to detail a lot of sensitive information, like my ISP user credentials. Looking through further I believe it actually outputs almost every single piece of sensitive information stored on your router . That includes things like all of your WiFi SSIDs and their WPA2 keys.



Ok, that's not so bad. I mean, we're logged in to the router as an admin, what does it matter if we can access all this data like this? The problem is, that even when you're not logged in, any client on the network can access the information. Here I am using incognito mode to view the page without needing to login to the web interface.



This would allow anyone to completely bypass any restrictions you had imposed on the WiFi networks for example. The router offers the ability to setup multiple SSIDs on independant VLANs. To each of these you can apply different restrictions like bandwidth throttling, firewall rules, QoS and even time restrictions . Once a user has access to your "Guest Network" for example, they could simply view the WPA key for your "Main Network" and completely bypass all of your restrictions with a simple copy/paste operation. Not only that, but if someone has brief access to your premises and perhaps connects to your LAN, they can steal a copy of your WiFi password/s. This would allow them remote access to your WiFi from outside the premises without you ever divulging the passwords to anyone. Not so good.


Password Management

The next thing I like to check out is the change password or password reset options. So often done completely wrong, they generally expose any weaknesses in how passwords are handled and stored. Navigating through the Advanced Set-Up menu, I found the change password option.



After submitting the form I saw a POST request to apply.cgi and found the data being sent back to the router.



Interestingly, there was only one parameter being sent back to the router and it wasn't my new password in plain text or an md5 hash. Time to have a quick dig through the source.




So, the password is being "encrypted" before being sent over the wire without any transport layer security. Phew, at least we're safe from pesky hackers... A quick 'hex to string' conversion of '70617373776f726432' confirms that the value is indeed 'password2'. At this point it dawned on me that there was no communication of my original password, 'password1', to the router. The form asked for it, and the password was successfully changed, so it must have validated the existing password, surely? Either the original password isn't validated and is merely a place holder, or, the original password must have been available on the client side to verify prior to submission. Both of these are very daunting prospects. If the original password isn't verified and someone walked by a computer with a logged in session, they could simply reset the password without knowing the existing password. If the password is available on the client side it means the router transmitted the current admin password to the client. A quick scroll through the Network tab in the Chrome Developer Tools and I'd found my culprit.



Retrieving The Admin Password Hash

When loading the page, a file called cgi_sys_p.js is requested, which contains the md5 hash of the current admin password. I then confirmed this was indeed the case with the change password function. You can see that the existing password the user provides is hashed with md5 and then compared to the current password.



Knowing that the existing password is simply an md5 hash, I can quickly crack it using the enormous rainbow tables available on sites like CrackStation or MD5Decrypter.




So, now we know the path of the file where the admin credentials reside, we can simply navigate to the file and view it from any network connected device.



Just to be sure, I fired up an incognito window and ruled out any existing cookies granting me access to the file. I also tried from a different client on the network as the device also seems to use your IP address as a form of authentication.



There you have it! Once you're on the network, via LAN or WiFi, you can retrieve the md5 hash of the admin password and run it through any rainbow tables you happen to have handy. Even if that's taking a while to run through HashCat, there is still a wide range of information you can grab from all the other files that expose information. Simply type the IP address of your router into the address bar and append any of the following file paths to take a look. I've highlighted the ones that expose particularly sensitive information in bold and hyper-linked them assuming you have the device's standard IP so you can just click the links.


/cgi/cgi_3g.js - 3G access credentials

/cgi/cgi_accessControlAdd.js

/cgi/cgi_atmint.js

/cgi/cgi_atmpvc.js

/cgi/cgi_ddns_main.js - DDNS user credentials

/cgi/cgi_dns.js

/cgi/cgi_dsl.js

/cgi/cgi_dsl_status.js

/cgi/cgi_firewall_a.js

/cgi/cgi_firewall_d.js

/cgi/cgi_firewall_mac.js

/cgi/cgi_firewall_main.js

/cgi/cgi_firewall_rule.js

/cgi/cgi_firewall_rule_a.js

/cgi/cgi_firewall_spi_h.js

/cgi/cgi_firewall_u.js

/cgi/cgi_lan.js

/cgi/cgi_nas_admin.js

/cgi/cgi_nat.js

/cgi/cgi_nat_m.js

/cgi/cgi_nat_show.js

/cgi/cgi_nat_sp.js

/cgi/cgi_nat_v.js

/cgi/cgi_ntp.js

/cgi/cgi_qos_addrule.js

/cgi/cgi_qos_main.js

/cgi/cgi_qos_traffic_map.js

/cgi/cgi_qos_wifi.js

/cgi/cgi_security_log.js

/cgi/cgi_sharedFolder.js

/cgi/cgi_status.js - Config info (including WPA keys)

/cgi/cgi_sys.js

/cgi/cgi_sys_bk.js

/cgi/cgi_sys_p.js - Device admin credentials

/cgi/cgi_sys_r.js

/cgi/cgi_system_info.js

/cgi/cgi_tr69.js - Remote management credentials

/cgi/cgi_upnp_main.js

/cgi/cgi_usb.js

/cgi/cgi_usb_basic.js - USB device credentials

/cgi/cgi_wan_eth.js - ISP user credentials

/cgi/cgi_wifi_1X.js

/cgi/cgi_wifi_e.js

/cgi/cgi_wifi_id.js - SSID list and keys

/cgi/cgi_wifi_main.js

/cgi/cgi_wifi_wep.js - WEP keys

/cgi/cgi_wifi_wpa.js - WPA keys

/cgi/cgi_wireless_advance.js

/cgi/cgi_wireless_wps.js - WPS PIN


Hijacking Your Broadband Account

As mentioned above, the /cgi/cgi_wan_eth.js file exposes my ISP user credentials. The password that the router uses to connect to the EE network is also the password that EE use to verify my identity when calling them. As the password is just base64 encoded in the file it's incredibly easy to make a quick telephone call to EE customer support and access my account. The only thing I was asked when dialling through to the cancellation team was my name, my telephone number and the 2nd and 4th character of my password. To add insult to injury, EE obviously don't even hash the passwords that they store... In most instances obtaining the name of the account holder and the telephone number could be done very easily with a little social engineering. Imagine a sales call from a "rival ISP" asking to speak to the current account holder, they already have your phone number and they're about to get your name, too. At a home or small business address it would be incredibly easy to obtain this information. The telephone directory and/or the electoral register would provide this information in most circumstances anyway. To make matters even worse, a little further down I will detail a method to allow you access to this information remotely. Not only could a malicious attacker incur some hefty cancellation fees on your account and leave you without any internet connection, they wouldn't even have to get out of their chair.


Cross Site Request Forgery

To determine if the device was also vulnerable to CSRF, I started tracking some of the POST requests in Fiddler and I decided to replay some forged requests to see how easy it would be to control the device. Taking a look at the initial request it looks pretty standard; this is for a device reboot.



Nothing out of the ordinary and no anti-CSRF so I was good for a straight up replay which rebooted the device nicely. Even cutting the request right down in Fiddler I still got a successful device reboot so it appears that it's using the source IP as my authentication to control the device.



This makes for a nice, simple html form. Of course, there is no need for the submit button, you could just fire it with JS, but for the purposes of demonstration it's nice to have a button.



The command for a factory reset is frighteningly similar and whilst CSRF requires the user to be logged in to the device, it still has the potential to do some real harm. If embedded into a page such as the EE help forums, or any internet/broadband related help forum, for example, it could have some devastating effects on people visiting the pages. Again, I realise that this is an incredibly narrow attack vector, and most people probably wouldn't even consider it worth patching, but an attacker does have the scope for a lot of harm. With a single POST request an attacker can enable a secondary or tertiary WiFi network, assign an SSID of their choosing and set a WPA PSK. Unless you have serious suspicions about what would most likely appear as a neighbour having a new WiFi access point, the attacker now has the ability to access your network at will. As demonstrated above they can then gain administrative access to the device and recover your ISP credentials to pass account security over the phone. A long shot, but all perfectly feasible with a little social engineering. I've setup a CSRF demo page here for you to try out.


Exploiting The Device Remotely

Whilst digging through some of the files with obscure names, it became apparent that one of them was the administration options for remote management of the router over the Internet. The page can only be viewed once you're logged in to the router and is then protected by another, different password. After some investigation I couldn't find a way to bypass it. Here is a link to the page: z983erv3210ba.htm



It seems the password protection is handled in JavaScript, as disabling JavaScript on the page loaded up the form.



Rather than trying to bypass the password, I decided to see if I could construct a forged POST request and set the configuration variables myself, without using the form. The file cgi_sys_r.js from the list above has some interesting variables, "rm_en", "rm_start_ip" and "rm_end_ip". I took a guess that these were remote management (rm) variables and we had enabled (en) and then the start and end ip for allowed client connections. The required CMD parameter for the POST request can be looked up in the subformvar.js file. This file lists all the possible values of the parameter and the "SYS_RMT_MGMT" one looked like the one for the job.



With this we can construct the first part of the POST request, "CMD=SYS_RMT_MGMT&GO=system_p.htm". The "GO" parameter is simply where we want to end up after the request is completed. Next up we need to assign values to the fields on the form. Fortunately, this is done with the unique ID for each field that is stored alongside it's value in the appropriate file in the /cgi/ folder. Going back to  cgi_sys_r.js we can see the three ID values we need.



Now with the ID numbers we can construct the rest of the request. You can submit as many parameters as you want on one page and they are simply labelled sequentially as SET0, SET1, SET2 etc... To set the "rm_en" variable to '1' we would use SET0=117703168%3D1. The %3D is just the hex code for an equals sign '=' so the parameter reads 117703168 = 1. All of the query parameters are now:


CMD=SYS_RMT_MGMT
GO=system_p.htm
SET0=117703168%3D1
SET1=117768704%3D0.0.0.0
SET2=117834240%3D255.255.255.255

With that done, we can use the Composer in Fiddler to construct the POST request and submit it to the router. Once submitted, you should be able to see the new values in the  cgi_sys_r.js file.




Now, with everything set, the only thing left to do is to visit your public IP and see if the web admin login is available, but more importantly, if the device leaks all your sensitive data publicly too. I decided to use my phone over 3G to rule out any conflicts. If you visit your external IP from inside your network, the router serves up the web admin login anyway. This is not remote management as it happens before you enable remote management, it's just some odd behaviour on behalf of the router.




Oh dear... That means, with a little CSRF, I can enable remote management on your router and steal all of your sensitive data like WPA keys, ISP credentials and the md5 hash of your admin password over the Internet. Once I've cracked the hash I can login and do just about anything I like with your device or not bother with any of that and just call EE to cancel your internet connection. To try and restrict access to the remote management config page but then still allow the feature to be enabled is a huge oversight, especially considering how much data the device leaks! What's even worse is that there are bugs and odd behaviour taking place over the web interface that aren't normally present. If an admin is logged in to the web interface and another device on the network visits the page, you get a message saying an admin is already logged in and there isn't much you can do. However, if an admin is logged in from the local network and then someone visits your public IP, the device hands over the valid session to the visitor on the public IP and kicks you out!!! No effort required, just visit the IP of the device, that's it.



It's now incredibly obvious why EE disabled this feature in a previous firmware patch. An attacker could quite easily traverse the entire collection of EE IP address ranges collecting the md5 hashes of each device as they go, along with every other bit of information exposed. Each device does have a unique password but given the relatively weak strength there are only just over 2 billion combinations. The passwords are 6 characters long and contain only lower case letters and numbers. With even a low end GPU in your computer, a rainbow table is almost a waste of time given that Hashcat can easily generate md5 hashes to the tune of hundreds of millions per second without breaking a sweat. On any decent specification machine you could just crack them on the fly as you retrieve them. Once all the hashes have been cracked, the attacker would then be free to visit each and every device and take total control of every device they could access.


Into The Rabbit Hole

If you're interested in hardware hacking then read on to see how you can get a root terminal on the router, if not, feel free to jump to the Conclusion below. Whilst I came across some of the files referenced in this article by monitoring traffic, trying to capture them all by sniffing the traffic of every page on the router admin panel seemed like too much effort. It was time to delve a little deeper. I tossed caution to the wind and decided it was time to open this thing up and the first security measure didn't take too long to bypass. Does everyone hate these security screws?!




With the PCB out of the case I was able to spot the serial header, labelled 'J3' on the board, and soldered on some makeshift pins. They could have left the old ones in place for me...



There are four pins on the board, 1, 2 and 3, with number 4 not having a number printed on it. Pin 2 is Tx, pin 3 is Rx and pin 4, the one without a label, is the ground pin. Once I had the pins in place I could connect my PL2303 Serial to USB converter. This would allow me to open a console to the device from my PC.




With everything connected all you need is the COM port for the USB converter, in my case COM5, and the baud rate for the device which is 115,200. Grab yourself a copy of Putty and get setup with the router powered off, then hit 'Open'.




Now Putty is waiting for some activity on the serial port you can power the router on and should immediately see some output in the window.



As the router boots you should see a considerable amount of output, too much to list here so I've uploaded it to my PasteBin. Unfortunately though we don't get a root terminal. Having a look around online it seems that most of the hidden config pages on the earlier versions of the BrightBox router firmware have been disabled, except one http://192.168.1.1/u132xzp32aai.htm, manufacturer mode. Once 'manufactory mode' has been enabled the device will provide us with a root terminal over the serial port.




Once we have a root terminal onto the device, it's pretty much just a stripped down Linux machine. This means we can dig out a little info about the device like CPU and memory information.




It's also quite interesting that using netstat I can see the device is listening on port 5438 though I'm not exactly sure what for, it seems to drop into a redirect loop to 'login_guest.html'.



But, as there is a lot of poking around I could do with the device I decided to record most of the outputs and upload them all to my PasteBin account. You can find everything there. As I was initially interested in what other files I could find in the /cgi/ folder a quick 'ls' of the directory revealed the following.



Using the rather handy USB port, I connected a flash drive, which is automatically mounted under /mnt/, and dumped out a copy of the entire /www/ folder for inspection. It's quite odd, having a brief look over some of what's included, that this is actually production code. I realise that a web interface for a router hardly needs to be optimised, but the code is littered with comments, example code and references to bug ID numbers and their outcomes for starters. Jack, if you're reading this, please don't comment out huge chunks of code saying "we no longer need this", just delete it! A simple JS minification would have reduced some of these files by up to 64%!!! It's also quite worrying that some of the bug fixes are dated as far back as 27 Feb 2007... The router also contains a lot of outdated image resources and Orange branding from the previous generation of firmware before EE took the helm. Do we not even bother tidying up after ourselves these days?




I realise that before I started any of this that the device has already revealed the MD5 hash of the administrator password. At that point all is pretty much lost. However, if an attacker can't crack the hash in time to use it, or may not have an opportunity to return once they do crack it, having access to all of the information exposed in these files could prove incredibly useful. It would allow you to quickly grab the WPA keys, DDNS account credentials or ISP/3G user credentials. Whilst my little venture into the internals of the BrightBox didn't reveal anything as drastic as I'd hoped, it was still interesting and useful to take a look around.


Conclusion

Being able to grab details like the WPA keys or the hash of my admin passwords was bad enough, but exposing my ISP user credentials represents a huge risk. This is made even worse by the fact it's possible to access all of the data remotely. Even if the device is only used in the home or small office, this represents a total compromise of the device's security and an attacker could wreak havoc with your account causing huge inconvenience and even financial losses. Whilst a session fixation attack, or a session hijacking attack, could get you access to the web interface as an admin, it would not expose the password and you wouldn't be able to gain access again after the session had expired or was invalidated. Yes, you could always try and sniff the password from the initial login, but you would be dependant on local network access and someone logging in to the admin interface for you to carry out the attack. With the details being available to any client on the network at any time, there are no such restrictions and the CSRF exploit means you don't even need local access. Anyone on the network could compromise the device at will and a targeted social engineering attack could be easily crafted to gain remote access. Just because we allow people access to our network, we certainly aren't intending to allow them access to this kind of sensitive information and exposing it over the WAN interface is the nail in the coffin.


Responsible Disclosure

Initially I had some difficulties trying to contact EE via their customer services email and going through their call centre was a lengthy and arduous task, which I gave up on. I sent them a couple of tweets informing them that I had found some vulnerabilities and asked them to follow and DM me and took a similar approach on Facebook. Eventually I gave up and emailed the CEO and CTO directly. Be it chance, or a reaction from going directly to the top, I had a response from the Head of Security Operations a few hours later. I explained the issues I had found and a day later I got a response confirming there was indeed an issue. As EE seemed keen to resolve the issues quickly, I offered to refrain from disclosing my findings until the patch was available, in the interest of protecting those affected. Initially the issue was supposed to be patched in December, but after several weeks of updating them with new findings, things started to slow down. I was then informed that a new firmware was in testing and that it would be deployed to all affected devices, remotely, by mid January, which included extra time allowances. At the time of publishing, the latest information I have is that the firmware is back in development to resolve further issues found during testing. Updates and information from EE regarding when this might be patched seem to have dried up completely. I don't even have an estimate of when the patch will now be available and my questions remain unanswered. I strongly considered when to publish this blog, but after much debate, I decided it was in the interest of the public to do so, due to the lack of confidence I now have in EE.


Replacing The BrightBox Router

I always replace the routers provided by my ISP for several reasons. The hardware isn't usually up to standards, your ISP generally has far more access than I'd care to allow them and the firmware on the device is usually a bit flakey. I replaced my BrightBox with the Asus RT-N16 and loaded up the opensource firmware from DD-WRT. Running a custom firmware like DD-WRT gives me a rock solid device, allows me to harness the full potential of the hardware and gives me considerably more options like VPN integration, hotspot capabilities, bandwidth monitoring and much, much more.



Now that I had no use for my old BrightBox router, I didn't really see any reason to keep it around...


Update 17 Jan 2014

An EE spokesperson has provided the following:

"We are aware of Mr Helme's article. As is the case for all home broadband customers, regardless of their provider, it is recommend they only give network access to people they trust. Customers should also be suspicious of any unsolicited emails and web pages, and keep their security software up to date.

“We treat all security matters seriously (no personal data will be compromised by the device itself), we would like to reassure customers that we are working on a service update which we plan to issue shortly, and which will remotely and automatically update customers’ Brightboxes with enhanced security protection.”