Bugtraq mailing list archives
SSH1 key recovery patch
From: Iván Arce <core.lists.bugtraq () CORE-SDI COM>
Date: Tue, 13 Feb 2001 21:13:58 -0300
Hello, In light of the recent posts to bugtraq concerning the CORE SDI advisory that describes the SSH1 session key recovery vulnerability a few things needs to be noted: - CORE SDI does not provide support services to SSH1 and does not maintain its source tree. However, given the installed base of SSH1 server we considered convenient to include a patch for the problem found. Although SSH.com does not support SSH1 anymore, and it was made clear that their prefered action is to switch to SSH2 to solve the problem, an untested and unsupported patch was provided. The provided patch had two flaws: - Arguments to the kill function were reversed preventing it from actually fixing the bug. This problem was spotted and reported by Matt Power from the Bindview RAZOR Team. - Even with the above problem corrected the patch does prevent exploitation of the vulnerability BUT it opens the door to a Denial of Service attack against the SSH server. I'll comment of the original patch below. 1) { 2) static time_t last_kill_time = 0; 3) if (time(NULL) - last_kill_time > 60 && getppid() != 1) 4) { 5) last_kill_time = time(NULL); 6) kill(SIGALRM, getppid()); 7) } 8) fatal("Bad result from rsa_private_decrypt"); 9) } The rationale for the above fix is to regenerate the key whenever a RSA operation failed - a symptom of an attacker trying to execute the key recovery attack- this does not close the information leakage in the ssh server (namely the existence of an oracle that can be used to infer a session key) but it does make IMPOSSIBLE to exploit it. The patch intends to limit the key regeneration rate to at most one regeneration per minute, in order to prevent a DoS. The problem here is that the code is executed in the context of an sshd *child* process and therefore after the first key regeneration the child process exits (in the fatal() function) loosing all notion of the last time the key was regenerated. This was spotted and reported to bugtraq by Andrew Brown, altho the explaination of why it didnt work was not correct. Below, is a new patch that does what it was originally intended. The rate limit for key regeneration is now put in the alarm signal handler and gets executed in the context of the sshd daemon responsible for doing it. This is not tested other than verifying that it applies correctly and compiles without errors. Our advisory will reflect this change, the patch will be available at ftp://ftp.core-sdi.com/pub/patch/ssh1-keyrecovery.patch shortly. - An interesting observation is how several people failed to see the wrongness of the multiple patches, starting with the person that produced it, me (ouch!, my bad) failing to spot 2 different problems in it, guys at the Bindview RAZOR Team and even Andrew Brown who pointed out that the patch was no good but for the wrong reasons. To me this had two outcomes: . shame (i should have found the problems!) . a reaffirmation of my belief that peer review and full disclosure are good things. - Note also that the path taken by other SSH vendor to address this problem is different. For example, OpenSSH and others chose to completly close the information leakage by setting a random session key when RSA operations fail and by regenerating the key after a given number of connections to the SSH server. -ivan This applies to the source distribution of ssh-1.2.31 decompress and untar the ssh-1.2.31 $ cd ssh-1.2.31 $ patch -p0 < ssh1-keyrecovery.patch $ ./configure $ make ----------------------------------- begin ssh1-keyrecovery.patch ------- --- rsaglue.c Wed Jan 17 11:42:52 2001 +++ rsaglue.c Tue Feb 13 16:05:33 2001 @@ -264,8 +264,10 @@ mpz_clear(&aux); if (value[0] != 0 || value[1] != 2) + { + kill(getppid(),SIGALRM); fatal("Bad result from rsa_private_decrypt"); - + } for (i = 2; i < len && value[i]; i++) ; --- sshd.c Wed Jan 17 11:42:53 2001 +++ sshd.c Tue Feb 13 16:05:15 2001 @@ -757,9 +757,11 @@ RETSIGTYPE key_regeneration_alarm(int sig) { + static time_t last_keygen_time=0; /* Check if we should generate a new key. */ - if (key_used) - { + if (key_used && (time(NULL) - last_keygen_time > 60)) + { + last_keygen_time = time(NULL); /* This should really be done in the background. */ log_msg("Generating new %d bit RSA key.", options.server_key_bits); random_acquire_light_environmental_noise(&sensitive_data.random_state); ----------------------------------- end ssh1-keyrecovery.patch ------- --- "Understanding. A cerebral secretion that enables one having it to know a house from a horse by the roof on the house, Its nature and laws have been exhaustively expounded by Locke, who rode a house, and Kant, who lived in a horse." - Ambrose Bierce ==================[ CORE Seguridad de la Informacion S.A. ]========= Iván Arce Presidente PGP Fingerprint: C7A8 ED85 8D7B 9ADC 6836 B25D 207B E78E 2AD1 F65A email : iarce () core-sdi com http://www.core-sdi.com Florida 141 2do cuerpo Piso 7 C1005AAG Buenos Aires, Argentina. Tel/Fax : +(54-11) 4331-5402 ===================================================================== --- For a personal reply use iarce () core-sdi com
Current thread:
- SSH1 key recovery patch Iván Arce (Feb 13)
- Re: SSH1 key recovery patch Andrew Brown (Feb 15)
- Re: SSH1 key recovery patch Pavel Machek (Feb 19)
- Re: SSH1 key recovery patch Johannes Geiger (Feb 20)
- Re: SSH1 key recovery patch Johannes Geiger (Feb 21)
- Re: SSH1 key recovery patch Markus Friedl (Feb 21)
- Message not available
- Re: SSH1 key recovery patch Markus Friedl (Feb 22)