COMMAND

    bootpd, CMU dhcpd

SYSTEMS AFFECTED

    Linux & BSD

PROBLEM

    John  McDonald  found  following.   He  discovered a remote buffer
    overflow in the bootpd daemon that is distributed with most  linux
    and  bsds.    However,   due  to   the  characteristics   of   the
    vulnerability, a good  portion of the  operating systems with  the
    bug  are  probably  not  vulnerable  to  a  remote  code execution
    situation.   In that  situation, bootpd  is still  vulnerable to a
    remote crash, which may or may not have an impact.   Specifically,
    John has been able to write a working remote exploit for  OpenBSD,
    and a  friend of  mine has  created a  working BSDI  exploit.   No
    attemption to  determine if  Solaris, Irix,  Digital Unix,  or any
    other OS's are vulnerable.  The vulnerability is in bootpd.c:

    ...
		    hlen = haddrlength(bp->bp_htype);
		    if (hlen != bp->bp_hlen) {
			   report(LOG_NOTICE, "bad addr len from %s address %s",
				       netname(bp->bp_htype),
				       haddrtoa(bp->bp_chaddr, hlen));
		    }
		    dummyhost.htype = bp->bp_htype;
		    bcopy(bp->bp_chaddr, dummyhost.haddr, hlen);
		    hashcode = hash_HashFunction(bp->bp_chaddr, hlen);
    ...

    bp_htype is an  unsigned character value  taken out of  the packet
    that was  sent. You  can see  here that  the bcopy  will copy hlen
    bytes out of the  packet onto a structure  on the stack.   hlen is
    what  haddrlength  returns,  given  our  htype  from  the  packet.
    haddrlength is a macro:

	...
	#define haddrlength(type)       ((hwinfolist[(int) (type)]).hlen)
	...

    hwinfolist  is  a  table  that  matches  up  types to a length and
    description.  It  is a predefined  array of about  10 instances of
    this struct:

	struct hwinfo {
	    unsigned int hlen;
	    char *name;
	};

    The problem is that we can specify a htype that is past the end of
    the hwinfolist table. Thus, we can address the memory that resides
    after this  structure, potentially  finding a  value that  will be
    appropriately aligned to give us  a sufficient amount of bytes  to
    overwrite  the  stack.   There  is  another potential problem with
    exploitation: if the  bp_hlen field in  the packet does  not equal
    the hlen returned from the macro, then it prints a warning.   When
    it  prints  this  warning,  it  dereferences  the  pointer  to the
    description given  in the  hwinfolist table.   We can  control the
    bp_hlen field,  but it  is only  an unsigned  character, so if the
    value we pick in memory for the number of bytes to copy is greater
    than 255, then the next value in memory has to be a valid pointer.
    Exploitation  is  aided  by  the  fact  that you can jump into the
    buffer read into  the data segment  from the socket,  thus placing
    few limitations on the size  and contents of your shell  code, and
    potentially bypassing stack patches.

    Unpatched  CMU  dhcpd  3.3.7  (which  traces  its roots to the old
    bootpd) was also vulnerable.

SOLUTION

    OpenBSD released patches  to fix this  problem on Nov.  28th 1998.
    These patches should be  appropriate for other versions,  and they
    are available at

	ftp://ftp.openbsd.org/pub/OpenBSD/patches/2.4/common/bootpd.patch

    FreeBSD and the Linux distributions checked (slackware and debian)
    were not vulnerable to remote code execution.

    Princeton  patch  6  (the  most  recent patch, released July 1998)
    fixed dhcpd bug:

	http://www.princeton.edu/~irwin/dhcpd.html.