¿Qué es un reverse shell? Una guía práctica para pruebas autorizadas
Cómo funcionan los reverse shells, por qué superan a los bind shells a través de firewalls y cómo un generador evita errores de copiar y pegar.
Un reverse shell es una sesión de línea de comandos que el objetivo abre de vuelta hacia ti. En lugar de que tú te conectes a un puerto donde el objetivo está escuchando, es el objetivo el que contacta con un listener que tú controlas y te entrega una shell al conectarse. Es la primitiva de postexplotación más habitual en las pruebas de penetración autorizadas, y existe por una razón muy tozuda: las conexiones salientes sobreviven a los firewalls que bloquean las entrantes.
Esta guía explica qué ocurre realmente en la red, cuándo conviene recurrir a un reverse shell frente a un bind shell, y por qué merece la pena usar un generador de reverse shell incluso cuando ya te sabes la mecánica de memoria.
Bind shell frente a reverse shell
Ambos se diferencian únicamente en quién inicia la conexión.
Un bind shell hace que el objetivo escuche en un puerto y espere. Tú te conectas a él. Eso funciona en una red de laboratorio plana y prácticamente en ningún otro sitio, porque los firewalls perimetrales y el NAT descartan de forma rutinaria el tráfico entrante no solicitado hacia un host.
Un reverse shell invierte la dirección. Tú ejecutas un listener; el objetivo se conecta hacia él. El filtrado de salida suele ser mucho más laxo que el de entrada —los puertos salientes 443 y 80 están abiertos en casi todas las redes porque los usuarios necesitan la web—, así que la llamada de vuelta del objetivo tiende a pasar.
Esa asimetría es la clave de todo. En un encargo real rara vez controlas las reglas de entrada del objetivo, pero casi siempre tienes una máquina en internet capaz de escuchar.
Qué ocurre paso a paso
- Inicias un listener en un host que controlas, p. ej.
nc -lvnp 443. - Consigues ejecución de código en el objetivo y lanzas un one-liner que se conecta de vuelta a tu
LHOST:LPORT. - El one-liner conecta el socket a la entrada, salida y error estándar de una shell.
- Tu listener recibe ahora la salida de la shell y le envía las pulsaciones de teclado. Tienes una sesión interactiva.
La parte de "conectar el socket a una shell" es lo que hace todo payload, solo que expresado de forma distinta según el lenguaje y la plataforma. Un payload de bash usa /dev/tcp; un payload de python usa los módulos socket y subprocess; un payload de PowerShell usa System.Net.Sockets.TCPClient. Misma idea, distinta fontanería.
Por qué fallan los payloads (y por qué ayuda un generador)
Los one-liners de reverse shell son engañosamente frágiles. El mismo comando falla o triunfa según detalles que no tienen nada que ver con el concepto:
- El intérprete equivocado.
/dev/tcpes una característica de bash. Pega un one-liner de bash en/bin/sh(a menudo dash) y fallará silenciosamente. - El entrecomillado. El payload pasa por un formulario web, un cuerpo JSON o una variable de CI antes de llegar a una shell, y cada capa se come o destroza una comilla. (Lo tratamos en detalle en entrecomillado de payloads.)
- Un binario que falta. Enviaste un payload de
pythona un host que solo tienepython3, o un payload denca una compilación de netcat creada sin-e. - Una errata en
LHOST/LPORT. El fallo más común de todos, y el más bochornoso.
Un generador de reverse shell elimina los fallos evitables. Configuras tu LHOST y LPORT una sola vez, eliges la shell y la plataforma del objetivo, y obtienes un payload con un entrecomillado consistente, con el comando del listener correspondiente justo al lado. Esa última parte importa más de lo que la gente espera: la mitad de las shells fallidas son un desajuste entre el payload y el listener, no un error en ninguno de los dos. (Consulta cómo elegir un listener.)
No se trata de no conocer la sintaxis. Se trata de no tener que reescribirla bajo presión y equivocarte con una comilla al quinto intento.
Una shell todavía no es una buena shell
Cuando la conexión llega, normalmente obtienes una shell cruda y no interactiva: sin control de trabajos, sin autocompletado con tabulador, sin poder pulsar Ctrl-C sin matar la sesión, sin un prompt de sudo que se comporte. Es lo normal. El siguiente paso es actualizarla a una TTY completa (habitualmente mediante python3 -c 'import pty; pty.spawn("/bin/bash")' y trucos con stty), algo que repasamos en mejorar un reverse shell.
Úsalo solo donde estés autorizado
Todo lo aquí descrito es para pruebas de seguridad que estés explícitamente autorizado a realizar: tu propio laboratorio, un CTF o un encargo con un alcance firmado. Los reverse shells son de doble uso por naturaleza; la técnica es idéntica tanto si el trabajo está sancionado como si no, y solo la autorización lo hace legítimo. Genera payloads contra sistemas que poseas o tengas permiso por escrito para probar, y nada más.
Por dónde seguir
- Construye un payload ahora con el generador de reverse shell.
- Análisis específicos por lenguaje: reverse shells de bash, reverse shells de python, reverse shells de PowerShell.
- Cuando no conecta: por qué fallan los reverse shells.