Thursday, September 25, 2014

Shellshocked: what is the bug in Bash?

The Internet has been awash with information and misinformation about a bug in GNU bash, a common system shell in many Unix variants. Here are some initial thoughts about what it is, and what it is not.

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 is not a bug. Bash is a program, which contains a bug, commonly referred to as the "shellshock bug." It's not a virus, or worm, or other malicious activity. It's a serious bug, but until someone writes malware to exploit the bug, that's all it is.

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:


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.