Skip to content
HackIndex logo

HackIndex

SSH Config and Known Hosts Enumeration

3 min read Mar 16, 2026

After gaining shell access, SSH configuration files reveal where the compromised account has connected before, which keys it uses for specific hosts, and which other hosts trust it. This is one of the fastest ways to map lateral movement paths without running any network scans.

Read the SSH Client Config

┌──(kali㉿kali)-[~]
└─$ cat ~/.ssh/config
┌──(kali㉿kali)-[~]
└─$ cat /root/.ssh/config
┌──(kali㉿kali)-[~]
└─$ find /home -name "config" -path "*/.ssh/*" 2>/dev/null | xargs cat 2>/dev/null
Host jumpbox
    HostName 10.10.20.5
    User deploy
    IdentityFile ~/.ssh/deploy_key

Host prod-*
    User ubuntu
    IdentityFile ~/.ssh/id_rsa
    StrictHostKeyChecking no

Host db-server
    HostName 192.168.10.50
    User postgres
    Port 2222

Each Host block is a lateral movement lead. HostName gives the target IP or hostname. User gives the account to connect as. IdentityFile tells you exactly which key to test. StrictHostKeyChecking no means the owner has been connecting to these hosts regularly without verifying fingerprints.

Read known_hosts

┌──(kali㉿kali)-[~]
└─$ cat ~/.ssh/known_hosts
┌──(kali㉿kali)-[~]
└─$ cat /root/.ssh/known_hosts
┌──(kali㉿kali)-[~]
└─$ find /home -name "known_hosts" 2>/dev/null | xargs cat 2>/dev/null

Modern systems hash known_hosts entries by default. Unhash them to get readable hostnames and IPs:

┌──(kali㉿kali)-[~]
└─$ ssh-keygen -l -f ~/.ssh/known_hosts

Or use the -F flag to check whether a specific host is present:

┌──(kali㉿kali)-[~]
└─$ ssh-keygen -F $TARGET_IP

Each entry in known_hosts is a host the current user has successfully connected to at some point. Cross-reference with the SSH config to identify which key was used for each.

For hashed entries, try to match against known IPs in the environment:

┌──(kali㉿kali)-[~]
└─$ ssh-keygen -H -F 10.10.20.5

-H computes the hashed form of the IP so you can check whether it exists in the file.

Read authorized_keys

┌──(kali㉿kali)-[~]
└─$ cat ~/.ssh/authorized_keys
┌──(kali㉿kali)-[~]
└─$ cat /root/.ssh/authorized_keys
┌──(kali㉿kali)-[~]
└─$ find /home /root -name "authorized_keys" 2>/dev/null

authorized_keys lists every public key permitted to authenticate to this account. If you hold any corresponding private key, you can authenticate. Cross-reference each public key fingerprint against keys found elsewhere on the system or in other users' home directories.

Check for command= and from= restrictions in authorized_keys:

┌──(kali㉿kali)-[~]
└─$ grep -E "command=|from=" ~/.ssh/authorized_keys

command="backup.sh" means the key is restricted to running a single command. from="10.10.0.0/16" restricts to specific source IPs. These restrictions limit what you can do with a matching private key. Full analysis of restricted keys is covered in SSH Authorized Keys ForcedCommand and Wrapper Audit.

Find Private Keys on the System

┌──(kali㉿kali)-[~]
└─$ find /home /root /etc /var /opt -name "id_rsa" -o -name "id_ed25519" -o -name "id_ecdsa" -o -name "*.pem" -o -name "*.key" 2>/dev/null | xargs ls -la 2>/dev/null

Private keys outside of ~/.ssh/ are common in deployment configurations, CI/CD pipelines, and automated backup scripts. Check application directories and web roots:

┌──(kali㉿kali)-[~]
└─$ find /var/www /opt /srv /home -name "*.pem" -o -name "*.key" -o -name "id_rsa" 2>/dev/null

Map Hosts for Lateral Movement

Combine what you find across all SSH files to build a host target list:

┌──(kali㉿kali)-[~]
└─$ grep -h "HostName\|Host " ~/.ssh/config 2>/dev/null | grep -v "^#" | awk '{print $2}' | sort -u
┌──(kali㉿kali)-[~]
└─$ cat ~/.ssh/known_hosts | awk '{print $1}' | tr ',' '\n' | grep -v '|' | sort -u

Take this list into SSH Lateral Movement with Harvested Keys and SSH Agent Hijacking for Lateral Movement.

References