Thursday, July 19, 2007

Discussion summary on improving SSH

SSH (OpenSSH) is a workhorse for secure web administration and, as such, important for managing Internet servers including email. SSH is, usually, the only way to access remotely located servers. Of course, this makes SSH a valuable attack target.

There are established practices for securing SSH. However, they currently rely substantially on additional systems, that also present their problems and add to the maintenance burden.

After some discussion in the list and in private, I present below a summary of the dialogue and clarifications with a view to improve SSH. I've divided it in sections A-F, to make it easier to discuss.

The free test tool Nessus allows a remote SSH server to be quite easily discovered and explored by automated scans & attacks. The information obtained in SSH server scans can be typically divided (from the view point of a sys admin) in six issues (to be discussed later, this is just a list):

1. no way to block scanning and attacks
2. does not learn from attacks
3. advertises itself and the server OS
4. allows empty authentication requests (eg, requests by invalid users)
5. sends host key fingerprint to invalid users (eg, with no username)
6. sends a reply to invalid users (eg, with no username)

These issues, alone or in combination, can lead to multiple vulnerabilities, some with higher security significance than others (according to operational factors as well).

Let's first state that not all the six issues are created by crypto use in SSH. And this leads us to the main question here:
Could new crypto in SSH help mitigate or solve any of these six issues?
Currently, how are these issues addressed? By non-portable and potentially buggy methods (see below), with more software that has to be patched, updated, configured and tested, all at different times, with added security gaps that can be compromised.

New crypto methods in SSH could do a better job by reducing the problems in the first line of defense at SSH itself and by avoiding security gaps. Non-crypto things such as PAM, tcpwrapper, port-knocking, grey-listing and others can always be added later anyway, if desired.

Some issues could be minimized by turning off password authentication, to use only private/public keys (PKs). SSH allows users to generate PKs without cost (no need for a CA). Users can keep their private keys in their drives and also in a USB dongle, for example. One can also add second-channel authentication (e.g., RSA SecurID) to SSH with a PAM or a patch.

However, turning off password authentication is not desired in many cases, even when PKs and second-channel authentication are used.

Password authentication may be more secure against attacks on the client, to gather information before compromising the server. According to Peter Gutmann, a study of SSH attacks a few years ago showed that nearly two thirds of all SSH private keys were stored on disk with no password protection at all, so that simply being able to read a hard drive will get you access to any number of systems without having to trojan the SSH client or plant a keyboard logger as you'd need for an SSH password. So turning off password authentication could make things less secure, not more.

Another reason for using passwords in SSH, and perhaps more compelling, is that you don't want to risk getting locked out just because your disk died, you forgot your laptop, SecurID or USB dongle, and the private key cannot be found (for security reasons!) in the back-up. Passwords can also easily be given over the phone from sys admin to sys admin, and are easily protected by threshold cryptography. And using a private/public key pair in SSH would anyway require a password for protecting the private key.

Using good, high-entropy passwords turns out to be preferred by many sys admins because it is simpler, more portable, and works fine for security (provided the password is chosen with enough entropy). Sys admins already need to use many passwords for many servers and protocols, and have safe methods for off-line storage, redundant record keeping, and authorized record access (including a handwritten notebook, encrypted USB dongles, and a printed list), that are of course not kept near the computer.

Some of the issues can be solved with SSH PAM, such as pam-abl. However, PAM libraries are usually buggy (buggier than SSH), and might be unstable unless suitable PAM items were added by which the daemon can communicate the client IP address and port number, and maybe other things too.

I believe that each one of the issues 1-6 can be met by a cryptographic protocol deployed in SSH. Some solutions are well-known. BTW, there were some similar issues in the SSL protocol.


#1. no way to block scanning and attacks
Firewall port-knocking can help here. It is hard to guess and defeat; nothing shows up in scanning. However, it is not portable and is hard to debug and use.

While there are also IDS that can turn off the SSH port if a scanning is detected, this can lead to DoS.

Pam-abl can also help, but PAM is usually buggier and adds security gaps.

Possible solution: SSH could easily incorporate some of the pam-abl code, enough to block an IP for some time T after N failed attempts, self-clearing after T.
#2. does not learn from attacks
Possible solution: SSH can incorporate some of the pam-abl code for this purpose.
#3. advertises itself and the server OS
"Need to know" is a valuable security policy.

Advertising the OS may compromise a higher security function (the OS) in the case of a zero-day or unpatched exploit. SSH MUST NOT advertise the OS. It may compromise policies and apps in a lower (more critical) layer than SSH, not just the OS.

Also, advertising SSH's innards in "already dead" authentication has no useful purpose that could not be more securely met.

Possible solution: let the client tell its version to the server, for the server to decide if it is acceptable -- it is a server function anyway (eg, not to accept SSH v1).

Additionally, it would also be useful for the client to send to the server a list of acceptable configurations, for the server to select, so that the server would no longer be groping in the dark as to what algorithm and parameters to use.
#4. allows empty authentication requests (eg, requests by invalid users)
#5. sends host key fingerprint to invalid users (eg, with no username)
#6. sends a reply to invalid users (eg, with no username)

- Some claim that the SSH protocol requires key exchange to occur before the user identity is sent, as it protects the user identity from disclosure to an impersonator.

However, if the user does not have a valid username, why and what should the server have to prove to that user? Invalid data deserves either "no response" (safer) or an error response. The SSH server should not do work or provide information to an user that is known already to be invalid. The SSH protocol needs improvement here.

- Some also claim that if the SSH protocol would permit such differing responses for valid/invalid users, then attackers can use SSH as an oracle to determine username validity.

However, SSH can prevent username enumeration by trial and error. With a simple keyed-hash, if this protection is desired, one would just enter the same key for the server and clients, so they can be all using the same transform. This is a simple mechanism that hackers cannot break by guessing. Note that SSH already uses a hash mechanism to hide domain names in the hosts file.

- Some claim that the issues #4 and #5 are actually "features" that are used by some of the anonymous services, such as anonymous CVS.

However, these "features" could be closed by default, and opened in the sshd config file if desired. This may also need some cryptographic protocol changes.
Because the reported issues could be improved by adding crypto, I am asking for more input first, before taking these issues to the OpenSSH development list. This should help the development effort. The OpenSSH development mailing list is at:

Thanks for all the input! Comments are welcome.

Ed Gerck