Quantcast
Channel: Steve Jenkins – Steve Jenkins
Viewing all articles
Browse latest Browse all 177

How to Manually Update Bash to Patch Shellshock Bug on Older Fedora-Based Systems

$
0
0

With the announcement of the Shellshock Bash Bug, Linux admins around the world have been scrambling to patch their Bash shells so that they’re no longer vulnerable to the exploit.

If you have a Fedora, RHEL, or CentOS system that hasn’t reached End-Of-Life, then updating to a patched version of Bash is as simple as:

sudo yum update -y bash

But what if you have an older Linux box, like the Fedora 12 box I keep around for testing, and an updated version of Bash isn’t available in the repos?

In that case, you can actually download the Bash source, manually apply all the patches, and compile and install it manually. It’s not as hard as you think!

Before You Start

It’s likely you’ve already done this step before coming here, but here’s how to check to see if you’re vulnerable to the Shellshock Bug (thanks to TheRegister for this test).

Check your vulnerablility by running the following lines (one at a time) in your default shell. If you see the word “busted”, you’re at risk and should update your Bash as soon as possible. If you don’t see “busted,” then your Bash is fixed or your shell is using another interpreter.

env X="() { :;} ; echo busted" /bin/sh -c "echo completed"
env X="() { :;} ; echo busted" `which bash` -c "echo completed"

Step 1: Back up your existing Bash binary

Find out where your existing bash binary is located on your system with:

which bash

You’ll get a response like:

/bin/bash

Backup that file with:

sudo cp /bin/bash /bin/bash.old

Step 2: Determine which version of Bash you’re running — and back it up

Now you’ll need to determining which version of bash your system is running. If you’re running Fedora 12, for example, it’s probably version 4.0. You can find out your version with:

bash --version

which will spit out a version number that looks something like this:

GNU bash, version 4.0.1-release (i686-redhat-linux-gnu)

This means you’re running Bash 4.0 (remember this number — it’s important later). But depending on how old your Linux version is, it could be as old as 2.0.

As you move through the following steps, resist the urge to try and change Bash versions… as you’ll probably end up causing more problems than you’ll fix. Patching your current version of Bash is the best option to ensure things keep working on your system.

Step 3: Set up your fix environment

Whenever I’m working with source code on a Linux box, I like to keep everything in the /usr/local/src directory. So create a new subdirectory for fixing bash, and then jump into that directory, with:

mkdir /usr/local/src/bashfix
cd /usr/local/src/bashfix

Step 4: Download the Bash Source

Locate the matching source code for the version of Bash you’re already running on the GNU.org FTP server. Since my test system was using 4.0, that’s what I’ll download in this example, but you should obviously download the one that’s appropriate for your system.

Again, resist the urge to upgrade to a newer version (such as 4.1, 4.2, or 4.3 in this example). This can potentially create serious problems. Just stick with what you’ve already got for now.

Download and extract the appropriate Bash source code into your fix directory with:

wget https://ftp.gnu.org/pub/gnu/bash/bash-4.0.tar.gz
tar zxvf bash-4.0.tar.gz

You should now have a new sub-directory containing the bash source. In this example, that directory is /usr/local/src/bashfix/bash-4.0.

Get into that directory with:

cd bash-4.0

Step 5: Download and Apply the Patches

If you check the GNU.org FTP server where you downloaded the source code, you’ll also see a few sub-directories for each major version that contain all the patches for that version. Different versions of Bash have a different number of patches.

In our example, the patches are located in https://ftp.gnu.org/pub/gnu/bash/bash-4.0-patches/. Checking that directory shows a total of 39 patches for version 4.0, from  bash40-001 to bash40-039.

Your first option is to download the first patch, apply it to the source code, then download the second patch, apply it to the source code, and so on. Don’t do this just yet, because I’m going to show you a faster way to do it. But you should at least understand what’s happening before you automate it.

The command you’d use to download the first patch and apply it in a single step would be (again, don’t do this… it’s just for illustration):

curl https://ftp.gnu.org/pub/gnu/bash/bash-4.0-patches/bash40-001 | patch -p0

That command uses curl to download the patch 001, then pipes the downloaded patch into the patch command, which patches the source code in that directory (you can check the patch man page for more details, if you want).

If you did this manually, you’d have to repeat this command it for each individual patch, changing the 001 to 002, and then again changing it to 003, and so on until you reached the final patch 039.

But my buddy Steve Cook helped me write a script (and stored it on GitHub as a Gist) that will automate all the patching for you. You just need to tell it the bash version you’re patching, and the total number of patches available for that version. Check it out:

Make sure you’re in the Bash source code directory you extracted, then download the “raw” version of the  bash-multipatch.sh script we wrote with:

wget https://gist.githubusercontent.com/stevejenkins/3d64d3543060c1bcac92/raw/b739c164b36ae77d1ebc89cbe580908ad2a5d4cc/bash-multipatch.sh

Edit the file with your favorite text editor and set the version, nodotversion, and lastpatch variables in the script to the appropriate values for your situation (the nodotversion is simply the version number of bash without a dot in the middle). In our example, the variables are 4.0 (because we’re using Bash 4.0), 40 (same as the version without the dot), and 39 (since there are 39 total patches available for this version of Bash).

Save your edited file, then make it executable with:

chmod 755 bash-multipatch.sh

Now run it inside the Bash source code directory with:

./bash-multipatch.sh

Depending on your connection speed, it shouldn’t take very long to download all the patches and apply them. You’ll see each download and patch happen on your screen as the script runs. Keep an eye out for any error messages. The very last one should look something like this:

https://ftp.gnu.org/pub/gnu/bash/bash-4.0-patches/bash40-039
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
102  3272  102  3272    0     0   8738      0 --:--:-- --:--:-- --:--:-- 44821
patching file builtins/common.h
patching file builtins/evalstring.c
patching file variables.c
patching file patchlevel.h

Now you’re ready to build the patched version of your bash binary.

Step 6: Build and Install your Patched Bash Binary

In the source code directory, do:

./configure

You’ll see your system check to make sure everything is ready for your build. If you don’t see any errors, go ahead and make the new binary with:

make

This might take a moment, depending on your system, when when it’s all done you should be able to do this command:

ls -la bash

And you’ll see a newly build Bash binary with a timestamp of just a few seconds ago, like this:

-rwxrwxr-x 1 root root 2273014 2014-09-26 08:37 bash

Now install your new binary with:

make install

Then check to see the location of your newly installed binary with:

which bash

When I did this on a Fedora 12 system, the new binary location was actually /usr/local/bin/bash. That’s fine. But I went ahead and copied my new bash binary file to /bin/bash just to make sure the old one was no longer on the system. I recommend you do the same, because /bin/sh is usually set up as a symlink to /bin/bash, and your system would still be vulnerable if /bin/sh still pointed to the old bash binary.

Step 7: Test Your Fix

Now that you’ve manually downloaded, patched, compiled, and installed a new bash, you should test it to make sure you’re no longer vulnerable.

Make sure your current shell session is using your newly compiled bash by simply running the new location from the command line. In this example, that would be:

/usr/local/bin/bash

Then do the exploit tests again:

env X="() { :;} ; echo busted" /bin/sh -c "echo completed"
env X="() { :;} ; echo busted" `which bash` -c "echo completed"

If you don’t see “busted,” you’re good to go!

Make sure you log out of any current shell sessions and log in again using your new shell. Congratulations on a successful fix!

As always, I welcome your questions, comments, and feedback below!

Further Reading:

Thank you to the authors of these blog posts, which were helpful in patching Bash on my “outdated” Fedora 12 test box, as well as in writing this post.

 


Viewing all articles
Browse latest Browse all 177

Trending Articles