More on SSH, public key authentication, and 'man in the middle' attacks

October 29, 2016

Several years ago, I wrote an entry on the (apparent) resistance of SSH public key authentication to man in the middle attacks. In this entry I concluded:

[...] I believe that if you use public key authentication you're probably immune to man in the middle attacks.

I think I was too cautious here, because I've recently come to realize that for public key authentication the SSH protocol must have a very closely related property that I'm going to call 'connection laundering resistance'.

Let's assume that you have some public keys that authenticate you to some valuable service (such as Github, to make this concrete). Suppose, not at all hypothetically, that an attacker can get you to connect to a random SSH server under their control, and that as part of that connection you offer to authenticate to that server with your Github public key.

(If you think this is implausible, it's been demonstrated as a cute toy to show how SSH keys are a potential information leak.)

One of the things the attacker can do as you connect and offer your user name and SSH public keys is to turn around, make their own connection to the valuable service (here, Github), and offer your public key up to authenticate their own connection. When Github challenges them to prove that they possess the private key, they turn around and send your original connection the same challenge, then pass your answer back, and so on. They are not a man in the middle because they never claimed to be Github; instead they're trying to launder your connection to them into an authenticated connection to Github.

Obviously, it is really important that this attempt at connection laundering not work. The attacker should not be able to get their own authenticated-as-you connection to Github, one that's under their control and they can read and send traffic on, and generally you and Github should fail to authenticate and establish an encrypted connection at all.

In order to make SSH public key authentication practical, I believe that the SSH protocol absolutely must block this connection laundering attack. An attacker claiming to be a one server cannot be able to launder your connection to them into an authenticated connection to second server. And once you have connection laundering resistance, I suspect that it's a short step to extend it even to man in the middle resistance, where the attacker can't win even if they claim to be the same server.

(It would be ideal if they can't win even if they have the server's proper keys.)

Coming to this realization has made me much more confident in my 'probably' in the original entry. I don't think I can conclude that it's absolutely guaranteed, because cryptography is a land full of counterintuitive landmines, but I would now be quite surprised if SSH public key authentication had connection laundering resistance but not MITM resistance.

(And I think the SSH protocol absolutely has to have connection laundering resistance for public key authentication.)

PS: I suspect that there is a proper cryptography term for what I'm calling 'connection laundering' here. If I find out what it is, I'll probably update the use of the term in the entry.


Comments on this page:

You are thinking about public key exchange, like Diffie-Hemman [1]. The paint analogy might help understanding how this works [2].

The idea is that a secret (a key for symmetric encryption) is negotiated by both parties using their key pairs, without communicating the secret over the air. In your scenario, Eve (the eavesdropper) cannot reconstruct the secret since they do not know the server's private key.

For a Man-in-the-Middle attack to work against asymmetric cryptography, an attacker must initiate one connexion with each participant and interface them. In the context of SSH, it means that the user would see a public key different from that of the server's real public key, hence the usefulness of public key pinning, like in SSH or HTTP [3].

  1. https://en.wikipedia.org/wiki/Diffie–Hellman_key_exchange
  2. https://en.wikipedia.org/wiki/File:Diffie-Hellman_Key_Exchange.svg
  3. https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning
By newt0311 at 2016-10-29 02:59:31:

What Yoha said...

"Connection laundering" is not a security failure because the server in the middle will only be able to see encrypted traffic. To actually perform a MITM attack, the middle-man needs to terminate the cryptographic connection. I.e. it needs to be able to use its own private key to talk to the Github server.

Put another way: every router on the internet performs "connection laundering."

Note that a MITM is still possible if there isn't any checking on Github's server pub key. In your earlier posts, you mentioned that this is hard because the session ID is hard to forge but I'm not convinced of that.

By cks at 2016-10-29 13:02:06:

I think I wasn't clear in my entry. In this attack, the attacker is actually terminating the SSH connection (well, your connection). You do 'ssh some.fun.host', which is the attacker's server; the attacker presents their own set of SSH host keys (which you accept), your SSH automatically offers your Github public key to the attacker's server as 'can you authenticate me with this?', the attacker says 'sure' and immediately opens their own connection to Github where they offer your public key. When Github challenges them to sign something with your private key, they turn right around and challenge you to sign the same thing, then pass your answer to Github.

If an attacker can turn your connection to them into their own connection to Github, offering SSH keys broadly is fantastically dangerous. Since SSH does offer keys broadly by default and the people who created SSH aren't crazy (or idiots), I believe that of course SSH stops this attack. If SSH stops this attack, stopping the attack where you think you're actually connecting to Github (with or without the correct keys) seems likely to come along for relatively free, and that's the situation I was talking about in my old entry.

It seems dubious to me that just because SSH does it by default, that must be because it’s not a problem… My guess would be that the protocol does protect against this attack, but I at least do not feel the mere existence of this scenario by default justifies increasing your confidence in the “probably”.

(I do think you are right that being protected against this scenario very probably implies being protected against MitM in general. I’m just less convinced that SSH really is protected against it.)

There are two parts in an SSH keypair: the public key (e.g. id_rsa.pub), and the secret key (e.g. id_rsa). As the name hints, he public key may be shared freely, and the security relies on the secret key remaining… well, secret.

In other words, the authentication (well, the initation of the encryption channel) uses the public key like an username, and the secret key like a password (except the password is never transmitted). So, even though Eve may know the public key, she cannot do anything interesting with it.

If you are concerned about anonimity, you may not want everyone to know your public keys (and being able to link various accounts). This is good practise to use one SSH keypair per service, using the IdentityFile options in .ssh/config. Just to be sure, you may want to use this as global setting:

   IdentitiesOnly yes
   IdentityFile none

and the set e.g.:

   Host github
       Hostname github.com
       User git
       IdentityFile ~/.ssh/github
By David Young at 2016-10-29 20:25:45:

The "challenge" is built by the client, not supplied from the server, and part of it is a hash of a string that includes the server's public host key.

For the record, the attack you are describing has also been described as an "unknown key share attack", as defined by Blake-Wilson and Menezes (http://dl.acm.org/citation.cfm?id=746578). It's an unknown key share because Github thinks they share a key with you but you think you share the key with random.evil.server.

The way to prevent these attacks is, as mentioned above, to make sure you include the identity (e.g. the string "Github") of the person you're intending to talk to in the session key. That way, Github will refuse to accept the forwarded connection.

Written on 29 October 2016.
« How I set up a DHCP client for my backup Internet connection
How modern SSH key exchange provides (strong) protection against attacks »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sat Oct 29 00:10:00 2016
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.