Hacking Linux Exposed





previous article
next article
Solution to Challenging the Man in the Middle
By Bri Hatch.

Summary: This week, Bri solves the mystery surrounding the man-in-the-middle attacks.

Two weeks ago, I challenged you to figure out how a machine was compromised. Let me quickly recap the situation:

On a machine maintained by a very security-conscious administrator, several users had reported that their accounts had been cracked. All the software was up to date, and only ssh access was allowed.

When I tried to log in from home, my ssh client told me that the server's host key had changed. However, when I checked the actual ssh host key files, they were no different than before. Even when I restarted sshd -- and I could see that it was using the correct key file -- it was presenting the wrong key on the network. However, when I started a new sshd server on a different port, it worked correctly.

There was no reason that the same sshd binary should have been acting differently just because it was running on a different port, and there was nothing on the system to explain why it wasn't using the correct key on the default ssh port.

I suspected that someone was using an SSH man-in-the-middle package on the local network. Both sshmitm (part of Dug Song's dsniff[1] package) and ettercap[2] can fill this role. (As it turns out, the culprit was a modified version of sshmitm, so I'll just call it by name henceforward.)

The machine running sshmitm needs to be situated between the ssh client and ssh server. When the client machine connects to the server, the machine running sshmitm intercepts the packets. The sshmitm process pretends to be the actual server. It will follow the SSH protocol specification, providing the host key, agreeing on cryptographic algorithms and keys, and eventually asking the client for the password.

The sshmitm program establishes a connection to the actual server, as if it's a normal ssh client. It takes the data that it receives from the real client, which it has available in cleartext, and re-encrypts it to the real ssh server as appropriate.

Because, in the end, the client sends packets to the server and everything looks normal, there's no way to realize anything is fishy once the connection is established. However each and every byte in those packets is readable (and modifiable) by the sshmitm program.

The sshmitm program was written as a proof of concept, and as such does not have much functionality for an attacker. It merely snags the password supplied by the user. Ettercap can snag the whole session as well, making it more powerful. Both dsniff and ettercap include other crypto-breaking code for SSL sessions too, in case you're not worried enough.

The pivotal security step in establishing a secure SSH session is to verify the ssh host key of the server. When the client connects to a machine for the first time, it presents the ssh host key of the server, as seen here:

The authenticity of host 'blah.example.com' can't be established.
RSA1 key fingerprint is 39:57:1c:9a:c1:8c:cb:4d:f7:25:c8:89:0f:31:fc:6f.
Are you sure you want to continue connecting (yes/no)?

The first time you connect, you have no way to know if that's the correct fingerprint or not[3]. Most folks blindly say "yes." At this point, you've entered the host key into your ~/.ssh/known_hosts so you can compare with later sessions.

The sshmitm (or ettercap) program does not have a copy of the actual ssh host key for the server it's impersonating; thus, it cannot present the correct key to the client. Instead it must generate its own fake host key.

Since a fake host key is in use, the user connecting will see the following (from the previous article) indicating that something is wrong:


sshmitm and ettercap work on the principle that most folks will ignore this warning, which is a pretty safe assumption.

The attacker had been running sshmitm for a while, capturing folks' passwords, which is why several people had found their accounts being cracked. The fact that there was no interference by sshmitm when I ran a new ssh process on port 4321 was because sshmitm was only listening for ssh connections on port 22, and was leaving port 4321 alone entirely.

Now the trouble was figuring out who the culprit was.

In order for sshmitm and ettercap to function, they must be sitting on a machine between the client and server. If the machine in question were somewhere out on the Internet in general, then there would be more than just our machine at stake. However, the easiest position where the rogue machine could do its work would be on the local LAN.

But if it's on the same LAN, it's not in between the client and server, you say? True, but that can be remedied easily enough. All the rogue machine needs to do is poison your ARP cache so that the cache thinks that the attacker is the router or the destination machine. Then all packets to that machine will go through the rogue machine, and it will be -- in the network's eyes -- between the client and the server, even though technically it's just sitting next to them.

In this case, the rogue machine was in a different lab but still on the same subnet. Through simple ARP poisoning it convinced the router that it was my friend's server, and convinced the server that it was the router. It then had an enjoyable time functioning as both a password sniffer and a router for unsupported protocols.

Since I suspected this was the problem, it was pretty easy to figure out where the rogue machine was. I simply pinged all the local machines ('nmap -sP' will do this quickly) and then checked the ARP table ('arp -an') for duplicates. I actually used the following very lame command to show me duplicate entries:

$ arp -an| awk '{print $4}'| sort | uniq -c | grep -v ' 1 '
    5 F8:F0:11:15:34:51

Then I simply looked at the IP addresses used by that ethernet address in 'arp -an' output, ignoring those that were blatantly poisoned (such as the router) and looked up the remaining address in DNS to see which machine it was. It was the desktop machine for one of the students in the lab. I sent all the info I had to the school's IT security folks; later that day they visited the student, and not to offer him a free pizza. Of course, our cleanup had only just begun.

One way to avoid having your password sniffed by tools such as ettercap and sshmitm is to use SSH identities for authentication. This form of authentication uses public/private-key crypto just as the verification of the host key does. Since the password for your key is only stored in your brain, and the private key is never sent across the network, there's no way for a man-in-the-middle attacker to get a hold of your actual private key. In fact, for this reason, MITM software may disable identity authentication, hoping to get you to type your password instead.

The moral of this story is, of course, that you shouldn't blindly ignore warning dialogs, especially those that concern something important like the security of your encrypted connections.

Congratulations to Reiner Schroeppel, who guessed the problem mere minutes after I got my copy of the challenge in my mailbox.


[1] http://www.monkey.org/~dugsong/dsniff
[2] http://ettercap.sourceforge.net
[3] Smart administrators will provide this key somewhere for users to verify, such as on a Web page, in email, etc. An attacker may be able to modify these sources too, but it's an additional measure of security. For more info on what you can do to verify the host key afterwards, see HLE.

Bri Hatch is Chief Hacker at Onsight, Inc, author of Hacking Linux Exposed and Building Linux VPNs. His known_hosts file is over a thousand lines long. Thank god he primarily uses identity authentication, lest he need to remember that many passwords. Bri can be reached at bri@hackinglinuxexposed.com.

Copyright Bri Hatch, 2002.

This article was first published here in ITworld.com Inc., 118 Turnpike Rd., Southborough, MA 01772  on 30-Apr-2002.

previous article
next article