On Wednesday, the world learned about a bug in the popular Unix, Linux, and Mac OS X command line interpreter Bash.
Discovered by engineers at Red Hat,
this bug is known as Shellshock, and allows an attacker to run commands
in the Bash shell. Since the bug was announced, Bash has been updated
for the major platforms it affects—so it’s pretty easy to update and
protect systems.
But there’s a problem: Bash is so widespread, and installed on so
many devices—such as cable modems, routers, and other devices with
embedded Linux operating systems—that it will be difficult, if not
impossible, to fully patch everything that’s affected. (Windows users
are generally unaffected by Shellshock, unless they’ve specifically
installed Bash along with Cygwin, Git Bash, or other third-party
packages.)
And that’s what makes it so important to update and protect what you’re able to fix.
A quick bit of test code has been making the rounds on the Internet,
which lets you know whether the version of Bash you have installed is
vulnerable to Shellshock. In particular, it contains a malformed
environment function, in this case x:
env x='() { :;}; echo vulnerable' bash -c "echo done running"
Paste that into the command line on your system, being sure to get
the quotes right: single quotes after “x=”, and also after “vulnerable”,
and double quotes around “echo done running”. Make sure that your
system hasn’t converted them to smart quotes.
If your version of Bash is vulnerable, the shell will incorrectly
interpret this environment function, and will execute the command after
it—in this case, a very innocent ‘echo’ command that prints the word
‘vulnerable’.
And you can see that’s exactly what happened. An attacker could use
similar code, but with a more malicious command or set of commands. This
code could be delivered in various ways, such as through a CGI script
on a web server.
Now let’s take a look at how to fix it.
Updating Bash on Ubuntu / Debian
On Ubuntu, you’ll want to make sure to get the latest information from the update repositories:
sudo apt-get update
And then you’ll want to get the latest version of bash:
sudo apt-get install bash
Next restart the system.
You’ll then run the test code from earlier. Here I’ll do the same:
In my example, you can see instead of ‘vulnerable’, I get some
errors, where the updated version of Bash caught the error, and reacted
correctly.
Updating Bash on CentOS / Red Hat
On CentOS, you’ll need to install the latest version of Bash:
sudo yum update bash
Then restart the system.
After that, run the test code. It’s catching the problem now, instead of executing the code it shouldn’t be running:
Updating Bash on Mac OS X
On Mac OS X, the operation is a little bit more complicated. The Mac
platform doesn’t have a package manager like apt or yum provided by
Apple, so until Apple makes an update available, we need to either build
an updated version of Bash from source, or use one of the third-party
package managers that are available.
Heads up: although I’ll step through how to
update Bash using the command line below, I strongly recommend that you
use any official patch Apple provides, when it becomes available. If
you’re not a developer, or are unfamiliar with command line workflows,
it’s probably in your best interest to wait until Apple makes a more
automated patch available through the App Store.
Using the Homebrew Package Manager
First let’s take a look at updating Bash with the Homebrew package manager.
Homebrew is a package manager, similar to apt or yum, which allows
Mac users to install open-source packages from the command line. To
install it, paste this line into your Terminal. Further information
about HomeBrew is
available on their website, at brew.sh.
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Then, run:
brew doctor
brew update
And type:
brew upgrade bash
This will download and build the current version of Bash, and put it into a private folder: /usr/local/Cellar/bash/4.3.25/bin.
You’ll need to replace your system’s copy of Bash with this version. First make a backup copy of the existing version:
sudo cp /bin/bash /bin/bash.previous
And make sure a clever attacker can’t easily run your backup copy:
sudo chmod a-x /bin/bash.previous
Then copy Brew’s version to your /bin folder:
sudo cp /usr/local/Cellar/bash/4.3.25/bin/bash /bin
And restart your system.
Running the test code, I can see that this version of Bash is patched.
Building from source
Next let’s take a look at building Bash from source. To do this,
you’ll need the Xcode developer tools, available from Apple. I’ll
download the source code for Bash from Apple:
curl -O https://opensource.apple.com/tarballs/bash/bash-92.tar.gz
Then unpack it:
tar zxf bash-92.tar.gz
Go into the source code folder:
cd bash-92
cd bash-3.2
After that, I’ll download the patched code from the GNU Foundation:
curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-052 | patch -p0
and I’ll pipe it to the patch command to apply the changes.
I’ll move up a directory:
cd ..
Then I’ll use xcodebuild to build the source code:
sudo xcodebuild
This leaves me with two executable files in the Release build folder: bash and sh:
cd build/Release
ls -lah
Now I’ll make backup copies of my existing versions of these, just in case:
sudo cp /bin/bash /bin/bash.previous
sudo cp /bin/sh /bin/sh.previous
And I’ll make them not executable:
sudo chmod a-x /bin/sh.previous /bin/bash.previous
Then replace the old versions with the patched versions:
sudo cp bash /bin
sudo cp sh /bin
I’ll restart the system.
Now, when I run the test code, I can see that my version of Bash has been patched.
Of course, you should also keep an eye out for, and install, any
relevant firmware updates released by device vendors. Stay safe out
there!
UPDATE 5/26/2014
On September 26th, a second vulnerability in Bash was patched. This
patch has been added to the RedHat and Ubuntu repositories, so if you
patched your system before the 26th, you’ll need to do it again to get
the patch for the second vulnerability. If you haven’t, just follow the
steps for your Linux distribution listed below.
The patch has not yet become available for Mac OS X, but Apple
reports that they are working on a fix. Mac users, keep an eye out for a
Security Update from Apple.
You can test for this vulnerability by pasting this command into your terminal:
env X='() { (a)=>\' sh -c "echo date"; cat echo
If you see the current date and time, your system is vulnerable — the
shell is interpreting the ‘echo date’ command incorrectly (it should
return ‘date’) but instead it’s running date as a command. It’s innocent
in this example, but could be replaced with a malicious command by a
less-than-ethical attacker:
If you don’t see the current date and time, your system has a patched version of the shell: