I received an email today from a friend and fellow Linux sysadmin, Todd Lyons, informing me of a very sneaky way to exploit the Shellshock vulnerability under what he calls “just the wrong conditions.”
Here’s how his email starts out:
With your recent blog post, you might also want to advise people to further look around their systems to see if they need to restart any services. If non-trusted users have shell accounts, you can still access the old (replaced) bash binary under just the wrong conditions:
Todd went on to share with me bits of an IRC chat where he explains the exploit further:
I found a sneaky way, not good for uptime :-(, to exploit the shellshock vulnerability.
if you do lsof | grep bash, and any of them are state “deleted”, it’s simple to merely call it.
A good example is mysql, which gets started by “/bin/sh /usr/bin/mysqld_safe”. If your /bin/sh is symlinked to /bin/bash (yes
for RH/CentOS, no for Debian/Ubuntu, probably not for most unixes), then it works because the old deleted one is still in memory.
# lsof | grep bash | grep deleted
mysqld_sa 20470 root txt REG 8,1 903336 268382 /bin/bash (deleted)
# env var='() { ignore this;}; echo vulnerable’ /proc/20470/exe -c /bin/true
vulnerable
:-/
Todd finished up his email to me by stating that he wasn’t sure that it’s “exploitable” to get root elevation, but that if a sysadmin doesn’t know about this potential method of “resurrecting” the deleted bash binary that’s still in memory, the system could still technically be vulnerable, even after patching.
I tested this on my patched Fedora 12 test system, and found exactly what Todd predicted:
# lsof | grep bash mysqld_sa 1714 root txt REG 253,0 861128 14303268 /bin/bash (deleted) bash 24123 root cwd DIR 253,0 12288 3768321 /etc bash 24123 root rtd DIR 253,0 4096 2 / bash 24123 root txt REG 253,0 2280202 14303310 /bin/bash
Right there, as process 1714, the deleted /bin/bash binary was still in memory. And even though my system had been patched, I was able to produce a “vulnerable” output with:
# env var='() { ignore this;}; echo vulnerable' /proc/1714/exe -c /bin/true vulnerable
Restarting the service (in this case, mysqld) did the trick:
# service mysqld restart Stopping MySQL: [ OK ] Starting MySQL: [ OK ] # lsof | grep bash mysqld_sa 7285 root txt REG 253,0 2280202 14303310 /bin/bash
I also checked on a production CentOS 6 box that I’d patched with the “official” patch from the repositories:
]# lsof | grep bash sh 5941 root txt REG 253,0 938832 921278 /bin/bash (deleted) mysqld_sa 7782 root txt REG 253,0 938832 921733 /bin/bash (deleted) sh 14553 root txt REG 253,0 938832 921278 /bin/bash (deleted)
Yep! Three naughty binaries right at the top of the list. I had to restart MySQL on this server too, and kill and restart the shell scripts that were attached to the other two processes.
So, as Todd suggests, after patching your system against Shellshock, you should check to see if anything in memory is still “holding on” to the old binary. And if they are, kill or restart the process to banish your old vulnerable binary forever.
Another solution, if you’re willing to reset your uptime, is simply rebooting your server.
Of course, the level of threat of an external attack using this vector is unlikely. Todd notes that “it’s limited to users having local shell accounts already, so the remote aspect of it is removed. But the vulnerable version is still in memory, and a local vulnerability is bad too.”