Guides, Linux, Privilege Escalation

Linux Privilege Escalation – Exploiting Misconfigured SSH Keys

Introduction

Secure Shell (SSH) is a cryptographic network protocol which allows users to securely perform a number of network services, such as remote authentication or file transfer, over an unsecured network. SSH keys provide a more secure way of logging into a server through SSH than via a password authentication.

If improperly configured, SSH keys could allow an attacker to authenticate as another user to escalate privilege, potentially even as root.

Understanding Asymmetric Encryption

Before diving into the possible attacks, it is crucial to understand the key pair concept that SSH and other asymmetric cryptographic protocols utilize to secure a connection. These use a private key to encrypt information, and a corresponding public key to decrypt it.

When communicating to a machine via SSH, a user can authenticate if their private key is considered trustworthy by the server and added to the authorized_keys file, or if their private key corresponds to a public key stored in the server.

The default name for public keys is usually id_rsa.pub or id_dsa.pub and the default name for private keys is id_rsa or id_dsa, based on the encryption algorithm used. DSA is known to be insecure.

Exploiting SSH Keys

The main two ways of exploiting SSH keys are the following:

  • Accessing readable private SSH keys and using them to authenticate
  • Accessing writable public SSH keys and adding your own one to them to authenticate

If readable private keys or writable public keys are present on the machine, this could allow for an attacker to escalate privileges to root.

Public and private keys are generally stored in one of the following locations:

  • /root/.ssh/
  • /home/user_name/.ssh/ (users home directory)
  • /etc/ssh/
  • in the paths specified in the ssh_config or sshd_config config files

The following command can be used to identify any existing public or private keys and their permissions:

ls -la /home /root /etc/ssh /home/*/.ssh/; locate id_rsa; locate id_dsa; find / -name id_rsa 2> /dev/null; find / -name id_dsa 2> /dev/null; find / -name authorized_keys 2> /dev/null; cat /home/*/.ssh/id_rsa; cat /home/*/.ssh/id_dsa

Readable Private Keys

As mentioned earlier, private keys are used by users to authenticate via SSH. If a private key is stored in a way that makes it accessible to the current user, this means it can be used to perform an authentication as the owner of the private key.

Using the command mentioned earlier, the system has flagged that the private key for the “stef” user is readable to all users:

The easiest way to exploit this is to simply copy the key over to a Kali host, either by using one of the techniques shown in this article, or by simply copying and pasting the contents of the file. For the purpose of this guide I will be copying the key to a new file in Kali using Vim:

In order for the private key to be accepted by SSH, it needs to be only readable and writable only by its owner, otherwise it will complain that the permissions applied are too open.

Using the following command to change the file permissions against the newly created SSH private key:

chmod 600 key_name

The following command can then be used to login as the “stef” user:

ssh -i key_name user_name@X.X.X.X

Note: When access services that allow file sharing such as FTP, SMB, HTTP etc is allowed, common SSH keys directories should be checked for open private keys.

Writable Public Keys

The authorized_keys file in SSH specifies the SSH keys that can be used for logging into the user account for which the file is configured.

The default configuration in most SSH implementations allows users to deploy new authorized keys for themselves and anyone else, which are permanent and may bypass privileged access management systems.

If the authorized_keys file is writable to the current user, this can be exploited by adding additional authorized keys.

The example below shows how the authorized_keys file is writable to all users:

The easiest way to exploit this is to generate a new SSH key pair, add the public key to the file and login in using the private key.

The ssh-keygen command line utility can be used to generate a new SSH key pair:

The public key can then be copied with the ssh-copy command line tool:

ssh-copy-id user_name@X.X.X.X

Or simply by using cat to output the contents of the id_rsa.pub file and redirect it to the authorized_keys file:

cat ~/.ssh/id_rsa.pub | ssh user_name@X.X.X.X "cat >> /home/user_name/.ssh/authorized_keys"

The methods above will only work if SSH access is already available. If not, the contents of the public key can simply be pasted into the authorized_host file. Using xclip to add the public key to the clipboard:

Copying the public key to the authorized_hosts file

This allows to login to the server via SSH without having to specify any private keys (as Linux checks for private keys in the user’s home directory by default):

If the key pair was not generated in one of the default directories for SSH, the private key can be specified using -i like the example used earlier.

Conclusion

SSH keys are a great way to securely manage user access to a server, although if misconfigured they could result in a full system compromise.

The private keys need to be stored and handled carefully, and no copies of the private key should be distributed. The authorized_keys file should only be editable by the owner of the file or by root.

Sources & Additional Resources