COMMAND

    Kerberos

SYSTEMS AFFECTED

    KTH Kerberos IV

PROBLEM

    Jouko  Pynnonen   found  following.    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.

    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 us 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

    OpenBSD has published information about the vulnerabilities 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 <port>"  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:<port>.

    The problem  was fixed  in NetBSD-current  on 2000/12/09;  systems
    running  NetBSD-current  dated  from  before  that  date should be
    upgraded to  NetBSD-current dated  2000/12/09 or  later.   The 1.5
    branch was  fixed by  2000/12/15.   Systems running  1.4.x are not
    vulnerable to this problem as they do not contain this version  of
    kerberos.  Systems running 1.5 should apply the patch found in:

        ftp://ftp.NetBSD.ORG/pub/NetBSD/misc/security/patches/20001220-krb

    and  then  rebuild  and  reinstall  both  the "libkrb" library and
    telnetd.   Systems  running   NetBSD-current  dated  from   before
    2000/12/09 should be  upgraded to NetBSD-current  dated 2000/12/09
    or later.

    KTH-KRB Kerberos  Release 1.0.4  is now  available with  bug-fixes
    (including one exploitable buffer overrun):

        http://www.pdc.kth.se/kth-krb
        ftp://ftp.pdc.kth.se/pub/krb/src/

    For FreeBSD upgrade your  vulnerable FreeBSD system to  4.2-STABLE
    or 3.5-STABLE  after the  respective correction  dates.  Otherwise
    apply the  relevant patch  from below  and recompile  the affected
    files:

        ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-01:25/telnetd-krb.4.2.patch
        ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-01:25/telnetd-krb.4.2.patch.asc
        ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-01:25/telnetd-krb.3.5.1.patch
        ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-01:25/telnetd-krb.3.5.1.patch.asc