A shell is a way of giving a computer commands, that it in turn executes. The Windows CMD shell (aka "DOS Prompt") is one example of a shell. Unix has many different shells, but a common one is bash, or "Bourne Again SHell." It is common in Unix and Linux variants ... which happen to be the operating system of choice for a great many non-PC Internet devices. Think wireless routers, Blu-Ray players, network hard drives, printers, Internet TVs, etc. Not all run bash - as I said there are a number of different shells - but many do.
Note: this post is largely a record of my own notes and references I have found useful, hence the large number of links. I will follow it up with things you can and should do as a consumer. |
Bash allows you to define static variables:
x = 'foo'
It also allows you to define variables in the form of functions:
x = '() {do something;}'
The variable is defined - but never executed unless you explicitly call it. In the right context, this is perfectly sensible: if you have access to the shell, then you should rightfully expect access to run commands with the shell. The fun occurs because bash does not stop processing at the end of the function:
x = '() {do something;}; do something malicious'
Here is an example on a vulnerable version (demonstrated on a Kali Linux image on Raspberry Pi):
The command that follows the end of the function is executed immediately. That command could be a simple pingback, or it could be to download and execute a reverse shell, or anything else that an attacker wishes. It will be executed with the same privileges as the bash shell itself is executed.
Herein lays the rub: a variety of web-accessible services use the system shell to execute some actions. This includes cgi, php, perl, and even some dhcp clients. The end user (the web browser) was never intended to have shell access - they were only allowed access to the web application, which in turn called out to the shell. If these services are run as a privileged user, then when they execute the shell, the attacker's code is immediately executed with privileged access.
What makes this easy to exploit is that http headers are automatically converted into shell environment variables, as part of the CGI standard. So I can set a user-agent string that exploits the bug:
curl -A "() { foo;};do something evil" http://192.168.0.1/file.cgi
Curl is something of a glorified command-line web browser; -A sets the user-agent header string (which is converted into an environment variable). http://192.168.0.1/file.cgi is the path to a cgi script on a vulnerable device on your network. Say for example your DVR has an admin control panel of http://dvr_ip/admin.cgi; executing the following would exploit the bug and erase the contents of your DVR:
curl -A "() { foo;};rm -rf /" http://dvr_ip/admin.cgi
A simple method of testing is to instead do this:
curl -A "() { foo;};ping router_ip" http://dvr_ip/admin.cgi
This would cause the DVR to ping your router; you could then check the router log to see if it received a ping. If so, it tells you the DVR is vulnerable.
Keep in mind web servers (HTTP/HTTPS) are not the only way to remotely exploit this bug. Certain ssh daemons are known to be vulnerable, as are certain dhcp clients. If a service is listening for connection requests, and that service executes any sort of shell command that invokes bash, it could be exploited.
The good news is, you cannot (usually) exploit this merely by browsing to the home page on a vulnerable device. You have to launch a cgi script that includes a shell call - which means you have to either know the location of a specific vulnerable cgi script, or have to try an awful lot of possibilities before stumbling across the right one. The bad news is, so far the patches released do not fully fix the bug. Essentially, we are in a race between developers (fixing code and creating detection / prevention signatures for firewalls and such) and malicious hackers (likely working to write self-propagating worms to take control of as many vulnerable devices as possible). Early proofs of concept simply checked for existence of the bug, but malicious uses will surely follow soon.
Stay tuned as the saga unfolds...
Some useful references:
- Troy Hunt's write-up
- Errata Rob's mass-scan
- SANS Internet Storm Center summary
- NIST VDB record for CVE-2014-6271 (original bug)
- NIST VDB record for CVE-2014-7169 (partial fix bug)
- Invisible Threat report, with notes on some RCE gotchas
- Brian Krebs write-up
- Mac Security Blog notes on OS X
- FireEye report on attacks in the wild
- Brian Krebs Apple OS X story
- Apple OS X patches: Mavericks, Mountain Lion, Lion
- InfoSec Nirvana recap of exploit vectors
- lcamtuf's blog on some RCE POCs, debunking the original patches
One final note: this post covers the technical details of the shellshock bug. For a followup article discussing the implications for most home users, see A Shell of a Bash.