lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Mon, 11 Jun 2007 18:52:11 -0400
From: Ken Raeburn <raeburn@....EDU>
To: bugtraq@...urityfocus.com
Subject: Re: Sudo: local root compromise with krb5 enabled

Thor Lancelot Simon writes:
> Widely distributed software using Kerberos for password authentication
> (e.g. the original Merit RADIUS server code, as I disclosed in the mid
> 1990s) has had a long and ugly history of failing to perform the  
> second
> step, usually because its authors didn't understand that it was  
> necessary.

Yes, this is the standard KDC spoofing attack, known since I think  
the early 90s at least, maybe late 80s.

> But sudo has a curious bug: it *tries* to do the second step,
> but if that step fails because no local service keys are known, it  
> lets
> the user become root anyway, because the (potentially fake)  
> Kerberos server
> said so.  For example, on a host without a "keytab" file:

In some MIT applications there was a conscious choice to that  
effect.  The MIT library's interface for verifying credentials has a  
flag that can be set to indicate whether it should return success or  
failure for this specific case.  (Though personally, I think the  
default should be the more paranoid one, it would be an incompatible  
break from previous versions.)

> Needless to say, this should be fixed.  Simply adding local keytabs
> with service keys for every host that has a kerberos-enabled sudo
> looks, from a cursory inspection of the code in auth/kerb5.c in the
> latest sudo distribution (1.6.8pl12) like it will suffice: the other
> errors appear to be correctly handled.  But woe betide any system
> administrator who accidentally puts a Kerberos-enabled sudo on a host
> that's configured as a Kerberos client only!

There is the argument that you should have keytabs on any host with  
resources you want to protect, and conversely, if there's no keytab,  
it doesn't matter if you grant root access.  For some environments,  
that's actually reasonably accurate, but not all environments by any  
means.

On a system without a keytab, Kerberos by itself -- any  
implementation -- cannot verify much of anything at all.

> Actually, if you link sudo to MIT krb5 (rather than Heimdal) it's  
> worse
> than that, I think: users can override the system keytab setting and
> cause sudo to *think* there's no keytab when there actually is one,  
> and
> then have it ask their fake Kerberos servers, and make them root.

Only because the sudo code is buggy.

> The MIT library provides several different flavors of  
> krb5_init_context

I count two, unless you're looking at internal functions.

> and only one of them (krb5_init_secure_context()) actually sets the
> profile_secure flag.  But sudo uses the standard krb5_init_context()
> which does *not* set profile_secure

Like I said, sudo has a bug.  Any program or module that needs the  
Kerberos code to not trust the environment must use  
krb5_init_secure_context, or clean out the environment.  You wouldn't  
call execvp (or system without an absolute path) from a privileged  
part of a setuid program with $PATH supplied by the untrusted user,  
would you?

> and also doesn't call the obsolete
> (and, I think, never documented) old krb5_secure_config_files()  
> function,
> which is the only other thing in the MIT library that would set
> profile_secure and avoid this root compromise.

That was the original way of dealing with this, until I pointed out  
back around 1999 that krb5_init_context used $KRB5_CONFIG to read the  
config file, and even reading some files that might be root-only  
could have bad effects, like device files (rewind a tape drive while  
the sysadmin is in between writing dump files to the current tape),  
or in subtler cases, expose information only root should be privy  
to.  (For example, does file X exist in that directory that I can't  
read?  A missing config file produces different results from a file  
found but not in krb5.conf format.)  So by the time you could call  
krb5_secure_config_files, you might have already lost.

The function still exists, and will set the "secure" flag, and throw  
away the original config data and re-read just the files at compiled- 
in pathnames, but now it also returns an error code saying it's  
obsolete.

> So the hole is worse than I thought.  It is probably simplest and best
> to remove the current krb5 password validating code from sudo, and
> use Heimdal's krb5_verify_user() instead, and make sudo thus no longer
> work with MIT krb5, which is a terrible security accident just waiting
> to happen.

You might consider talking with the MIT Kerberos team about the issue.

> Evidently modern MIT krb5 has krb5_verify_user too and though it pokes
> around in the library internals it doesn't set profile_secure in the
> context.

Not in my source tree it doesn't.  Maybe you're looking at  
krb5_verify_init_creds?

As I described above, at this point in the process, if you've created  
a normal context in a setuid process, you may have already had some  
exposure.  Indeed, in future versions it's possible that creating a  
normal context and calling get_init_creds could potentially load some  
plugin modules indicated by the user's config file.  Calling  
verify_init_creds after that and expecting the user to be unable to  
subvert it is pointless.

It might be a useful enhancement to have krb5_init_context create a  
"secure" context when invoked with uid!=euid (and likewise check for  
setgid, oh and check saved set-user-ID too).  But I think it would be  
sloppy to rely on that for security.

>   For that, with MIT krb5, one has to call krb5_init_context_secure()
> instead of the standard krb5_init_context().

Right.  We do want to be able to run servers in secure environments  
with information passed in through environment variables.  Since  
setuid programs are much more the exception than the rule, our  
defaults are oriented towards programs running in environments that  
can be trusted, and krb5_init_secure_context is for handling the  
other cases.  (Not just programs when running with different real and  
effective uids, but any such programs that have since set both ids  
the same, or programs spawned from such processes without purging the  
environment, etc.)

> the initial patch
> to sudo I posted won't protect against it (since one can override  
> the keytab
> and krb5.conf locations and just force a bogus keytab to be checked  
> against
> a bogus server).

You should just make it call krb5_init_secure_context.

People concerned about proper use of Kerberos in applications are  
welcome to send mail to the kerberos@....edu list for discussion;  
we'd be glad to help, and there are a lot of people besides the MIT  
team on the list.

Ken

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ