[ SOURCE: http://www.secureroot.com/security/advisories/9768317143.html ] 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 ftp://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