Qualys Blog

Prutha Parikh

Bash Shellshock Command Injection Vulnerabilities

Shellshock (CVE-2014-6271)

Bash or Bourne Again Shell is prone to a remote code execution vulnerability in terms of how it processes specially crafted environment variables. Most Linux and Unix based systems are vulnerable since the Bash shell is one of the most common installs on a Linux system and is widely used. A lot of programs like SSH, telnet, CGI scripts allow bash to run in the background allowing the vulnerability to be exploited remotely over the network which makes it more scary. Refer to Wolfgang’s post BASH Shellshock vulnerability – Update5 for more details on the vulnerability.

Proof of Concept

A simple test to check if your Bash is vulnerable is available publicly.

$ env var='() { ignore this;}; echo vulnerable' bash -c /bin/true

Upon running the above command, an affected version of bash will output "vulnerable".

Once the patch has been applied, the same test will return the following result.

bash: warning: var: ignoring function definition attempt
bash: error importing function definition for 'var'

The way this proof of concept works is that bash functions can be exported to environment variables. When code is added to the end of the function definition inside the variable, it gets executed when the shell is invoked ("bash -c"). In this case "echo vulnerable" will execute. Once the patch has been applied, code execution after end of the bash function is not allowed. A detailed explanation of the issue can be found at: Bash specially-crafted environment variables code injection attack | Red Hat Security

Authentication is required to exploit this vulnerability via SSH, but there are variables like HTTP/CGI which make remote code execution over the network possible, widening the areas of exploitation.

Incomplete fix to Shellshock (a.k.a AfterShock – CVE-2014-7169)

Update: The bash fix for CVE-2014-6271 was incomplete and command injection is possible even after the patch has been applied. The issue is being tracked as CVE-2014-7169 and exists due to incorrect function parsing. Details can be found here: Bug 1146319 – CVE-2014-7169 bash: code execution via specially-crafted environment (Incomplete fix for CVE-2014-6271)

Proof of Concept

$ env var='() {(a)=>\' bash -c "echo date"; cat echo

A target patched for CVE-2014-6271 will output the date upon executing the following PoC.

bash: var: line 1: syntax error near unexpected token `='
bash: var: line 1: `'
bash: error importing function definition for `var'
Thu Sep 25 17:52:32 EDT 2014

Additional CVEs related to Shellshock (CVE-2014-6277,CVE-2014-6278,CVE-2014-7186,CVE-2014-7187)

There are also reports about two other issues which may be used to circumvent the original patch (CVE-2014-6277 and CVE-2014-6278). Refer to lcamtuf’s blog for a detailed explanation on these issues.

Proof of Concept

$ var='() { echo "vulnerable to CVE-2014-6278"; }' bash -c var

An affected host will output "vulnerable to CVE-2014-6278". A non-affected host will output the following:

bash: var: command not found

For two other likely non-exploitable one-off issues (CVE-2014-7186 and CVE-2014-7187) refer to this link at oss-security

Qualys Detection

Qualys has already released QID 122693 to detect CVE-2014-6271. QID 122698 covers CVE-2014-7169, CVE-2014-6277, CVE-2014-6278, CVE-2014-7186 and CVE-2014-7187. The QIDs are detected via SSH using a similar concept explained in the proof of concepts above. We also have QID 13038 that detects the Shellshock vulnerability remotely. For a detailed explanation on the remote detection, refer to Qualys QID 13038: Remote Detection for BASH ShellShock. We recommend that customers patch this vulnerability as soon as possible.

16 responses to “Bash Shellshock Command Injection Vulnerabilities”

  1. Am I missing something with the second test string? I get:

      env var='() {(a)=>\' bash -c "echo date"; cat echo  

    which by my reading should echo the word date not the output of the date command. leaving off the cat (which is presumably also missing something) and adding backticks we get:

      env var='() {(a)=>\' bash -c "echo `date`"

    where we DO get the output posted, but as far as I can tell this is simply normal operation for the env command.  if I substitute

      env var='x\' bash -c "echo `date`"

    I also get the date output (env var=val <command> is normal syntax); there is no trace of anything inside the variable being executed. now running

      env var='x\'

    shows "var=x\" pretty much as you would expect (the \ is not acting as an escape character). further, if I substitute

      env var='() { /bin/date; }' bash -c "var"

    then again, we have correctly used env to define a function-style variable, and if called it executes, but it executes only if called – now, if you substitute a real command for var, you can replace the command with your own, but that has been known to be an issue for decades, hence certain programs refusing to start unless you specify their absolute path rather than allowing the path to find them.

    So, clearly, I am missing something here; can someone point out my error?

  2. Signature file was updated from 2.2.831-5 to 2.2.831-6, What was fixed, do we need to re-scan again with the new Signature file update?

  3. In reference to: CVE-2014-6277

    -You have this command listed to check vulnerabilities: $ var='() { echo "vulnerable to CVE-2014-6277 and CVE-2014-6278"; }' bash -c var

    -Other sites have: bash -c "f() { x() { _;}; x() { _;} <<a; }" 2>/dev/null || echo vulnerable

    Question: Which one is correct because your command states that I am not vulnerable while the second command states vulnerabilities on my shell?

    -Please explain discrepancy

  4. Peter: To be precise, the exploit var='() { echo "vulnerable to CVE-2014-6277 and CVE-2014-6278"; }' bash -c var is for CVE-2014-6278 and the exploit your mentioned is for CVE-2010-6277. The reason, we just had one in the explanation is because most vendors patched both of them together. Also, the exploit for CVE-2014-6277 might lead to a denial of service and cannot be used when writing Qualys checks since they are non-intrusive. So the two were clubbed together. I updated the blog to avoid the confusion.

Leave a Reply