Forge
Executive summary — Forge is a Linux box built around a single vulnerability class exploited twice in a row: SSRF (Server-Side Request Forgery). The first SSRF, bypassed with a trivially case-sensitive blacklist, opens the internal admin panel; the second, chained through that same panel and the
ftp://scheme, leaks the user's SSH private key. Privilege escalation to root relies on no kernel exploit or CVE at all: it abuses an interactive Python debugger (pdb.post_mortem) left reachable inside a privileged script, triggered by nothing more than a non-numeric input.
| Platform | Hack The Box |
| Operating system | Linux (Ubuntu 20.04, Apache 2.4.41) |
| Difficulty | Medium |
| Status | Retired |
| Target IP | 10.129.82.27 |
| Domain | forge.htb |
| Initial vector | SSRF on /upload (upload from URL) |
Attack map
/upload (upload from URL)
│ SSRF: the server fetches whatever URL we give it
│ blacklist bypass via mixed case -> aDmIn.FoRgE.hTb
▼
admin.forge.htb ("localhost only" panel)
│ /announcements leaks credentials
│ user:heightofsecurity123! (internal FTP)
▼
Chained SSRF -> ftp://user:...@forge.htb/
│ via the admin's own /upload?u=
│ reads /home/user/.ssh/id_rsa
▼
[USER] ssh -i id_rsa user@10.129.82.27 <- user.txt
│ sudo -l: /usr/bin/python3 /opt/remote-manage.py (NOPASSWD)
▼
localhost socket + int(recv()) <- non-numeric input
│ unhandled ValueError -> except: pdb.post_mortem(e.__traceback__)
│ interactive Python debugger running as root
▼
[ROOT] pdb -> os.system(cp /bin/bash SUID) <- root.txt
1. Reconnaissance
sudo nmap -p- --min-rate 2000 -T4 -Pn 10.129.82.27 -oN nmap/allports.txt
21/tcp filtered ftp
22/tcp open ssh OpenSSH 8.2p1 Ubuntu
80/tcp open http Apache/2.4.41 (Ubuntu) -> redirects to http://forge.htb
The FTP port shows as
filtered, notclosedoropen: a firewall is dropping packets from the outside. That doesn't mean the service isn't there — as it turns out, there's an internal FTP server reachable only from the box itself, exactly the kind of resource an SSRF is good for reaching. HTTP redirects toforge.htb, so the vhost is added to/etc/hosts:
echo '10.129.82.27 forge.htb admin.forge.htb' | sudo tee -a /etc/hosts
forge.htb is an image gallery with an /upload endpoint offering two modes: upload a local file, or upload from a URL. The frontend's JavaScript (/static/js/main.js) reveals the actual parameters of the URL form:
<form action="/upload" method="POST" enctype="application/x-www-form-urlencoded">
<input type="textbox" name="url">
<input name="remote" type='hidden' value='1'>
</form>
POST /uploadwithurl=<URL>&remote=1. The server itself fetches whatever URL we give it: the textbook definition of SSRF (CWE-918) — the attacker never talks to the target resource directly, they make the application talk to it on their behalf, which hands over for free whatever network privileges the server itself has (access to localhost, the internal network, "internal only" services).
curl -s http://admin.forge.htb/
Only localhost is allowed!
Vhost discovery (or just reading the JS) reveals a second subdomain,
admin.forge.htb, whose panel is restricted by source IP: it only answers if the request comes from127.0.0.1. That control, sound at first glance, collapses the moment we get the server itself to issue the request on our behalf — and that's exactly what an SSRF is.
Resumen ejecutivo — Forge es una máquina Linux construida alrededor de una sola familia de vulnerabilidad explotada dos veces seguidas: SSRF (Server-Side Request Forgery). La primera SSRF, con un bypass trivial de una blacklist sensible a mayúsculas, abre el panel de administración interno; la segunda, encadenada a través de ese mismo panel y del protocolo
ftp://, filtra la clave SSH privada del usuario. La escalada a root no depende de ningún exploit de kernel ni CVE: abusa de un depurador interactivo de Python (pdb.post_mortem) dejado vivo en un script privilegiado, que se activa con una simple entrada no numérica.
| Plataforma | Hack The Box |
| Sistema operativo | Linux (Ubuntu 20.04, Apache 2.4.41) |
| Dificultad | Medium |
| Estado | Retired |
| IP objetivo | 10.129.82.27 |
| Dominio | forge.htb |
| Vector inicial | SSRF en /upload (subida desde URL) |
Mapa del ataque
/upload (subida desde URL)
│ SSRF: el servidor descarga lo que le pidamos
│ bypass de blacklist por mayúsculas -> aDmIn.FoRgE.hTb
▼
admin.forge.htb (panel "solo localhost")
│ /announcements filtra credenciales
│ user:heightofsecurity123! (FTP interno)
▼
SSRF encadenada -> ftp://user:...@forge.htb/
│ vía /upload?u= del propio admin
│ lee /home/user/.ssh/id_rsa
▼
[USER] ssh -i id_rsa user@10.129.82.27 <- user.txt
│ sudo -l: /usr/bin/python3 /opt/remote-manage.py (NOPASSWD)
▼
socket en localhost + int(recv()) <- entrada no numérica
│ ValueError sin manejar -> except: pdb.post_mortem(e.__traceback__)
│ depurador interactivo de Python ejecutándose como root
▼
[ROOT] pdb -> os.system(cp /bin/bash SUID) <- root.txt
1. Reconocimiento
sudo nmap -p- --min-rate 2000 -T4 -Pn 10.129.82.27 -oN nmap/allports.txt
21/tcp filtered ftp
22/tcp open ssh OpenSSH 8.2p1 Ubuntu
80/tcp open http Apache/2.4.41 (Ubuntu) -> redirige a http://forge.htb
El puerto FTP aparece
filtered, noclosedniopen: hay un firewall descartando los paquetes desde fuera. No significa que el servicio no exista — como se verá, hay un FTP interno solo alcanzable desde la propia máquina, que es exactamente el tipo de recurso que una SSRF permite alcanzar. El HTTP redirige aforge.htb, así que añadimos el vhost a/etc/hosts:
echo '10.129.82.27 forge.htb admin.forge.htb' | sudo tee -a /etc/hosts
forge.htb es una galería de imágenes con un endpoint /upload que ofrece dos modos: subir un fichero local y subir desde una URL. El JavaScript del front (/static/js/main.js) revela los parámetros reales del formulario de URL:
<form action="/upload" method="POST" enctype="application/x-www-form-urlencoded">
<input type="textbox" name="url">
<input name="remote" type='hidden' value='1'>
</form>
POST /uploadconurl=<URL>&remote=1. El servidor hace él mismo la petición a la URL que le demos: la definición de libro de SSRF (CWE-918) — el atacante no habla directamente con el recurso objetivo, hace que la aplicación hable por él, lo que le entrega de regalo cualquier privilegio de red del servidor (acceso a localhost, a la red interna, a servicios "solo internos").
curl -s http://admin.forge.htb/
Only localhost is allowed!
Hemos descubierto por vhost fuzzing/lectura de JS un segundo subdominio,
admin.forge.htb, cuyo panel está restringido por IP de origen: solo responde si la petición llega desde127.0.0.1. Ese control, correcto a primera vista, se derrumba en cuanto conseguimos que el propio servidor sea quien formule la petición en nuestro nombre — y ya tenemos justo eso: una SSRF.
Root Access unlocks the content you can't see — everything else on the site is already open.
See Root Access plansNo account? Create one free then upgrade from your console.
Root Access desbloquea el contenido que no puedes ver — todo lo demás de la web ya está abierto.
Ver planes de Root Access¿Sin cuenta? Crea una gratis y luego mejora desde tu consola.