Brief introduction of SSH better known as ( Secure Shell )  

SSH is a network protocol that is using cryptography to allow users to securely execute various network services. One of the methods of logging into the server via SSH is with Passwords. Every password's weakness is a brute force attack, some passwords can be eventually cracked this way however SSH keys are almost impossible to decipher with brute force attacks.

A simple demo for creating the RSA Key Pair.

Usage:

ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/demo/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/demo/.ssh/id_rsa.
Your public key has been saved in /home/demo/.ssh/id_rsa.pub.
The key fingerprint is:
4a:dd:0a:c6:35:4e:3f:ed:27:28:8c:64:54:4d:83:68 demo@a
The key's randomart image is:
+--[ RSA 2048]----+
|          .oo.   |
|         .  o.E  |
|        + .  o   |
|     . = = .     |
|      = S = .    |
|     o + = +     |
|      . o + o .  |
|           . o   |
|                 |
+-----------------+

The public key is located in /home/demo/.ssh/id_rsa.pub. The private key is located in /home/demo/.ssh/id_rsa.

Now that I have a key pair generated, I need to move the public key on the server that I want to use.

I can copy the public key into the new machine's authorized_keys file with the ssh-copy-id command.

ssh-copy-id [email protected]

Or another method is the oneliner below.

cat ~/.ssh/id_rsa.pub | ssh [email protected] "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >>  ~/.ssh/authorized_keys"

Note: If you want to use only SSH key pair to log into your server you need to edit the sshd_config file located in /etc/ssh. Find and edit the line PermitRootLogin.

PermitRootLogin without-password

Lastly make sure you reload the sshd service so all these changes have effect.

sudo systemctl reload sshd.service

This concludes the introduction into SSH keys.

Interesting part to follow..

Before we move on please see /disclaimer/

I was allowed to PenTest a company (which I prefer not to disclose identifiable information) the only thing I was given was a single hostname. While doing a little reconnaissance e.g finding all the subdomains and port scanning, I had noticed one of them was running SSH on port 22 and I have managed to gain a low privilege user in a SVN server (centralized version control system) through nefarious means (yes, the user had a weak password). To gain root access I had noticed there was a couple entries while executing sudo -l.

(root) NOPASSWD: /usr/bin/apt, caught my attention. Perfect.. looking into how I can exploit this to escalate my privileges I came across this.

sudo apt update -o APT::Update::Pre-Invoke::=/bin/sh
privilege escalation from user to root
privilege escalation from user to root

Navigating in this server I went straight away for the .ssh folder and found the following.

contents of /root/.ssh, found id_rsa private key and contents of known_hosts.
contents of /root/.ssh, found id_rsa private key and contents of known_hosts.

A little bit about the contents of the .ssh folder.

  • .ssh/authorized_keys – holding the signature of the public key of any authorised clients.

And the following files on the client:

  • .ssh/id_rsa – Holds the private key for the client.
  • .ssh/id_rsa.pub – Holds the public key for the client.
  • .ssh/known_hosts – Holds a list of host signatures of hosts that the client has previously connected to.

Perfect! Now I have got a private ssh key, and looking inside the known_hosts the ip addresses weren't encrypted so I can see where else they connecting from this machine. Although in the known_host file were only a few entries and some of them duplicates but it's still a good indication for me because it showed me the format this company has their hostnames for machines.. and they started with service1.company.com service2.company.com and so on all the way to 55! Looking at the netstat traffic and the firewall rules in iptables also confirmed my theory and it showed me all the hosts including a few other ones that were the 'super' controllers and had a different hostname.

This is a good oneliner to find out which hosts are up if you have a big list of known_hosts available.

for i in $(awk -F '[ ,]' '{print $1}' known_hosts);do echo -n "$i ";ping -n $i -c 1 2>&1 >/dev/null && ssh $i "echo -n online"  ;echo; done

So far I've got a id_rsa key and a few of hostnames.. I could manually try to connect to those hosts with the following command line ssh -i id_rsa [email protected], my thinking was.. who owns this key? is this key for root login or for another user..?

Best to try this out before automating.

logging into other servers using ssh private keys
logging into other servers using ssh private keys

I had tried as root@ but it was prompting me for a password so then I tried as the user I had entered in the first place and I logged straight in, looking at sudo again the same apt ... perfect to get root.

Each server was hosting different applications e.g phpMyAdmin , MariaDB databases, openresty and so on. I had also noticed the increase in specs as I moved through each server, from 1-3 processors to dedicated servers i7, i9 processors with a ton of RAM memory..and even 30+ processor servers. This was overkill.. There was a lot of data to go on, alot of custom scripts, servers for backing up to remote servers, ftp servers.. all sorts of servers! and I had the credentials to all of them! How? looking through their custom scripts most passwords were hard coded but a good point for them was that they weren't reused for other services and at least they were generated, so.. pretty strong!

Automating

I have found out about a really good tool to do this, it's called crowbar.

Crowbar is brute forcing tool that can be used during penetration tests. It is developed to support protocols that are not currently supported by thc-hydra and other popular brute forcing tools. Crowbar supports OpenVPN, Remote Desktop Protocol, SSH Private Keys and VNC Keys.

By this point I gathered all their IPs nearly 100 in total and placed them in a file where I used crowbar. A small note here I have to use this format IP/CIDR notation <192.168.37.37/32, 192.168.1.0/24>.

Brief example using crowbar with sshkeys
Brief example using crowbar with sshkeys

Nearly every ip address that I had gathered and was online I managed to log inside and further look for new hosts.

Where things can get even more interesting...

Many companies have from tens to hundreds of servers internally, those are not publicly available to connect to, with such a tool and the ssh keys or credentials I could attempt and brute force my way into the whole internal network.. but is there any? I'm yet to find out.

I need to scan all the Private IP addreses, now I know their ranges are those:

  • Range from 10.0.0.0 to 10.255.255.255 — a 10.0.0.0 network with a 255.0.0.0 or an /8 (8-bit) mask
  • Range from 172.16.0.0 to 172.31.255.255 — a 172.16.0.0 network with a 255.240.0.0 (or a 12-bit) mask
  • A 192.168.0.0 to 192.168.255.255 range, which is a 192.168.0.0 network masked by 255.255.0.0 or /16

A private IP address is reserved for internal use behind a router or other Network Address Translation (NAT) device. Sometimes a private IP address is also referred to as a local IP address.

For this I'm going to use a Fast SYN Scanner to collect any listening ip on port 22 or 2222 (quite common) on the ranges I mentioned above. And then I will append with awk the IP CIDR (/32) to them as it's a crowbar's requirement.

awk '{print $0"/32"}' input > output
This is a method that is widely used by hackers whom want to penetrate networks even further and use all the resources from all the hosts for mining cryptocurrencies.

I personally have seen networks that had even 20-30 thousand internal hosts in a network.. so you can imagine the damage there.

Conclusion

Leaving your private keys and using a weak password could lend a company in big trouble very quickly. Even though all the servers in question were under firewall I was unable to log into them from outside the network but there was 1 server that allowed me to log inside and from there I made it all the way into all of the servers.

Below is my advice in regards to this.

  1. Be careful where store private ssh keys.
  2. Don't use weak passwords.
  3. Change the default ssh port to something uncommon.
  4. Install fail2ban!
  5. Avoid using passwords to log into servers.. try to use authorized keys.

Have you got any suggestions for me ? Get in touch!

Thank you for reading my article, Until next time!

Your friendly neighbourhood Hacker.

You've successfully subscribed to Flaviu Popescu
Welcome back! You've successfully signed in.
Great! You've successfully signed up.
Success! Your account is fully activated, you now have access to all content.