COMMAND

    Kerberos

SYSTEMS AFFECTED

    System running Kerberos4

PROBLEM

    This text is part  of L0pht security advisory.   The tool used  to
    present  this   vulnerabilities  is   available  as   a  uuencoded
    compressed tar file off of the URL

        http://www.l0pht.com/advisories.html

    under the Kerb4 advisory.

    Remote users can dictionary  crack kerberos user accounts  without
    needing to know the username  or kerberos realm name. It  has long
    been  known   that  Kerberos   4  Ticket   Granting  Tickets   are
    susceptible  to  dictionary  attacks  as  they  contain a constant
    string that  can be  used for  compares (the  string happens to be
    "krbtgt").  Thus it has always been possible to; query a  Kerberos
    server,  hand  in  a  valid  principle  (user and kerberos realm),
    recieve a  Ticket Granting  Ticket, decrypt  the DES  ticket using
    dictionary words  for the  key, if  the phrase  "krbtgt" exists in
    the decrypted packet you have  the correct key. This exact  attack
    has been going on for some time in certain circles. In  particular
    it seems to work quite  well on dialup servers using  kerberos for
    password authentication.

    The results usually end up looking more or less like this:

	---
	users file:
	---
	johndoe
	markg
	sally

	---
	pass file:
	---
	love
	sex
	secret

	% ./k4 -S -h kerb.server.com -r REALM -u users -f pass
	Username: sally
	Realm: THEK4REALM
	Password: love
	--------


    The problem  with the  above is  the need  for a  userlist and the
    kerberos realm name in order to  mount the attack. If the site  is
    running kerberos  it might  be that  they have  a clue  and are at
    least  slightly   security  conscious   so  there   is  a   strong
    possibility that they have services like finger and rusers  turned
    off to the outside world.   You could sniff incoming and  outgoing
    e-mail  for  usernames  or  do  a  little  social  engineering but
    lo-and-behold there's a much easier way. And guess what -- due  to
    the herculean  effort that  is required  to setup  Kerberos people
    want to get the most mileage out  of it once it is in place.  This
    includes leaving it  open through filters  and firewalls to  allow
    outside  users  to  authenticate  and  come  in.  Naughty  Naughty
    Naughty!

    The new Bug:

    It  turns  out  that  upon  receiving  a  malformed UDP packet the
    kerberos4 server returns a  packet containing an error  string and
    the principle  from some  un-sanitized data  structures. A perfect
    example  is  a  udp  packet  containing  a null. Since you are not
    handing in  as much  data as  it is  expecting the  pointer to the
    re-used structure references the un-purged principle  information.
    This  un-sanitized  data  contains  the  name  of the last user to
    request a TGT and the kerberos Realm name.  Needless to say,  this
    is all the  information you need  to then request  a tgt for  that
    user and dictionary attack the  response. Welcome to the world  of
    'buffer underflows'.

    What our  program does  is builds  up a  linked list of principle
    structures.   It  repeatedly  queries  the  Kerberos  server  and
    updates the list each time a  new user has gone through. It  then
    constructs  a  valid  TGT  request  for  the last user it saw and
    requests their TGT, proceeding to crack upon it.

    A sample run utilizing this information leak follows:

	% ./k4 -D -h kerb.server.com -f pass
	bboy:THEK4REALM:BF7ECF2A2AC21DBAEC1827C28BA828372FD951
	..........
	sally:THEK4REALM:AACEF2372192762768797987FE821AC1825387
	-----
	Username: sally
	Realm: REALM
	Password: love
	-----

	....recieved interrupt... dumping linked list...
	Record number 1
	Username: bjoy
	realm: REALM
	passwd:
	tgt: BF7ECF2A2AC21DBAEC1827C28BA828372FD951
	Record number 2
	Username: sally
	realm: REALM
	Passwd: love
	tgt: AACEF2372192762768797987FE821AC1825387

    A sample that everyone can do:

	nc -v -u kerberos.server.com 750
	kerberos.server.com [xxx.xxx.xxx.xxx] 750 (?) open

	[type a c/r]

	jdoeTHEK4REALM2=D2
	Kerberos error -- KRB prot version mismatch: KRB 3D4 request 3D 10 punt!

    Guess what... jdoe was the last person through here and the realm
    is THEK4REALM - you can now use this information to form a TGT
    request and away you go...

SOLUTION

    This data leak does not exist in kerberos5 nor does it seem to  be
    in kerb5 running in  kerb4 compatibility mode. Unfortunately  many
    sites  still  use  kerb4  due  to  their  legacy  systems  and the
    incompatibillity between the two versions. OpenBSD is the only  OS
    distribution that  I am  aware of  that already  has this  problem
    fixed.   On  23th  December  Kerberos  V  v1.0  has been released.

    Mark Eichin also made some workarounds.

    ==================================================================
    RCS file: kerberos/src/server/ChangeLog,v retrieving revision 1.21
        diff -u -r1.21 ChangeLog
        --- ChangeLog   1996/02/11 01:05:41     1.21
        +++ ChangeLog   1996/11/25 22:07:41
        @@ -1,3 +1,9 @@
        +Mon Nov 25 17:05:32 1996  Mark Eichin  <eichin@cygnus.com>
        +
        +       * kerberos.c (kerberos): clear req_name_ptr,  req_inst_ptr,
        +       req_realm_ptr, req_time_ws to avoid leaking data  through
        +       kerb_err_reply.
        +
         Sat Feb 10 20:03:19 1996  Mark Eichin  <eichin@cygnus.com>

                * kerberos.c (main): initialize des-based random key generator
    ==================================================================
    RCS file: kerberos/src/server/kerberos.c,v
    retrieving revision 1.40
        diff -u -r1.40 kerberos.c
        --- kerberos.c  1996/02/11 01:05:42     1.40
        +++ kerberos.c  1996/11/25 22:07:41
        @@ -386,6 +386,9 @@
             unsigned char   *ptr;      /* must be unsigned for 	 timestamp fetch */

        +    /* clear per-packet statics */
        +    req_name_ptr = req_inst_ptr = req_realm_ptr = "";
        +    req_time_ws = 0;

             ciph->length = 0;