|
Home : Advisories : Vulnerabilities in KTH Kerberos IV
Title: |
Vulnerabilities in KTH Kerberos IV |
Released by: |
Jouko Pynnönen |
Date: |
9th December 2000 |
Printable version: |
Click here |
OVERVIEW
Kerberos is a network authentication protocol which by using
secret-key cryptography provides authentication over insecure networks.
There are at least two common free Kerberos implementations:
MIT and KTH (Royal Institute of Techology, Sweden). The latter is
included in OpenBSD and FreeBSD.
The KTH Kerberos IV implementation (http://www.pdc.kth.se/kth-krb/)
contains the following vulnerabilities:
1) Honoring certain environment variables
2) Buffer overflow in protocol parsing code
3) File system race when writing ticket files
The vulnerabilities may lead to local and remote root compromise if
the system supports Kerberos authentication and uses the KTH
implementation (as is the case with e.g. OpenBSD per default). The
system needn't be specifically configured to use Kerberos for all of
the issues to be exploitable; some of the vulnerabilities are
exploitable even if Kerberos is disabled by commenting out the realm
name in the "krb.conf" file.
It should be noted that the MIT implementation of Kerberos is
probably NOT vulnerable for most of the problems discussed here;
however a quick glance at the MIT code reveals that the krb4
compatibility code of krb5 seems to honor "KRB_CONF" and "KRB_REALMS"
while running setuid (the package inspected was krb5-1.1.1-9.src.rpm on
a Red Hat Linux system, vulnerability wasn't further tested). The telnetd
versions used on most Linux systems don't pass the mentioned environment
variables to the login process.
DETAILS
1) Honoring certain environment variables
The variable "krb4_proxy" is used regardless of setuidness of the
process. A local user may set the variable to intercept the
authentication requests with their own proxy and generate false
replies. In conjunction with the buffer overflow (see below) this could
lead to root compromise. The variable is used when an authentication
request is being sent, thus to be exploitable with this environment
variable the system must be configured to use Kerberos.
The "krb4_proxy" variable can be imported through a telnet session to
fool the login process to proxy its authentication requests in the same
way. This is possible without having a local account on the system.
However it's unclear at this point (for me at least) whether exploiting
this without the buffer overflow is possible; the password check itself
can be bypassed, but the login program does an additional check to find
out if it's talking with a bogus server. The encryption key used for
this is contained in the local srvtab file. If this key can be
retrieved by the bogus proxy, or the verification request can be
validly proxied to the original server as normally, then it would be
possible to exploit this without the buffer overflow.
The environment variable "KRBCONFDIR" is used if the process isn't
running setuid. The variable can be brought in via a telnet session to
redefine the directory containing Kerberos configuration files. A
local user, or a remote user who is able to upload files on the system,
can supply their own configuration files (krb.conf, krb.extra,
krb.realms, srvtab) to be used by the login program, which at the
moment of authentication has both effective and real user id equal to
zero. It is thus possible to define an arbitrary Kerberos server which
may then tell the login program to accept the authentication. For this
issue to be exploitable, the system needn't be configured to use
Kerberos, or Kerberos may be disabled in the original configuration
file /etc/kerberosIV/krb.conf.
This scenario was successfully tested on an OpenBSD-2.7 system and a
Linux system with the latest kth-krb4 package compiled (no Linux
distributions as far as I know use the KTH Kerberos implementation).
Logins with any user with a valid shell defined were accepted when
using a password coded in the bogus server code. To get root access, a
login name such as nobody.root can be issued, as plain root logins
aren't usually accepted.
2) Buffer overflow in protocol parsing code
There is at least one easily producable buffer overflow in the Kerberos
library. When parsing an authentication reply from a Kerberos server
a memcpy() call without bound checking is done. This happens in
function kdc_reply_cipher(), end of file lib/krb/kdc_reply.c:
p += krb_get_int(p, &clen, 2, little_endian);
cip->length = clen;
memcpy(cip->dat, p, clen);
p += clen;
The code reads a 16-byte length value from the packet and without
further checking copies the amount of bytes to a fixed-sized buffer.
This causes a segmentation fault, but has turned out to be
not-so-trivial to exploit; writing over return address happens, but
setting the address isn't necessarily easy because there's a limit for
the maximal length of a reply that is read from the server
(MAX_KTXT_LEN, 1250 bytes). The length parameter itself contained by
the packet can be set to any value between 0 and 65535.
3) File system races
The Kerberos system stores ticket files in /tmp. When a privileged
process writes such a file, there exists a race condition which can be
used to overwrite arbitrary files with the ticket data. The ticket file
name is predictable and a user may create a symbolic link having the
same name. This was tested on an OpenBSD system.
SOLUTION
OS vendors were notified 11/28 via a mailing list, and KTH Kerberos
team 12/01.
OpenBSD has published information about the vulnerabilities at
http://www.openbsd.org/security.html
and a patch for the problem at
http://ftp.openbsd.org/pub/OpenBSD/patches/2.8/common/006_kerberos.patch
A patch fixing the buffer overflow problem by from Assar Westerlund
:
diff -u -w -u -w -r1.13 kdc_reply.c
--- kdc_reply.c 2000/05/15 00:15:26 1.13
+++ kdc_reply.c 2000/12/04 14:23:30
@@ -124,6 +124,9 @@
p += krb_get_int(p, &exp_date, 4, little_endian);
p++; /* master key version number */
p += krb_get_int(p, &clen, 2, little_endian);
+ if (reply->length - (p - reply->dat) < clen)
+ return INTK_PROT;
+
cip->length = clen;
memcpy(cip->dat, p, clen);
p += clen;
To check whether your login process is linked against the Kerberos
library issue the command
ldd /usr/bin/login
If "libkrb" is included in the library listing, then the program is
likely to have Kerberos code compiled in. In this case you should
consider recompiling it and possibly Kerberos-aware "su" or
"ksu", "rlogin", and "rsh" without Kerberos support, or upgrading
them.
To test if your telnetd filters out the dangerous environment variables,
you can do this:
$ telnet
telnet> environ define KRBCONFDIR /tmp
telnet> environ export KRBCONFDIR
telnet> environ define krb4_proxy http://your.host:80
telnet> environ export krb4_proxy
telnet> open localhost
Then you can login with your username and password. If you now issue
the command
$ env | grep -i \^krb
you will see the currently defined environment variables concerning
Kerberos. If you get no output you are safe; if you see KRBCONFDIR or
krb4_proxy listed, then the telnetd of your system lets the Kerberos
environment variables through (assuming your login scripts don't set
them).
You can check with file timestamps if arbitrary Kerberos configuration
files get read (in the above example, ls -lu /tmp/krb.conf shows the
time the file was last read, assuming you've created it first). For the
krb4_proxy exploitableness you can use "nc -l -p " or another
program to listen on a port and then check if the login program
connects to it while logging in with krb4_proxy defined to
http://your.host:.
CREDITS & ACKNOWLEDGEMENTS
Vulnerabilities discovered by: Jouko Pynnonen
Thanks to: Assar Westerlund + kth-krb team,
Hobbiton.org, Theo de Raadt
Greets to: Esa Etelavuori, cc-opers@IRCNet
--
Jouko Pynnonen Online Solutions Ltd Secure your Linux -
jouko@solutions.fi http://www.secmod.com
|