1

With password authentication you're basically giving your password to the attacker. At least that is my understanding. What about public key authentication? I hear that a private key never leaves your side, and that it's not possible to perform a man-in-the-middle attack with public key authentication. Is that so? Is there anything else I'm missing here?

x-yuri
  • 257
  • 3
  • 7
  • 1
    Your title and your body appear to be different questions – schroeder Nov 08 '21 at 11:29
  • @schroeder You think so? Maybe after changing the title a bit they are more in line? My understanding is that with a man-in-the-middle attack an attacker basically gets access to your account. But it seems that with public key authentication a man-in-the-middle attack is not possible. In other words the body is more specific. But if my understanding is wrong, I'd like to know the whole picture. – x-yuri Nov 08 '21 at 11:40
  • Are you asking if you ignore the warning that you could fall victim to a mitm attack? – schroeder Nov 08 '21 at 11:59
  • @schroeder That, and if I understand the implications of the mitm attack correctly, and if there are any other implications. Updated the question. – x-yuri Nov 08 '21 at 13:10

2 Answers2

4

Publickey authentication does not mitigate man in the middle attacks, but the risk of compromising other servers can be reduced, depending on the client configuration.

Sorry for the long answer, but there are a lot of answers and articles, which does only explain a specific part of mitm attacks on ssh.

Definiton of a man in the middle attack:

Network Layer: If you talk about a man in the middle attack on the network layer, this attack is very easy. If the attacker has access to the network, is possible to redirect the traffic to a different server using arp spoofing or BGP route injection. There is not much you can do against such attacks, if you are only in control of your client.

When talking about this layer, most connections are vulnerable to mitm attacks and you are able to intercept ssh connections.

Application Layer: To mitigate the risk of a man in the middle attack on the application layer, the connection must be encrypted. This is the reason, why a lot of protocols like HTTPS are using certificates to make sure, that they are connecting to the right server and the traffic is encrypted.

The certificates which are used for HTTPS connections are signed by a Certificate Authority (CA) and the public keys are distributed with the operating systems or the browsers. As long as the CAs are trusted, a man in the middle attack is not possible, because they does not establish the connection if the certificate is not signed by a known CA.

OpenSSH also supports certificates, but those are not compatible with the certificates used by webservers and administrators has to setup their own CA. Another problem is, that most ssh clients does not support certificates.

When using publickeys without certificates, you must verify the fingerprint. This is the part you mentioned. The server fingerprint must be compared against a trusted source to make sure, you are connecting to the right destination server. It's the only step which guarantees, that you are not affected by a man in the middle attack (as long as the destination server is not compromised or malicious).

If the connection to a malicious server is established, the attacker has full control over the session and has access to a lot of information and depending on the configuration of the ssh client, it's possible to connect to other servers. This is what most people understand as a mitm attack on ssh.

Implications of ignoring ssh host key warnings:

This depends on the used client, the client configuration and the operating system.

The ssh client sends all public keys to the server (CVE-2016-20012). Those keys are used to spoof the login process against the remote server and the attacker knows if publickey authentication is possible and which key will be used for authentication. This is neccesary for spoofing attacks (CVE-2021-36367, CVE-2021-36368, CVE-2021-36369) against the login process.

Agent was not forwarded:

If you are not using agent forwarding, the attacker can redirect the session to a honeypot. On the honeypot, the attacker is able to collect information (entered passwords, filenames, ...), which can be used for other attacks. If the connection was established by a script, the script does not recognize that the connected server is only a honeypot. If the honeypot can react properly on the input, error during script execution can be avoided. Interactive sessions are also possible, but it's more likely that the users detects the honeypot.

Agent forwarded:

If you are using agent forwaring, it's likely that you are vulnerable to mitm attacks, even if you are only using publickey authentication.

Agent forwarding allows the remote server to access your local agent and performing key operations with your private keys. Private keys never leafs the client, as long as the client is not vulnerable to the roaming bug CVE-2016-0777.

Using agent forwarding does not mean, you are vulnerable to mitm attacks. If you are vulnerable depends on the client configuration. In most cases the default configuration of agent forwarding is highly vulnerable to mitm attacks!

There are some use cases, where you need to work on a remote server and access another server (e.g. git repository). To access the git repository over ssh you need a private key.

You have 2 options.

  • password protected private key stored on the remote server
  • using agent forwarding

Which method is better and more secure depends on the used client, the configuration and the operating system.

password protected private key stored on the remote server

If the server is compromised, the attacker is able to read the password for the private key. You should only use a stored private key, if it's not possible to configure agent forwarding to be secure (details explained in agent forwarding).

Agent Forwarding

When using agent forwarding, you must always protect your keys with ssh-askpass or a fido2 token. If the private key is used, you have to confirm this usage and abusing a forwarded agent becomes harder.

WARNING! The described setups does not protect you from a mitm attacks! It only reduces the implications, if you are affected by a mitm attack. You must always verify the server fingerprint against a trusted source!

Windows:

Most users are using PuTTY for SSH connections, but with Windows 10, OpenSSH can be installed as an extra feature.

PuTTY has it's own agent (pageant) which can be forward to another server. Pageant does not support ssh-askpass or fido2 token. When using PuTTY on Windows, it's not secure to use agent forwarding. The Windows version of putty is not able to use the windows version of OpenSSH's agent. (There are some tools, which allows to use the openssh agent with putty, but I had no time to test them)

The windows version of OpenSSH is < 8.2. This is important, because with OpenSSH 8.2 a lot of security features are implemented. It's not possible to use a fido2 token. Even if you are using ssh-askpass in combination with agent forwarding, the authentication process can be spoofed and you are vulnerable to a full mitm attack.

When using PuTTy or OpenSSH under Windows, it's not save to use agent forwarding.

When using windows and you must access another remote server, you should use a password protected private key stored on the server.

Linux & PuTTY:

When using Linux you should use PuTTY>0.71 in combination with the OpenSSH agent. Since version 0.71 PuTTY is able to detect spoofing attacks.

When using a vesion <0.76 you can detect spoofing attacks with the trust sigils. Since 0.76 PuTTY has a new option to close the session if a spoofing attack was detected.

When using PuTTY>=0.76, you should use Disable "trivial" authentication (SSH-2 only). This option can be found under "Connection -> SSH -> Auth".

All keys which are managed by the OpenSSH agent must be protected with a fido2 token or ssh-askpass.

With this setup, PuTTY is able to detect spoofing attacks and closes the session. This is the most secure setup and even better than stored private keys on the remote server.

Linux & OpenSSH:

If you have an OpenSSH version < 8.2, you should not use agent forwarding, because those versions does not support forwarding different agents.

When using OpenSSH >= 8.2, you must configure 2 agents and only add the necessary key, which is used to access the remote servers. Let's call them "agent1" and "agent2".

You must also use different keys for each server!

Agent1 is used to login to the first remote server. This agent has only access to the key, which is necessary to login to the server. That key can be protected with ssh-askpass or fido2 token.

Agent2 is used to be forwarded to another server. That agent must only contain keys which are used to login to remote server and the key which is used to login to the first server must not be included. All keys in the second agent must be protected with ssh-askpass or a fido2 token.

Release notes of OpenSSH 8.2:

sh(1): allow forwarding a different agent socket to the path
   specified by $SSH_AUTH_SOCK, by extending the existing ForwardAgent
   option to accepting an explicit path or the name of an environment
   variable in addition to yes/no.

With this setup the attacker is not able to do a full man in the middle server to the first remote server, because the necessary kay is not forwarded. If the attacker tries to connect to another server, you will be prompted with a confirmation dialog and you are noticed, that a malicious server tries to abuse your forwarded agent.

Proof of Concept MitM Attack

If you want to test your configuration, you can use SSH-MITM, which is an audit server for ssh connections.

Install SSH-MITM on linux:

python3 -m venv ~/sshenv
source ~/sshenv/bin/activate
pip install ssh-mitm

Start SSH-MITM and redirect session to a honeypot if publickey authentication failed:

ssh-mitm server --remote-host target --remote-port 22 --fallback-host honeypot --fallback-username honeypotuser --fallback-password honeypotpasswd 

This configuration checks, if the user is allowed to login with publickey authentication. If the user is not allowed, password authentication is used.

If the user is allowed to login with publickey authentication, but no agent was forwarded, SSH-MITM redirects to the honeypot.

Conclusion:

When agent forwarding is not used, you can only be redirected to a honeypot.

If you need agent forwarding on a windows machine with PuTTY or the windows version of OpenSSH, it's not possible to mitigate mitm attacks. Perhaps you can use another client (e.g. cygwin), but I have not tested this at the moment.

The most secure option is to use PuTTY on a Linux machine in combination with OpenSSH's agent and keys protected by a fido2-token or ssh-askpass.

When you need OpenSSH, you must use 2 agents, but I don't recommend this setup, because it's error prone and complicated.

Disclosure: I the author of SSH-MITM, which is a mitm server for SSH connections. This server is used to verify if the described mitigation strategies can reduce the risk of mitm attacks on ssh. I have also written the patch for PuTTY to mitigate trivial authentications without the trust sigils.

Manfred Kaiser
  • 1,236
  • 2
  • 4
  • 19
  • So, is [this](https://www.gremwell.com/ssh-mitm-public-key-authentication) only part of the truth? My guess is, the article is only considering the case where an attacker wants to just listen in on the communication. And with pubkey auth that will fail. But an attacker can be smarter then that. He can authenticate the client, then authenticate on the server (if he's able to employ a possibly forwarded agent), and after that he can retransmit the packets as is. Or just present the user with a fake server (a honeypot), if he can't exploit the client's agent. Is that so? – x-yuri Nov 09 '21 at 16:20
3

The ssh host key warning means that the public key that your ssh client now sees for the server is not the same as the public key that your client saw for this server previously. This means that you could be connecting to a malicious server being run by an attacker - either in an attempt to spoof the 'real server', or in an attempt to MITM the connection to the real server. If that's the case, and you ignore the warning, then you will be enabling the attacker to proceed with the attack.

One benefit to public key authentication over password authentication in this case is that if the attack succeeds, the attacker does not come away with anything useful for authenticating with the real server. With public key authentication, the client only divulges his public key (which is public anyway), instead of divulging his password.

mti2935
  • 19,868
  • 2
  • 45
  • 64
  • And what about implications or, should I say, risks? If I use password authentication, the password might get into attacker's hands? In case of pubkey authentication, my key won't get compromised, but an attacker will be able to see all the communication, and run arbitrary commands on my behalf (while the session is active)? Is mitm attack even possible with pubkey authentication? According to my link it's not. In case of server spoofing it's probably harder to talk about implications. If I end up on an attacker's server, then probably again, all communication can be intercepted. – x-yuri Nov 08 '21 at 18:35
  • 1
    @x-yuri: As far as I can tell a MiTM is not possible with pubkey authentication. Of course you are still talking to an attacker's server so whatever you send will be captured by the attacker. If all you do is bring up a terminal, type `ls -l` and realize you're not talking to the correct server and then disconnect then little damage has been done. – President James K. Polk Nov 08 '21 at 22:49
  • @x-yuri I think President Polk covered most of the bases. With an active MITM in an SSH connection, if the client attempts to authenticate using public key authentication, then authentication will fail. See https://www.gremwell.com/ssh-mitm-public-key-authentication for more info. – mti2935 Nov 08 '21 at 23:04
  • the public key is not sent so it is not exposed. The way the public key authn works with ssh is the server already has a copy of the public key in advance, ts a secret token that the client generated with its private key and the server using the corresponding public key to verify only the secret key holder could have that secret that permits login, and a MITM can actually leverage this once but in so doing would tip the client off because they'd have to terminate the client connection and use the token themselves. Its actually server impersonation that public key are a protection for, not MITM – Stof Nov 09 '21 at 10:11
  • 2
    @Stof I believe the client's public key is sent along with the signature. See [RFC4252, Section 7](https://datatracker.ietf.org/doc/html/rfc4252#section-7), where it shows the packet sent from the client to the server to perform authentication (bottom of page 9). The second to last component in this packet is `public key to be used for authentication`, followed by `signature`. – mti2935 Nov 09 '21 at 11:28
  • 1
    The publickey is always sent to the server. Most users have more than one key. In the first step, the client asks the server, which key is allowed to login. If a key is allowed (stored in authorized_keys), a signature is generated. If the key was not allowed, the next available publickey is sent. The first step can be skiped and the signature can be sent directly. This is allowed according to RFC-4252. This avoids leaking all publickeys. In OpenSSH you should use the "IdentitiesOnly" config option, which avoids leaking all publickeys. The configured key is still leaked CVE-2016-20012 – Manfred Kaiser Nov 09 '21 at 13:43
  • Pub key to be used refers to the client signature generation, the public key is never transferred because it's already in the server (peer) you're connecting to. It it wasn't already on the server, auth wouldn't be possible, so sending it is redundant. – Stof Nov 09 '21 at 21:34
  • The client signs using the key you specify, and if you use verbose mode you can see the negotiations whete the server compares the signature, but if you don't specify on the client you can see in the verbose output your client signs with each key it's able too access (ssh-agent too) until one succeeds negotiation. If a piblic key is sent, this entire process of trying key signatures would be skipped wouldn't it? I.e. its obvious that the public key isn't actually sent – Stof Nov 09 '21 at 21:38
  • The publickey is always sent, that is clear from the RFC. – President James K. Polk Nov 10 '21 at 02:56