Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Mar 2001 12:55:32 -0500
From:      James Snow <snow@teardrop.org>
To:        Kris Kennaway <kris@obsecurity.org>
Cc:        Brooks Davis <brooks@one-eyed-alien.net>, Alex Popa <razor@ldc.ro>, security@FreeBSD.ORG
Subject:   Re: 4.3-BETA, sshd.core found in root directory.
Message-ID:  <20010316125532.A65814@teardrop.org>
In-Reply-To: <20010312152215.A94640@mollari.cthul.hu>; from kris@obsecurity.org on Mon, Mar 12, 2001 at 03:22:15PM -0800
References:  <20010313004813.A78221@ldc.ro> <20010312145754.A489@Odin.AC.HMC.Edu> <20010312152215.A94640@mollari.cthul.hu>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Mar 12, 2001 at 03:22:15PM -0800, Kris Kennaway wrote:
> On Mon, Mar 12, 2001 at 02:57:54PM -0800, Brooks Davis wrote:
> > On Tue, Mar 13, 2001 at 12:48:13AM +0200, Alex Popa wrote:
> > > I am not really sure what this means (could mean a lot of things, 
> > > including bad memory on my machine), but here are the facts:
> > 
> > This reminds me of something I noticed during the last discussion of
> > ssh I got involved in and compleatly forgot about.  If you create an
> > account with a bad shell (say, /bin/false) and run the following command
> > you get an immediate sshd core dump:
> > 
> > ssh -t xxx@localhost /bin/sh
> > 
> > Attempting to run gdb on the core appears to show that I'm in:
> > 
> > #0  0x4817c3b7 in login_getpwclass () from /usr/lib/libutil.so.3
> > 
> > but the binary is stripped so I don't know and my /usr/obj is out of
> > sync with my world at the moment so I figure running gdb against the
> > unstripped binary is not productive.
> 
> There's a PR open about this and Brian is looking into it -
> indications are it's a simple bug and not a security problem, denial
> of service or otherwise.

I don't know whether or not it's exploitable, but I just ran up against
this myself today. You can reproduce it by using ssh version 2 and giving 
sshd an invalid username.

The problematic code is in src/crypto/openssh/auth2.c in 
input_userauth_request:

    208                 pw = getpwnam(user);
    209                 if (pw && allowed_user(pw) && strcmp(service, 
                            "ssh-connection")==0) {
    210                         authctxt->pw = pwcopy(pw);
    211                         authctxt->valid = 1;
    212                         debug2("input_userauth_request: setting up 
                                        authctxt for %s", user);
    213 #ifdef USE_PAM
    214                         start_pam(pw);
    215 #endif
    216                 } else {
    217                         log("input_userauth_request: illegal user %s", 
                                     user);
    218                 }

If you supply an invalid username, this line:

    208                 pw = getpwnam(user);

will set pw to null.

The if statement at line 209:

    209                 if (pw && ...

will fail immediately because pw is null, and the code skips to:

    216                 } else {
    217                         log("input_userauth_request: ...
    218                 }

Things fall down and go boom here:

    231         if (authctxt->pw != NULL) {
    232                 lc = login_getpwclass(authctxt->pw);

authctxt->pw never gets set to anything unless you enter the if, which
we don't because of the pw pointer being null. So it points off into
space, and login_getpwclass will cause a SIGSEGV when it tries to
deference it.

My fix for this was to stick a 'authctxt->pw = NULL;' in the else block:

    216                 } else {
    217                         log("input_userauth_request: ...
    218                         authctxt->pw = NULL;
    219                 }

Then you get this:

	input_userauth_request: illegal user nonexistant
	Failed password for NOUSER from 198.76.121.128 port 3150 ssh2

instead of this:

	input_userauth_request: illegal user nonexistant
	Segmentation fault (core dumped)

I don't think this fix is ideal, as I think the log entry should
continue to show the username the client tried to login with and not
'NOUSER,' but it will certainly close the hole, if indeed it is one. At
least I'll sleep better tonight.

I wasn't able to reproduce this under Linux and it doesn't occur using
ssh1. 

Also, is anyone going to fix the pipe bug in sshd that causes all those
annoying "Broken pipe" errors? I know there's a patch out there for it.


-Snow

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010316125532.A65814>