Apple has yet to patch the Shellshock vulnerability (Bash specially-crafted environment variables code injection attack) found by Stephane Chazelas (see also http://seclists.org/oss-sec/2014/q3/650)
Update
Apple released patches for Lion, Mountain Lion and Mavericks:
OS X bash Update 1.0 – OS X Lion
OS X bash Update 1.0 – OS X Mountain Lion
OS X bash Update 1.0 – OS X Mavericks
You should soon see the update for your OS (not yet for Yosemite) in the App Store!
People who don’t like to wait… here is what you can do:
1.) download the bash-92 tarball here.
2.) unpack it (double click on it).
3.) cd into the bash-92 directory
4.) launch: patch -p1 < ../bash_52.patch
And that should end with:
patching file bash-3.2/builtins/common.h
patching file bash-3.2/builtins/evalstring.c
patching file bash-3.2/patchlevel.h
patching file bash-3.2/variables.c
5.) compile bash/sh (launch Xcode)
6.) replace: /bin/bash and /bin/sh with the compiled files from:
~/Library/Developer/Xcode/DerivedData/bash-[salt]/Build/Products/Release
7.) verify version info with the info at the bottom of this article.
The patch to remedy this specific vulnerability can be found below, and can be downloaded from GNU project archive.
diff -uwr bash-92/bash-3.2/builtins/common.h bash-93/bash-3.2/builtins/common.h
--- bash-92/bash-3.2/builtins/common.h 2009-06-12 01:29:43.000000000 +0200
+++ bash-93/bash-3.2/builtins/common.h 2014-09-25 01:52:13.000000000 +0200
@@ -33,6 +33,8 @@
#define SEVAL_RESETLINE 0x010
/* Flags for describe_command, shared between type.def and command.def */
+#define SEVAL_FUNCDEF 0x080 /* only allow function definitions */
+#define SEVAL_ONECMD 0x100 /* only allow a single command */
#define CDESC_ALL 0x001 /* type -a */
#define CDESC_SHORTDESC 0x002 /* command -V */
#define CDESC_REUSABLE 0x004 /* command -v */
diff -uwr bash-92/bash-3.2/builtins/evalstring.c bash-93/bash-3.2/builtins/evalstring.c
--- bash-92/bash-3.2/builtins/evalstring.c 2009-06-12 01:29:43.000000000 +0200
+++ bash-93/bash-3.2/builtins/evalstring.c 2014-09-25 01:58:33.000000000 +0200
@@ -234,6 +234,14 @@
{
struct fd_bitmap *bitmap;
+ if ((flags & SEVAL_FUNCDEF) && command->type != cm_function_def)
+ {
+ internal_warning ("%s: ignoring function definition attempt", from_file);
+ should_jump_to_top_level = 0;
+ last_result = last_command_exit_value = EX_BADUSAGE;
+ break;
+ }
+
bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
begin_unwind_frame ("pe_dispose");
add_unwind_protect (dispose_fd_bitmap, bitmap);
@@ -291,6 +299,9 @@
dispose_command (command);
dispose_fd_bitmap (bitmap);
discard_unwind_frame ("pe_dispose");
+
+ if (flags & SEVAL_ONECMD)
+ break;
}
}
else
diff -uwr bash-92/bash-3.2/patchlevel.h bash-93/bash-3.2/patchlevel.h
--- bash-92/bash-3.2/patchlevel.h 2013-01-22 02:37:34.000000000 +0100
+++ bash-93/bash-3.2/patchlevel.h 2014-09-25 01:51:19.000000000 +0200
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 51
+#define PATCHLEVEL 52
#endif /* _PATCHLEVEL_H_ */
diff -uwr bash-92/bash-3.2/variables.c bash-93/bash-3.2/variables.c
--- bash-92/bash-3.2/variables.c 2009-06-12 01:29:43.000000000 +0200
+++ bash-93/bash-3.2/variables.c 2014-09-25 02:03:54.000000000 +0200
@@ -318,12 +318,10 @@
temp_string[char_index] = ' ';
strcpy (temp_string + char_index + 1, string);
- 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';
+ /* Don't import function names that are invalid identifiers from the
+ environment. */
+ if (legal_identifier (name))
+ parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
if (temp_var = find_function (name))
{
@@ -332,10 +330,6 @@
}
else
report_error (_("error importing function definition for `%s'"), name);
-
- /* ( */
- if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
- name[char_index - 2] = '('; /* ) */
}
#if defined (ARRAY_VARS)
# if 0
Is my version of bash/sh Vulnerable?
Most likely yes. You can verify this in two ways.
1.) run this terminal command:
bash -version
If that reports something like this (Mountain Lion, OS X 10.8.5)
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin12)
Copyright (C) 2007 Free Software Foundation, Inc.
Or this with Mavericks (10.9.5 Build 13F34):
GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13)
Copyright (C) 2007 Free Software Foundation, Inc.
And this with Yosemite (10.10 Build 14A343f):
GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin14)
Copyright (C) 2007 Free Software Foundation, Inc.
Then your version of OS X is vulnerable! After you have applied the patch you should see this:
GNU bash, version 3.2.52(1)-release (x86_64-apple-darwin1[2/3/4])
Copyright (C) 2007 Free Software Foundation, Inc.
Note the new patch level (52) in the above lines.
2.) The second test is to run code in a shell by entering:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
If the output of the above command looks like this:
vulnerable
this is a test
Then your version of bash/sh is vulnerable, but this is what you should see with the patched version of bash/sh:
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x’
this is a test
Which is fine!