NetSPI Blog

Stealing unencrypted SSH-agent keys from memory

Kevin Burns
July 21st, 2014

If you've ever used SSH keys to manage multiple machines, then chances are you've used SSH-agent. This tool is designed to keep a SSH key in memory so that the user doesn't have to type their passphrase in every time. However, this can create some security risk. A user running as root may have the ability to pull the decrypted SSH key from memory and reconstruct it.

Due to needing root access, this attack may seem useless. For example, an attacker may be able to install a keylogger and use that to obtain the passphrase for the SSH key. However, this causes the attacker to have to wait for the target to type in their passphrase. This might be hours, days, or weeks, depending on how often the target logs out. This is why obtaining the SSH key from memory is vital to pivoting to other machines in a speedy fashion.

Using SSH-agent

A common method of using SSH-agent is running “SSH-agent bash” and then “SSH-add” to add the key to the agent. Once added, the key will stay in the SSH-agent's stack until the process ends, another key is added, or the user uses the -d or -D option with SSH-add. Most people will run this once and then forget about it until they need to reboot.

Pulling a SSH Key From Memory

There are a few ways to create a copy of the SSH-agents memory. The easiest way is through the use of gdb. Gdb uses the ptrace call to attach to the SSH-agent. This provides gdb with the privileges necessary to create a memory dump of the running process. The script provides a way of automating the dumping of this memory. By default, when it runs it will create a memory dump of the stack for each SSH-agent process. These files are named SSHagent-PID.stack.

root@test:/tmp#  Created /tmp/SSHagent-17019.stack

If gdb is not available on the system, then it might be feasible to take a memory dump of the entire machine and use volatility to extract the stack of the SSH-agent processes. However, this process is currently out of the scope for this document.

Parsing SSH Keys From the Memory Dump

Once we have a copy of the stack it becomes possible to extract the key from this file. However, the key is kept in the stack in a different format then the one that was generated by SSH-keygen. This is where the script comes in handy. This script requires the installation of the pyasn1 python module. Once that is installed the script can be run against the memory file. If that memory file contains a valid RSA SSH key then it will save it to disk. Future versions of the tool may support additional key formats, such as DSA, ECDSA, ED25519, and RSA1.

root@test:/tmp# /tmp/SSHagent-17019.stack /tmp/key Found rsa key Creating rsa key: /tmp/key.rsa

This key.rsa file can then be used as an argument to the -i switch in SSH. This will act like the original user's key, only without requiring a pass phrase to unlock it.

Obtaining valid, usable SSH keys can help a penetration tester gain further access into a client's network. It's common for keys to be used on both the user's account, as well as the root account on servers. It is also possible that a server is configured to only allow key access. Having access to an unencrypted key can make moving around the environment much easier.

Newest Most Voted
Inline Feedbacks
View all comments
6 years ago

I have to say, this seems kinda obvious. This is why keychain and ssh-agent have timeout options in the first place, no?
Is kind of a balance of risk versus convenience.

The nice thing about timeout is you can set yourself where you want to set that balance.

6 years ago

Well I think this is an unlikely case when the user is in root and tries to do something like this. Another way considering that the user has access in root is to scan the hdd for .rsa files and recover them.
Again, a great article but it’s not likely to see this happen in a real working environment unless the admin is careless 🙂

6 years ago

Old news…
Like an aquaitenace of mine said, 2012 has called and left these messages in the voicemail: