SSH Pentesting
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>
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>
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>
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>
Medusa
Syntax : medusa -h <TARGET> -u <USERNAME> -P <PASSFILE> -t <THREADS> -M ssh
Patator
Syntax : patator ssh_login host=<TARGET> user=<USERNAME> password=FILE0 0=<PASSFILE> -x ignore:fgrep='Authentication failed.'
Checking if password is valid
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 :
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 wheretest.txt
will be sent:/tmp
: represents the destination directory wheretest.txt
will be saved.
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 :
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.
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>
/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 :
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.
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 :
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 :
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>
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
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 :
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
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 :
-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 😎