SSH Pentesting

0liverFlow
12 min readJan 10, 2025

--

SSH (TCP/22) is a protocol used to securely connect to a remote host. It allows two computers to establish an encrypted connection. This helps preventing third parties from reading the transmitted data which can lead to a violation of the confidentiality.

SSH can be found on Linux, Windows and MacOS. There are several SSH servers namely :

  • OpenSSH : implemented on Linux distributions and Windows (since Windows 10)
  • PuTTY : SSH implementation for Windows
  • CopSSH : SSH implementation for Windows

With that being said, let’s now dive into the heart of the matter.

In this post, we will see some unknown but interesting SSH tricks that you can use during your penetration testing.

SSH Enumeration

In this section, we will use various techniques to enumerate an SSH server. For the rest of this post, we will consider that the target SSH server is : 10.10.11.18

Banner grabbing

To grab the banner, we will use netcat : nc -nv <TARGET> <PORT>

SSH Banner Grabbing

As you can see the server is using SSH version 2.0 and running an OpenSSH version 8.9p1. Furthermore, from the output above, we can see that the target is also using Ubuntu as an OS.

Note : SSH-2 (SSH version 2) is a more advanced protocol than SSH version 1 in encryption, speed, stability, and security. For example, SSH-1 is vulnerable to MITM attacks, whereas SSH-2 is not.

SSH Authentication Methods

Prior connecting to an SSH server, it is worth checking the allowed authentication methods. For example, it will be useless to conduct a dictionary attack if the password authentication is not allowed. Knowing that information can help us save lots of time and look for other interesting attack vectors.

Here is how to check SSH authentication methods :

1/ SSH verbose mode

ssh -v username@<TARGET>

SSH verbose mode

The SSH verbose mode causes SSH to print debugging messages regarding what’s going on. Here, you can see that the public key as well as the password authentication is enabled.

2/ Nmap NSE script : ssh-auth-method

nmap -p22 --script ssh-auth-methods <TARGET>

Nmap NSE ssh-auth-methods

Here again, the supported authentication methods are : publickey and password.

Note : The SSH client will first try to authenticate to the target SSH server using the public key authentication. For that, it will look for private keys in ~/.ssh . If it found nothing, it will move with password authentication by asking you to enter the password of the username you’re trying to authenticate to.

To change the authentication method, you can use this SSH’s option PreferredAuthentications :

As you can see, there is no public key authentication this time. We automatically jumped to password authentication.

We could also get the same result by using the option PubkeyAuthentication

SSH Brute Forcing

In this section, we will cover how to conduct a dictionary attack against SSH using various tools.

Note : To conduct a dictionary attack, we will need a valid user and a list of passwords. We will suppose that during our reconnaissance, we find out a valid user named dash.

With that in mind, we can perform our dictionary attack using these tools :

Hydra

Syntax : hydra -l <USERNAME> -P <PASSFILE> -t <THREADS> -fv ssh://<TARGET>

SSH brute-forcing with hydra

Medusa

Syntax : medusa -h <TARGET> -u <USERNAME> -P <PASSFILE> -t <THREADS> -M ssh

SSH brute-force with medusa

Patator

Syntax : patator ssh_login host=<TARGET> user=<USERNAME> password=FILE0 0=<PASSFILE> -x ignore:fgrep='Authentication failed.'

SSH brute-forcing with patator

Checking if password is valid

Authentication succeeded

Note : It is always good practice to know how to use various tools to perform the same task as some tools may not work properly at times.

Here are the links to find the tools used above :

SSH File Transferring

In this section, we will learn how to securely transfer files using scp.

SCP (Secure Copy) is a command-line utility that uses SSH to securely transfer files between two computers. It ensures data integrity and encryption during the transfer, making it a secure alternative to older protocols like FTP.

Well, let’s see how to send a file from our attacker to the target system :

Syntax : scp <FILE-TO-SEND> <TARGET-USERNAME>@<TARGET-IP>:<TARGET-DESTINATION-DIRECTORY>

Let’s send a file called test.txt in the /tmp folder :

Sending test.txt to the target system (10.10.11.18)

Here is a quick breakdown of the command above :

  • test.txt : represents the file on our attacker machine that we want to send to the target machine.
  • dash@10.10.11.18 : represents the target machine where test.txt will be sent
  • :/tmp : represents the destination directory where test.txt will be saved.
File successfully uploaded

As you can see on the image above, our file was successfully uploaded.

You may wonder how to send a file from the target system to our attacker machine ? Well, this is as easy as Bonjour ! Here is the syntax :

scp <TARGET-USERNAME>@<TARGET-IP>:<FILE-TO-SEND-TO-ATTACKER> <ATTACKER-DESTINATION-DIRECTORY>

Let’s say we want to copy dash’s /etc/passwd on our machine. To do that, we can use the following command :

Sending /etc/passwd to our attacker machine

Like we did previously, here is a quick breakdown of the command above :

  • dash@10.10.11.18 : represents the target machine
  • :/etc/passwd : copies the file /etc/passwd into our attacker machine
  • . : represents the destination directory where /etc/passwd will be saved.
passwd successfully sent to the target machine

Note : To send a directory, you only need to add the -r option to the scp command.

Mounting a remote filesystem using SSHFS

Did you know that SSH could be used to mount filesystems ?

Indeed SSH provided us with a command named sshfs that is used to mount a remote filesystem on your local machine. This can be handy especially when dealing with large files. Indeed rather than downloading them on your system, you can simply mount them and get access to their content on your machine.

To install sshfs on your debian based distribution, you can use this command : apt install sshfs -y .

Once the installation done, you can mount a remote filesystem using this command :

sshfs <TARGET-USERNAME>@<TARGET-IP>:<FILESYSTEM-TO-MOUNT> <MOUNTPOINT>

Mounting a remote filesystem using sshfs

/home/dash and /mnt/dash are respectively the filesystem to mount and the mountpoint.

Note : The mountpoint must exist prior executing the sshfs command, otherwise you will get this error : No such file or directory.

Once you are done with the remote filesystem, you unmount it using the umount command :

Unmounting ssh mountpoint (/mnt/dash)

Voilà ! Hope this was clear for you :)

SSH Persistence

In this part, we will see how to use ssh keys for persistence.

Persistence is a technique generally used by red teamers and adversaries to maintain their access to the target system after interruptions that can cut off their initial foothold.

Well, let’s now get our hands dirty. First of all, we will generate a pair of ssh keys using the following command :

Syntax : ssh-keygen -t rsa -b 4096 -N '' -f id_rsa

Here is a breakdown of the command :

  • ssh-keygen : command to generate a pair of ssh keys
  • -t rsa : specifies the type of ssh key to create (rsa)
  • -b 4096 : specifies the length of the ssh key (4096 bits)
  • -N '' : set a null passphrase for the ssh key
  • -f id_rsa : specifies the filename of the key file.
Generated ssh keys

Well, let’s send the public key (id_rsa.pub) to the target system’s ~/.ssh/authorized_keys file. One way to achieve is by using ssh-copy-id with the target session’s password. However most of the time, we will have no idea of the target session’s password because we will generally get our initial foothold after exploiting a web vulnerability (command injection, file upload, etc), then leverage that to get a reverse shell.

That being said, to establish persistence, we will proceed as follows :

1/ Copy the content of our public key in the target ~/.ssh/authorized_keys file :

~/.ssh/authorized_keys
Initial content of ~/.ssh/authorized_keys
Adding the content of our public key (id_rsa.pub) to ~/.ssh/authorized_keys
Public key content successfully added

2/ Once done, we can go back to our attacker system, then authenticate to the target machine with the following command :

ssh -i id_rsa <TARGET-USERNAME>@<IP-ADDRESS>

As you can see, the authentication succeeded !

Note : Always make sure to change the private key permissions to 400 or 600 prior using it in your ssh command, otherwise ssh will raise a warning : “UNPROTECTED PRIVATE KEY FILE!” and the private key authentication will fail.

For instance, if I allow everyone to read the private key which is a security concern, I will get the following message :

SSH Warning : UNPROTECTED PRIVATE KEY FILE!

Note : SSH private keys are also use to get a stabilized shell. For instance, when playing CTFs, it can be exhausted to run multiple times the reverse shell payload because you unintentionally pressed CTRL+C. Therefore, if ssh is open on the target machine and if your compromised user has a shell, you can switch to a ssh connection using ssh keys.

Auditing SSH configuration

During your penetration test, you should take a minute to audit the configuration of your client’s ssh server if this is part of the scope.

This is very important because sometimes you maybe surprised of what you can find. One great tool to perform this task is ssh-audit which is a python tool developed by Joe Testa for this matter. Here is how to use it :

ssh-audit [options] <HOST>

SSH configuration audit with ssh-audit

As you can see, the tool audited the key exchange algorithms, the encryption algorithms, the host-key algorithms and much more.

At the very bottom, you must find this link for hardening guides on common OSes.

Last but not least, if you’re using Linux, you can find the server SSH file configuration in /etc/ssh/sshd_config

SSH configuration file

grep -Ev '(^#|^$)' was used to get rid of blank lines and comments in the configuration file.

Bonus

In this section, I will show you how to find valuable information from a SSH private key. First of all, let’s see how to retrieve the owner of a private key.

Here is the private key that we generated in the “SSH persistence” section :

id_rsa

Well, let’s retrieve the owner of this private key using this trick :

cat id_rsa | grep -v "OPENSSH PRIVATE KEY" | base64 -d | xxd

At the first 5 lines, you can already detect the ssh algorithm used to generate the private key : ssh-rsa.

Nevertheless, things get more interesting when you scroll at the bottom specifically at the 2 last lines. As you can see below, we have two interesting information here :

  • The name of the user who generated the private key : root
  • The hostname on which the private key was generated : kali

That’s it. Now you can find interesting information from a SSH private key.

Note : This trick only works for non protected SSH private keys.

To give you more perspective, let’s create a new protected SSH private key with the passphrase : password

Generating a protected SSH private key with password as passphrase
SSH private key content

Let’s see if we can retrieve the owner of this private key and the host on which it was generated :

As you can see, at the first 5 lines, we have : aes256-ctr bcrypt. This tells us that the private key is probably encrypted.

Furthermore, when we go at the bottom, we no longer have information regarding the owner of the private key as well as the host on which it was generated :

To retrieve these information, we will need to crack the private key’s passphrase. Here is how we can do that with a hash cracking tool called John the Ripper :

1/ Convert the private key into a hash file understandable by John using the ssh2john command :

ssh2john protected_id_rsa > protected_id_rsa.hash

protected_id_rsa and protected_id_rsa.hash represent respectively the protected ssh private key and the generated hash that will be sent to John for cracking.

2/ Cracking the ssh private key's passphrase with John

john --wordlist=<WORDLIST> protected_id_rsa.hash

Great ! As you can notice, we were able to crack the passphrase of the SSH private key. Therefore, we can enumerate the information by removing the passphrase from the private using this command :

Removing passphrase from the protected ssh private key

-p requests changing the passphrase of a private key file instead of creating a new private key.

When asking you to enter the old passphrase, simply provide the password returned by John.

After that, you should be able to retrieve the private key information :

Common Vulnerabilities

Here are some known vulnerabilities that affected OpenSSH in the past :

CVE-2016–6210 : OpenSSH before 7.3 allows remote attackers to enumerate users by leveraging the timing difference between responses when a large password is provided (refer here for more information)

CVE-2018–15473 : OpenSSH versions prior to 7.7 allows username enumeration through a malformed public key authentication request (you can find an exploit here)

Note : These vulnerabilities could simply be detected by running ssh-audit against the target but it is always good practice to have these information in mind as a pentester.

Wrap Up

In this post, we covered several interesting topics regarding SSH penetration testing. I hope that you really learned something new and enjoyed the content. If so, do not forget to click on the little clap icon below and subscribe to my newsletter to keep up with my latest articles !

Last but not least, Hack the planet 😎

--

--

0liverFlow
0liverFlow

Written by 0liverFlow

Pentester | Enjoy breaking and building stuffs

No responses yet