Shellshock

CVE-2014-6271

Shellshock is a critical remote code execution vulnerability affording escalated privileges to attackers, which allow them to compromise systems at will.

Shellshock allows systems containing a vulnerable version of Bash to be exploited to execute commands with higher privileges. This allows attackers to potentially take over that system.  The Bash bug poses a serious threat as it is very easy to execute an attack, and requires little technical expertise to do so.

Typical Shellshock exploits attempt remote command execution by telling Bash to assign an empty function declaration to an environment variable

Shellshock & Bash Functions

1: What is Bash?

Bash is a command-line interface shell program used extensively in Linux and macOS. The name Bash is an acronym for “Bourne Again Shell,” developed in 1989 as a successor to the Bourne Shell

“What’s a Shell?” you ask?

When you open your Terminal, the Shell is the name of the program that runs in the terminal.

Please note that the terminal is a dumb thing, and it does not know what to do with any user input. When you input a command into that window and hit enter key, that input goes to another program to process it, and in most cases, it’s the Shell.

2: Bash Functions

Like REAL programming languages, Bash has functions, though in a somewhat limited implementation. A function is a subroutine, a code block that implements a set of operations. Wherever there is repetitive code, consider using a function.

Bash functions can be used in .sh files and may be "compacted" into a single line.
image You may define a bash function with following syntax

function_name () { commands; }

That all sounds great. However, what if, for some reason, I defined a function in one shell, and wanted to invoke that function new instance of bash, as a subprocess?

Well, unfortunately, subprocesses don't inherit the function definitions.
However, they do inherit the environment variables.
So what if we made our functions environment variables?!
We are geniuses 🤩

However, here's something sketchy 🫣.

The functions are actually just like regular environment variables. When our subprocess (the second shell) opens and reads it's inherited environment variables, and see's something that looks like a function, it evaluates it. However, here is the bug: the evaluation of the variable does not stop at the end of the function definition. It kepts going.

This meant that even if we defined our function like this:

function_name () { commands; } sketchy code

The evaluation wouldn't end at the bracket, where our function ends. It will continue until it reaches our sketchy code, and it will execute the code!
image The bug makes it possible for hackers to trick Web servers into running any commands that follow a carefully crafted series of characters in an HTTP request.