Versão em Português

The Debian OpenSSL Predictable Random Number Generator Vulnerability

Rec 17-may-2008 14:08

By now you probably heard it elsewhere, but here's my take on the issue: several crucial programs that use public key cryptography services provided by certain versions of the OpenSSL library shipped with Debian-derived Linux distributions (including Ubuntu and Kubuntu) have a severe vulnerability that may enable attackers to gain access to your machines. The exact extent of the possible access depends on how exactly things are set up in your computer, as I'll explain below.

The root of the problem is this: almost two years ago, one of the maintainers of the Debian version of the OpenSSL package disabled a few lines of code in the random number generator. The motivation behind the change seems to have been because running that particular part of the code through Valgrind, one of many automated tools for finding common problems in computer source code, caused it to complain about a possible use of uninitialized data. This would prove to be a disaster.

The security of almost all crypto-based programs depends on choosing keys that are unpredictable by an outsider. Normally, when you ask the OpenSSL routines to generate, say, a x-bit number, it is randomly drawn from a set of 2x numbers. Let's work this calculation out for a couple of values:

  • If you ask for a 32 bit random number, it'll get you one from a set of four billion possible numbers.
  • If you ask for a 64 bit random number, it'll be drawn from a set of eighteen quintillion numbers. It's a set so large that most people can't even imagine it.

When choosing keys for public key cryptosystems, we need random number larger than 100 decimal digits; the size of the set where this number comes from is so absurdly large that most people don't even know what to call it, yet it does have a name -- it's "ten duotrigintillion" items, also known as "one googol".

But what all that means is that the chance of an outsider guessing the correct number that comprises our keys is next to nil because there number of possibilities is all those duotrigintillions. Trying each and all of them is not viable for the exact same reason: it's just too much. In other words, your key derives its security from being indistinguishable from the rest of the crowd.

The change the Debian maintainer made to the code, however, caused the OpenSSL random number generator to output random numbers drawn from a set of only 32,768 possible numbers. Suddenly the crowd is WAY smaller, so small that it becomes perfectly viable to list them all.

Most users of Windows probably never heard about SSH, but most users of Linux that go beyond the graphical user interfaces, myself included, use SSH every single day. For the benefit of my many Windows-centric readers: SSH is kind of a remote control program that allows people to control their computers over the Internet, a bit like Windows' Remote Desktop, but (normally) much more secure. Find out more about it at the Wikipedia entry for SSH.

SSH uses public key systems for two things: authenticating servers and optionally authenticating users. But because of the change the Debian maintainer made, if you generated the server keys (automatically done when the SSH server is first installed or upgraded) with a vulnerable version of the software, the key is almost guaranteed to be in that list (or that one).

This means an outsider can mount what crypto people call a "man-in-the-middle attack": first, he asks your SSH server for its public keys (the server can't deny, otherwise legitimate users wouldn't be able to connect.) Then he uses the list to see which private keys correspond to your public keys (that's the part that fails if the random number generator is good.) Now he can install a SSH server that identifies exactly like yours. If he can also redirect you to his server (not a very hard thing to do), it can lure you to connect to his server instead of yours and, if he is careful enough, you won't notice the difference well past the point you typed in your passwords. If the attacker is really careful, you might not notice at all.

For authenticating users, SSH provides several authentication methods. You can use the older "name+password" method, but many people, myself included, use the modern "public key authentication" method, which is normally more secure and provides lots of other practical advantages: for instance, you could give me acess to a server just by putting my public key there -- I woundn't need to go there and set up yet another password; this makes it possible for me to have one single password to remotely access several computers yet none of them actually knowing what my password is.

However, if the key I use to identify myself was generated with the vulnerable SSH version from Debian, my key would surely be one of those 32,768 -- which means it would be easy for an outsider to figure out exactly what is the corresponding private key. Unless something else stops him, this outsider could access all the computers I have access to, just as I can.

Notice that the vulnerability is in the key generation process. This explains why I wasn't affected myself -- my current SSH keys were generated circa 1999, using a version of the SSH program that didn't have this random number generator problem. If your personal keys (in ~/.ssh/id_dsa or ~/.ssh/id_rsa) arent't in the compromised set, you aren't in the high risk group. But there may be other risks -- read on.

To check whether your key is affected, do this:

  • Upgrade to the latest version of the SSH package. First, give a apt-get update to get the new package lists. Then, in Debian, give a apt-get install openssh-client openssh-server openssh-blacklist. The upgrade process will check whether your server's keys are vulnerable and offer to regenerate them. If they weren't vulnerable, they'll be kept unchanged. This will solve the "server" part of the problem.
  • Run the ssh-vulnkey utility that comes with the new version of the SSH tools. It will check whether the keys in your ~/.ssh directory are vulnerable. If it says "COMPROMISED", you generate a new set of keys with the ssh-keygen utility (read the man page for details). Now you should copy those new keys to all ~/.ssh/authorized_keys files in every server you previously copied your vulnerable keys to. This is the tricky part -- it may very well be that you don't remember all computers you ever copied your vulnerable key to; or some of them may be unreachable to you at the time. And if you have a vulnerable key in hundreds of servers, it will be quite a lot of work.

The new SSH server will reject connection attempts from users using keys in the blacklist, so even if your system still has users with vulnerable keys, they will no longer be able to connect.

On the other hand, the new SSH client will not prevent you from connecting to servers with blacklisted keys. This is a bit unfortunate, because you may have no simple way to determine whether you're connecting to your real server or to a trap in the form of a man-in-the-middle attack. But it is understandable why the OpenSSH developers did this: in many cases, SSH is the only way people have to get to their servers. If the new SSH client prevented them from getting there, it might render the users unable to fix them. But you shouldn't connect to servers with blacklisted keys unless you have other means of making sure you're actually connecting to the server you really intend to.

If your version of the SSH toolset already has the ssh-vulnkey utility, you can test if a remote server has vulnerable keys with the following commands:

ssh-keyscan -t dsa,rsa your-server-name-or-ip-address | cut -d' '  -f2- | ssh-vulnkey -

(The "ssh-vulnkey" man page has a similar recipe, but it doesn't work; the ssh-keyscan utility outputs an extra initial field with the server address that the ssh-vulnkey doesn't understand. That's the reason for the cut command in the middle for the pipe.)

The problem may be deeper still: one thing I didn't see people commenting all that much was the impact of all this to the symmetric keys used for encrypting the bulk data past the authentication phase. If there are only 32,768 symmetric keys as well, it should be trivially easy to decrypt the data in transit (that's why intelligence agencies record everything, even if they can't decrypt it today -- they might be able to decrypt it later.) The sad conclusion would be that during almost two years, Debian's SSH was almost as insecure as TELNET.

This whole mess brought new fuel to an old holy war: the fact that the Debian maintainers make changes of their own in many packages. I think that most of the time this is a good thing: it keeps the platform stable and things generically working. For instance, I recently had a 2.6.18 kernel failing to run on a brand new server because it didn't have support for the Intel ICH9 SATA chipset, while Debian's 2.6.18 kernel worked just fine because the maintainers usually backport new hardware support from newer kernels. This made a lot easier to get the server running and pinpoint exactly where the problem was so we could fix our custom kernel as well.

In the OpenSSL's random number generation mess, however, we had a critical security code changed by someone who obviously didn't understand the implications. I wouldn't want to be in that guy's shoes; no doubt many curses are being directed his way. And it also gives Debian a bad press that I think it doesn't deserve, along with the usual jokes. People hav even been ressurecting an old Dilbert strip.

My suggestion to the Debian people is to have only certain knowledgeable people touch security critical stuff. But, sure, this easier said than done. The mere act of establishing what constitutes "security-critical" is a lot of work already -- plenty of stuff that doesn't look like security-related at first sight and yet it is ("Ooooh! I didn't know that a random number generator was a security critical thing!"). Let alone gathering knowledgeable volunteers.

Kiko > EnBlogEntry2008May17A
Creative Commons License   The content of this site is made available under the terms of a Creative Commons License, except where otherwise noted.
  O conteúdo deste site está disponibilizado nos termos de uma Licença Creative Commons, exceto onde dito em contrário.