**********************************************
+ Wais.pl parameter passing security problem +
**********************************************
# Another fine advisory by Scrippie #
|============================================|
* Cheers to: zsh, Synnergy, phreak.nl *
| Lots of Love to: Maja, Hester |
##############################################
---[ The CGI ]---
The wais.pl CGI written by Tony Sanders provides means to
access the waisq WAIS client via the webserver.
---[ The Source ]---
First of all I will show you a bit of offending code in wais.pl:
open(WAISQ, "-|") || exec ($waisq, "-c", $waisd,
"-f", "-", "-S", "$src.src", "-g", @query);
Since WAISQ is opened like this, silly stuff like shell characters will not
work, we can, however, write extra command line parameters to waisq in our
query array. This can be done because the information we provide the CGI is
passed to exec($waisq) as an array, which perl expands to command line
parameters to the called program. If a scalar would have been used, this
wouldn't be the case.
It seems that waisq allows us to specify a file that contains a WAIS question
by using the -f parameter. One of the strange things is that waisq seems to
do the following:
if(dosearch == TRUE) {
SearchWais(question);
if((qfilename == NULL) || (strcmp(qfilename, "-") == 0))
WriteQuestionfp(stdout, question);
else
WriteQuestion(qfilename, question);
So, waisq does not only read it's question from the file, but will also write
the question to the same file, effectively ruining any older contents.
Back to the perl source:
@query contains our optional search keywords, which we can fill in ourselves.
This means we can write a bunch of mess and our own string to any file owned
by the uid the webserver runs CGI scripts with (the file must exist).
---[ They call me the Wild Rose ]---
Suppose we do something like:
echo "Thanks for all the fish" > test.htm
cat test.htm
-> Thanks for all the fish
wais.pl -f test.htm "Elisa Day"
cat test.htm
We'll get the following:
(:question
:version 2
:seed-words "Elisa Day "
:relevant-documents
( )
:sourcepath "/root/wais-sources/:./"
:sources
( (:source-id
:filename "www.src"
)
)
:maximum-results 40
:result-documents
( )
Not good eh?
HTML tags are as easily submitted in this manner as regular text is.
We could do something like:
wais.pl -f t.html -g `printf "

Test

Will redirect us immediatly to our favourite clan of the goat site.
Ah, this seems somewhat better, if we know the absolute path of index.html we
could deface the server without ever being on the box...
---[ It's getting better (all the time)]---
Well, the previously described problem doesn't seem to scary, since most files
aren't writeable by user nobody and the nasty header is in the way and any
webmaster chowning his pages to "nobody" should have his head examined.
More interesting is the fact that the waisq client contains a buffer overflow
in the following piece of code:
Boolean ReadSourceFile(asource, filename, directory)
Source asource;
char *filename, *directory;
{
FILE *fp;
char pathname[MAX_FILENAME_LEN+1];
Boolean result;
strncpy(pathname, directory, MAX_FILENAME_LEN);
strncat(pathname, filename, MAX_FILENAME_LEN);
Both "directory" and "filename" is input provided by the user to waisq by
the command line parameters "-s" and "-t". MAX_FILENAME_LEN is defined as
255 bytes in "cutil.h". We can clearly see that our target buffer can be
overflown by 254 bytes.
For the remote overflow I choose to combine the injection vector and the
payload (a bad choice as it turned out, but it worked), they are delicatly
intertwined in the exploit. The first buffer is used as the "NOP sled" buffer
while the second one contains the payload (which may not contain a lot of
metacharacters, I used smegma_v0.5 - written by me - to get rid of them). We
can also see that 4 bytes of our buffer get ruined, because somewhat later in
the code the FILE* fp is filled in - I joined the two buffer together by
jumping a few bytes forward at the end of "pathname" using 0xeb 0x08 and some
NOPS (it can also be done using 0xeb 0x04, but I used a few NOPS to provide
some more "space" for this little trick).
The final exploit is included at the end of this article.
---[ The patches ]---
I included the patches for completeness sake, they are so trivial anyone will
probably hand-code them before reverting to use these.
The patch for waisq
===================
--- source.old.c Sun Aug 13 23:41:40 2000
+++ source.c Sun Aug 13 23:41:57 2000
@@ -328,7 +328,7 @@
char *filename, *directory;
{
FILE *fp;
- char pathname[MAX_FILENAME_LEN+1];
+ char pathname[MAX_FILENAME_LEN*2+1];
Boolean result;
strncpy(pathname, directory, MAX_FILENAME_LEN);
The patch for wais.pl
=====================
--- wais.old.pl Sun Aug 13 23:46:51 2000
+++ wais.pl Sun Aug 13 23:47:21 2000
@@ -37,7 +37,7 @@
print "Content-type: text/html\n\n";
open(WAISQ, "-|") || exec ($waisq, "-c", $waisd,
- "-f", "-", "-S", "$src.src", "-g", @query);
+ "-f", "-", "-S", "$src.src", "-g", $pquery);
print "\nSearch of ", $title, "\n\n";
print "\n