How to unofficially fix the ‘Shell Shock’ bash vulnerability in OS X

NewTerminalIconXThe recent vulnerability that has affected systems running the popular Bash shell can allow an attacker to arbitrarily run code on any system that has a running installation of the unpatched bash shell. This includes every version of OS X, so if you have a Mac that you regularly use, then you can be sure it is updated first and foremost by applying any security updates that Apple issues; however, if you wish to update your system right away then you can download and compile the latest Bash version for OS X, which to date is version 3.2.

First, click this link to download Xcode from the App Store for free, and install it. If you do not use it regularly you can delete it later, but it will be required to compile the patched version of Bash. When it downloads, be sure to open it and accept its terms of use before continuing on (you can quit it after accepting the terms).

Next, you will need to download the Bash source from Apple, patch it, and then compile and install it. This sounds complicated, but can be done by running the following series of commands in the OS X Terminal after you have installed Xcode:

  1. Download and unpack Bash from Apple:
    curl https://opensource.apple.com/tarballs/bash/bash-92.tar.gz | tar zxf -
  2. Change directory to the downloaded Bash folder:
    cd bash-92/bash-3.2
  3. Download the patch script from Gnu.org, and apply it. These must start with 052 (the first listed here), and then apply subsequent patches sequentially, if available:
    curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-052 | patch -p0;
    curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-053 | patch -p0;
    curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-054 | patch -p0;
    curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-055 | patch -p0
  4. Go up one directory and then build the patched version (a bunch of text will scroll up when you do this):
    cd ..;xcodebuild
  5. Backup the current Bash and Sh executables:
    sudo cp /bin/bash /bin/bash.bak;
    sudo cp /bin/sh /bin/sh.bak
  6. Copy the new version into place to make it the default and targeted executible
    sudo cp build/Release/bash /bin;
    sudo cp build/Release/sh /bin
  7. Remove the execute bit on the backup versions of Bash and Sh to ensure they are not run:
    sudo chmod a-x /bin/bash.bak /bin/sh.bak

After you have completed these steps, your system should have a patched version of Bash that is not vulnerable to the problem at hand. Keep in mind that while this is a fix, a more robust or complete solution may develop in the next few days, so be sure to check back here for updates on patches. In addition, if there is an update available from Apple, then be sure to apply that update instead. Doing so will replace any custom builds you have installed.

In addition, keep in mind this fix does not address the issue in full, since the problem at hand may be in hardware devices like routers, media centers, and print servers, some of which are so old that companies are no longer supporting them with updates.

Reverting the patch

To undo this change to OS X and revert your Mac back to the old version of Bash, you can perform the following steps in the Terminal:

  1. Remove the patched versions of Bash and Sh:
    sudo rm /bin/bash /bin/sh
  2. Rename the backups to their original names:
    sudo cp /bin/bash.bak /bin/bash;
    sudo cp /bin/sh.bak /bin/sh
  3. Ensure both of these files are executable:
    sudo chmod a+x /bin/bash /bin/sh

UPDATE: This fix will work with Snow Leopard, provided you have XCode version 3.2 installed on your system (which you can still download for free). Alternatively, you can try modifying one of Apple’s update installers so the Bash updates in them can be applied to a system running Snow Leopard. You can read how to modify the Bash Update installers here.

80 thoughts on “How to unofficially fix the ‘Shell Shock’ bash vulnerability in OS X

  1. jeroenbouman

    Tip: after downloading & installing Xcode, open it first and accept the terms. Otherwise step #4 won’t work and you’ll run into trouble at #6

    Reply
    1. Vic

      This must only affect OS X 10.7.5 or later because I was able to compile bash on OS X 10.6.8 using just the command line tools. I didn’t have to download Xcode.

      Reply
      1. Brian

        How did you do this from the command line without XCode? I’m on OS X 10.6.8 and not a developer. I used to work for a tech startup and had to do a little work in terminal, so I can copy and paste instructions and understand some basic commands, but needing XCode is preventing me from completing these instructions. The current version of XCode won’t work on 10.6, and I’m not sure if downloading an older version of XCode that will work with 10.6.8 (3.2.6) from the download sections of my free developer account would allow me to compile the bash updates.

        Reply
        1. Topher Kessler Post author

          You do this in 10.6.8 systems by first installing XCode 3.2.2 from the Apple developer downloads section (you can sign in with an Apple ID, and do not need to pay the $99/year for a developer account). With XCode installed, you can then use the xcodebuild command mentioned here to build the project.

          The location for the download is here: http://developer.apple.com/downloads/

          Do a search for “XCode 3.2.2” to locate the XCode installer for 10.6.8 systems.

          Reply
          1. Brian

            Thanks for the reply Topher, unfortunately I’m not seeing Xcode 3.2.2 in the developer downloads area. I see 3.2.1 and 3.2.3, but for some reason no 3.2.2. I do however see a version of XCode specifically for Snow Leopard that some Googling suggests is the oldest compatible version without needing a paid developer account, “Xcode 3.2.6 and iOS SDK 4.3 for Snow Leopard.” Let me know if this version would work for compiling the bash patch.

          2. Simon Andersen

            If you’re running Snow Leopard you should have the Snow Leopard install media tucked away somewhere. It has the XCode installer on it so you can start there and update via Software Update

          3. Rachel R. (@REReader)

            I tried installing XCode from my Snow Leopard install disk, and got an error message–

            “The installation failed. The Installer encountered an error that caused the installation to fail. Contact the software manufacturer for assistance.” BUT…it looks like it’s installed… ?

          4. Simon Andersen

            Did you mess with bash prior to trying to install Xcode? If so maybe the installer error is generated by the fact that it is unable to run install scripts which are ironically possibly written to run in bash.

          5. Alec (not Alex)

            I posted the following comment to Aladdin’s fix, but maybe y’all can help me:

            “I think I did what you suggested correctly. However, when I open Terminal and type ‘help,’ I get:

            GNU bash, version 3.2.53(1)-release (i386-apple-darwin11).

            I take that to mean that patch 53 was applied, and that patch 54 wasn’t. Is patch 54 not needed for Snow Leopard? Am I looking in the wrong place to find out what was patched? If it matters, I’m using an iMac 4,2.

            Thank you.”

          6. Rachel R. (@REReader)

            Simon: The only thing I did before downloading Xcode was run a line to see if my system is vulnerable. I DEFINITELY didn’t try altering anything at all yet!

            Interestingly, Xcode seems to open just fine, and when I tried to run the Software Update again, it says there’s nothing to update. Perhaps the error message is in error? Any ideas?

          7. Alec (not Alex)

            I see that there’s a 55 available now, too.

            Also, I have the same questions as Brian. As I mentioned, I followed the same technique as Aladdin to make use of the update for Lion, even though I have Snow Leopard, but apparently I’ll have to go the XCode route to install the more recent patches. XCode 2.2.1 is on my Mac currently. I assume that came with my Snow Leopard media.

          8. Alec (not Alex)

            I just tried opening my XCode 2.2.1, but was told that it couldn’t be used with the version of the OS on my computer (10.6.8).

          9. Alec (not Alex)

            Downloading “Xcode 3.2.6 and iOS SDK 4.3 for Snow Leopard.” Will use Topher’s method to install patches 54 and 55.

          10. Alec (not Alex)

            Patch 056 now available. In trying to apply it, during Step #3, I received the following:

            patching file make_cmd.c
            patching file copy_cmd.c
            patching file patchlevel.h
            Hunk #1 FAILED at 26.
            1 out of 1 hunk FAILED — saving rejects to file patchlevel.h.rej

            Do I need to undo something now? I’m lost.

          11. Brian

            Hey Alec not Alex, I figured out what that error was. After some Googling, it means that the patch is looking for specific lines of code and not finding them. What you need to do is start over at step 1 by downloading the source from Apple, but then during step three put a semi-colon at the end of the last line shown by Topher, then add an additional line that says:

            curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-056 | patch -p0

            This will make the lines of code line up with what the patch expects to see, and then you can do the rest of the steps again. For me, this fixed all vulnerabilities that can be tested on shellshocker.net.

          1. Brian

            I was able to patch bash up to version 3.2.55 on 10.6.8 using XCode 3.2.6 as well. If I type bash –version I get “version 3.2.55(1)-release.” However the last step trying to make sure the backup files cannot be executed did give me an error:

            “/bin/sh.bak: No such file or directory”

            Also, like Alec (not Alex) pointed out above, there is now a patch 56. I tried step 1-3 above, but after the download tried to install the patch I got the same error:

            patching file make_cmd.c
            patching file copy_cmd.c
            patching file patchlevel.h
            Hunk #1 FAILED at 26.
            1 out of 1 hunk FAILED — saving rejects to file patchlevel.h.rej

            My main concern is that when I tried the tests on this site https://shellshocker.net/ the last one concerns me. When I enter:

            bash -c “f() { x() { _;}; x() { _;} </dev/null || echo vulnerable

            I get:

            Segmentation fault
            vulnerable

            That seems to suggest I’m still vulnerable to the last exploit, which my guess is fixed in patch 56. Let me know how I can get it?

            Thanks!

  2. B. Jefferson Le Blanc

    Topher, you forgot one essential step – back up your system first. That said, I think I’ll wait for Apple’s fix, too.

    Reply
    1. Topher Kessler Post author

      Backing up the entire system is not necessary since you are backing up the files you are changing; however, maintaining a full system backup at all times is always recommended.

      Reply
  3. Vic

    Using the command line tools on 10.6.8, the build “succeeded”, but there were a bunch of compiler warnings. Is this that normal? Will the newly compiled version of bash still function properly?

    Reply
    1. Topher Kessler Post author

      The build will likely have a number of warnings show up (in purple text). These just point out minor inconsistencies in programming style, and should be fine if the program compiled successfully.

      Reply
      1. Vic

        Thanks. The warnings were in the same colour as the rest of the text, but I guess that’s because I used the Terminal.app and not a 3rd party terminal emulator. Most of the warnings were these two:

        “warning: passing argument 1 of ‘list_append’ from incompatible pointer type”
        “warning: format not a string literal and no format arguments”

        Reply
  4. Robert

    Just open the terminal, open its preferences and where it says: “Shells open with:” select “Command (complete path):”
    Then type in the path: /bin/zsh
    The z shell is backwards compatible with the bash shell, has more power features and lacks the vulnerability that bash has. As a developer, I always use z shell instead of bash.

    Reply
    1. Topher Kessler Post author

      This will not fix the problem at all, and has nothing to do with the issue at hand. Regardless of what shell your account uses, or which the Terminal uses when launching, the BASH shell can still be opened. With this software not coded correctly, you can open it with the “env” command above, and thereby inject code that will run when it should not. The only way to fix this issue is to replace BASH with a version that works correctly, either through an update or through manually compiling a fixed version and installing it (as outlined here).

      Reply
    1. Topher Kessler Post author

      You must first apply the 052 patch, and then run the “curl URL | patch” command again for the 053 patch. I have updated the article to reflect this.

      This may be true for additional fixes, if found, where you should start with 052 unless a patch is cumulative and there is explicit instruction for a patch that previous ones are not needed.

      Reply
      1. Vic

        Do I have to delete the folder and it’s contents from the first download and compile before downloading and compiling the second, more recent update?

        Reply
        1. Topher Kessler Post author

          You shouldnt have to. The source code files should all be the same as they were before compiling. You can then update them accordingly, and recompiling the program will create the new version based on the updated code.

          Reply
  5. Mark Squance

    This instructions for this patch / fix worked 100% on my 27″ Late Sept. 2013 3.5GHz QuadCore i7 iMac (14,2) running Mavericks 10.9.5 (Build 13F34) I already have the latest Xcode Version 6.0.1 (6A317) with command line tools installed and updated

    Thank You for publishing it here 😉

    Many Thanks,

    Have Fun !

    Reply
  6. Walkers

    This patch / fix worked 100% on my 21.5″ Mid 2010 3.1GHz i3 iMac running Mavericks 10.9.5- already have the latest Xcode. Also worked 100% MacBookPro late 2013.
    Message: bash: warning: x: ignoring function definition attempt bash: error importing function definition for `x’ hello

    Reply
  7. Kupe

    Hi Topher-

    My iMac running Mavericks defaults to the TCSH shell- not the BASH shell. (I set that preference years ago for some reason I can no longer recall.) So my question is does the TCSH shell share this vulnerability?

    Thanks!

    Reply
    1. Topher Kessler Post author

      Setting the shell for your system or your account, or that which the Terminal invokes when it is launched, is irrelevant to the problem at hand. As long as you have a vulnerable version of Bash on your system, then you can launch it from within zsh, tcsh, csh, or any other shell by typing the command “bash.” Similarly, a process can launch bash, and do so by supplying it with an environmental variable purposed to exploit this vulnerability. To fix this problem, you need to replace Bash with a patched version.

      Reply
  8. Lawrence

    I’m a little unclear as to the relationship between sh and bash in my Snow Leopard Mac. I’ve read that nowadays in most flavors of Linux, the sh is really just a symlink to bash, but somebody said that in his Mac sh seemed to be a duplicate of bash, that is an executable not a symlink. On my Mac sh is certainly not a symlink or alias (I suppose it might be a hard link to bash). The file size between my sh and bash are very slightly different, so perhaps it’s not a dupe.

    What’s the typical story about this on Macs? And when you compile a patched bash following your instructions, are you simply compiling the same binary under two different names, and if so, why?

    Thanks for all the explanations.

    Reply
    1. Topher Kessler Post author

      For most purposes they are similar enough that Bash covers all the uses of sh, and then some. However, they are still separate programs in OS X that contain their differences, and are not just symlinks to the same executable. This problem affects Sh as well as Bash, but both are built and distributed together so they are handled like siamese twins by developers and users.

      Reply
  9. Bob Main

    When I try to run step 5 of the fix, Terminal requests a password but I am unable to type anything in response. Any suggestions as to how remedy this situation? What password is Terminal looking for? Thanks.

    Reply
    1. Russsgood

      No text or ****’s will display in terminal when typing your master password (the password you usually type to install software or updates etc). Type it anyway then hit return. If the password is correct you should be able to continue.

      Reply
    1. Lawrence

      As Topher already indicated, that wouldn’t help. The problem usually arises from a script that’s set up to use bash (without any visible command line or “Terminal” on your screen), in which case whether _you_ use bash or not doesn’t matter. If by “disable” you mean remove bash from your system entirely, that might plug the security hole, but then that script would break.

      If, on the other hand, the script were set up to use whatever your default shell program happens to be (rather than specifically using bash), then deleting bash and telling your system to use that other shell as its default would fix the problem. But many scripts nowadays do call bash specifically.

      Reply
  10. john

    I’m on OS X 10.6.8 and I copyed and pasted into terminal and got half way but it didn’t work and It messed up my OS. Is there anything I can copy and past that would fix my computer,,, Thank you;-)

    Reply
    1. Topher Kessler Post author

      How specifically did it “mess up your OS”? By the instructions here you cannot mess up your system for anything that does not use “bash;” however, if something is not working correctly, then you can follow the steps at the end to undo the changes and revert back to the backed up copy.

      I have repeatedly performed these steps on 10.6.8 systems (both client and server, with Xcode 3.2.2 installed), and these systems have shown no problems booting to or running services with a fully patched version of bash 3.2 (the version Apple includes with OS X).

      Reply
  11. Simon Andersen

    Which bash source do you pull off of opensource.apple.com for Snow Leopard 10.6.8? It appears that the bundled one is bash-80 but that one doesn’t contain an Xcode project file so the xcodebuild command subsequently fails.

    Do you just use the bash-92 tarball which first appears in the Mavericks branch?

    Reply
  12. John

    It was a weird problem I couldn’t run Onyx any more and my router connected to my usb port wouldn’t work any more. Disk Warrior didn’t fix it:-( I didn’t expect any response from you so I moved my whole system to a back up from a month ago. Simon’s answer sounds like that might be what happened to me. It was a good lesson in me creating a problem when I didn’t need to. I didn’t really need to run that Terminal code but I did any way and destroyed something that was fine. Lesson learned;-)

    Reply
    1. Simon Andersen

      Depending how far half way you got you may have reached the point of renaming or moving the existing bash and sh. That would certainly explain why Onyx failed. Onyx runs a lot a maintenance scripts many are probably reliant on bash being present. So your Mac may have been wonky but at least it sounds like it may have been completely safe from “shellshock” :-)

      It’s good to have backups. But maybe your problem could have been solved by using the Finder’s “Go To Folder…” menu-command, going to “/bin” and restoring bash and sh in place from TimeMachine rather than a full system restore.

      DiskWarrior fixes filesystem errors. It wouldn’t go out its way to fix a file you’d moved (because you know, maybe you wanted to. Damn computers, doing what we ask instead of what we want :-) )

      Reply
  13. Lawrence

    I have a feeling this may be a dumb question… but for us Snow Leopard neanderthals, instead of installing Xcode and learning about tarpits and hairballs and compiling our way into all kinds of trouble, couldn’t we just download a pre-compiled version that someone else was kind enough to create for 10.6.8 and post online? That might sound like a security risk, but after all I’m not going to audit the source code even if I do go the compile-it-yourself route.

    Also, why does each version of OS X need a different version of bash and sh? Do the APIs that connect the shell to the OS really change with each major upgrade, or is it some other issue?

    Reply
    1. Simon Andersen

      Those were my thoughts exactly. I became increasingly frustrated over the weekend and finally found Topher’s instructions which are quite concise so I finally managed to do it myself.

      Now Apple have provided patch pkg installers for 10.7, 10.8 and 10.9 ( http://support.apple.com/kb/DL1767 , http://support.apple.com/kb/DL1768 and http://support.apple.com/kb/DL1769 respectively ) but Snow Leopard users are left hanging.

      It’d be trivial for anyone who has compiled on Snow Leopard to wrap the build products in a pkg installer. Maybe Topher can weigh in here (as he appears to be a more competent developer than me) on what the issues would be.

      If anyone is interested I’d be happy to provide the binaries I’ve produced on Snow Leopard from Topher’s instructions as long you don’t hold me responsible for any unexpected ill effects your Mac may suffer subsequently.

      Reply
    1. Alec

      I think I did what you suggested correctly. However, when I open Terminal and type “help,” I get:

      GNU bash, version 3.2.53(1)-release (i386-apple-darwin11).

      I take that to mean that patch 53 was applied, and that patch 54 wasn’t. Is patch 54 not needed for Snow Leopard? Am I looking in the wrong place to find out what was patched? If it matters, I’m using an iMac 4,2.

      Thank you.

      Reply
        1. Simon Andersen

          There’s a tester script available here: https://github.com/hannob/bashcheck

          You can run it using the following Terminal commands:

          curl -s “https://raw.githubusercontent.com/hannob/bashcheck/master/bashcheck” | bash

          The bash 3.2.53(1) that Apple has put out evidently still contain bugs in that it doesn’t get green lights across the board but it is not exploitable which is what we should worry the most about.

          Reply
  14. kittnprydz

    thank you so much! it worked! Your instruction proved to be most helpful as other ones I’ve seen on the other sites failed to work! (I was having getting the latest bash instaleld although the build was successful).

    Reply
    1. Topher Kessler Post author

      No. The instructions are correct. The files being modified with this command are the original backed up versions of bash and sh, which we are setting to not be executable for all users by supplying “a-x”. If we were to use “a+x” then this would set them to be executable, which is not what we want.

      Reply
  15. Toost

    Thanks for the excellent instructions! I had no problems applying the latest patches (up to bash32-055 as of 01-Oct-2014) and checked the new version was being used by restarting terminal and entering “bash –version”

    Reply
  16. James

    If you have an ancient version of OS X, you can update your bash. I ‘m running something like 10.4 on G5 hardware.
    What I did is download the sources and apply the patches as mentioned above:

    curl https://opensource.apple.com/tarballs/bash/bash-92.tar.gz | tar zxf –
    cd bash-92/bash-3.2
    curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-052 | patch -p0
    curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-053 | patch -p0
    curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-054 | patch -p0

    Then I made an empty ostype.h file.
    Then:

    configure
    make
    I then copied the resulting bash executable to /bin/bash and /bin/sh

    This is a much newer version of bash than was already present. If the differences hose some services I’m running, I’ll worry about that independently. I’m more worried about fixing this exploit immediately.

    Reply
    1. Topher Kessler Post author

      Less of one, but still a potential problem for any service or program that is built to use Bash. Even though relatively rare, there are some programs in OS X that do this.

      Reply
  17. hacksagogo

    Here’s for the crazy ones, the misfits, the trouble makers, the round heads in the square holes. The ones who see things differently… and are still running Snow Leopard.

    Reply
  18. Bob

    worked perfectly with xcode 3.2.6 on 10.6.8 Snow Leopard

    GNU bash, version 3.2.55(1)-release (x86_64-apple-darwin10)

    thanks Topher

    Reply
  19. Brian

    After updating bash to 3.2.55(1)-release on OS X 10.6.8 using XCode 3.2.6, I ran the test at https://shellshocker.net/. The only vulnerability I’m showing still is CVE-2014-6277 (segfault). Anyone have a solution for how to fix this on Snow Leopard yet? As I mentioned before, when I tried to update to patch 56 I got the following error:

    patching file make_cmd.c
    patching file copy_cmd.c
    patching file patchlevel.h
    Hunk #1 FAILED at 26.
    1 out of 1 hunk FAILED — saving rejects to file patchlevel.h.rej

    Thanks in advance for helping a non-developer fix this up. It’s becoming clear to me though that there’s too much risk using an OS that is no longer supported with security updates, so it looks like it’s time to start shopping for a new Mac. Until I get one though I want to protect my existing machine as much as possible.

    -Brian

    Reply
    1. Brian

      I figured out the problem. After some Googling, I found that error means that the patch is looking for specific lines of code and not finding them. What I did was start over at step 1 by downloading the source from Apple, but then during step 3 I put a semi-colon at the end of the last line shown by Topher, which installs patch 55, then add an additional line to install patch 56 that says:

      curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-056 | patch -p0

      This will make the lines of code line up with what the patch expects to see, and then you can do the rest of the steps again. For me, this fixed all vulnerabilities that can be tested on shellshocker.net.

      Reply
  20. Dr_T

    I get the following error in step 4 (when running xcodebuild):

    2014-10-06 14:02 xcodebuild[45600] (CarbonCore.framework) FSEventStreamStart: ERROR: FSEvents_connect() => Unknown service name (1102)
    2014-10-06 14:02:20.054 xcodebuild[45600:807] The event stream could not be started.
    xcodebuild: Error: couldn’t load project /Users/me/source/bash-92/bash.xcodeproj

    I am on Mac OS 10.6.8 and running Xcode 3.2.6. Any ideas? Thanks.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *