/ penetration testing

Man-in-the-middle SSH? Yes, please.

Some days ago I stumped upon a github repo called "ssh-mitm" and that triggered me.
The GitHub repo: https://github.com/jtesta/ssh-mitm
Why? Well, everyone in the PT world is quite used to the concept of doing MITMs against cleartext protocols like HTTP, FTP, Telnet and so on.
The only encrypted protocol that I (and many others) targeted in MITM is HTTPS (well, I also did it against RDP but that's another story)
But SSH is a quite common protocol, why doesn't get attacked SO brutally like HTTPS? Let's find out!

The theory

The attack implemented in the tool is not well documented, so I tried to understand the concepts behind it.
That's a summary (and a simplification) of what is happening under the hoods:

sshmitm
Let's break this process step by step:

  • The Attacker machine is in a MITM position respect to the victim machine and the SSH server
  • A patched version of openssh is running on the attacker machine.
  • The victim tries to connect to the original server, its traffic gets redirected to the attacker machine
  • The attacker uses iptables to rewrite the destination of the SSH connection and point to its own patched SSH server
  • The rogue SSH server accepts any type of auth.
  • The victim receives the classic credentials prompt and send the creds to the attacker machine
  • The patched SSH server connects to the original server with the provided credentials.
  • If the credentials where valid, the SSH server acts like a proxy and forwards everything to and from the original SSH server.

There's a lot going on.
The developer did a huge work patching the OpenSSH server to make it act in this way.
But, is that SO easy? Is the world over?

No, obviously SSH has a way to prevent this, and it is called known_hosts.
The known_hosts file is a collection of public keys fingerprints of the servers you previously connected to.
In this scenario, the rogue SSH server has no way of presenting the right public key (well, it might do that, but without the private key it is pretty useless) and the connection is dropped, so if a users tries to connect to a known server it will receive an error (we will go deeper in the practical section).
However, if the user is trying to connect to the server for the first time the attack will work trasparently.

The practice

In this section we will cover the practical aspects of the SSH MITM attack. The setup for this test will be the following:

  • The victim machine: My Macbook Pro
    • IP: 192.168.0.221
  • The attacker: Kali Linux VM
    • IP: 192.168.0.222
  • The SSH server:
    • blog.riccardoancarani.it
    • ;)

Setup

First of all, it is necessary to install the tool in the attacker machine.
The README in the Github repo is quite enough, just clone the repo with:

git clone https://github.com/jtesta/ssh-mitm.git

cd into the ssh-mitm dir, and run as root:

./install.sh

this will install all the necessary dependencies, build the patched server and everything else is needed.

Attack

Let's start with running the script called start.sh

Schermata-2018-11-17-alle-20.07.52

this will setup iptables rules as needed.
Now we need to perform an arpspoof that targets the victim and the server, in my case the server is outside the local network so I'll target the default gateway instead.
You can use your favourite tool for MITM, I'll use the old arpspoof for semplicity.

arpspoof -t 192.168.0.221 -r 192.168.0.1

Schermata-2018-11-17-alle-20.11.16

In order to monitor the retrieved credentials, you should also run this command:

sudo tail -f /var/log/auth.log

We are ready, let's try to connect to the SSH server blog.riccardoancarani.it with the victim machine:

Schermata-2018-11-17-alle-20.15.54

NOOOO what happened?
known_hosts, do you remember?
Apparently, I already connected to this SSH server and I have its fingerprint, now my machine is refusing to connect to the server (and with a reason :P)
See, keys changes for a lot of reason, like updates and so on, it is not a strange or particularly suspect error, it just happens! (like you do with invalid SSL certificates, do you remember?)
The sysadmin in this case would probably remove the previous key and retry to connect:
Schermata-2018-11-17-alle-20.17.41

Schermata-2018-11-17-alle-20.18.15

credentials stolen ;)

Note that if the first shown attempt would have been the first time I connected to the SSH server, no errors would have been shown.

Limitations

It is not possible to apply this technique against servers that accept only key authentication :(

Other stuff

  • There is also a script inside the repo that periodically spoof group of IPs in order to find who's trying to use SSH, this could be useful in large environments.
  • Technically, if the credentials are valid, you could see the commands that the user is executing, cool but credentials are enough for me.

Outro

Big claps to the author of this nice tool, use with caution!
I hope I showed you an unconventional attack that you can try in your pentests.
Share this article if you found it interesting!
Happy Hacking!