Clang – S3lab http://s3lab.deusto.es S3lab Security Blog Wed, 06 May 2020 12:51:35 +0000 es hourly 1 https://wordpress.org/?v=5.1.5 Hardening de binarios (V) – UBSan http://s3lab.deusto.es/hardening-binarios-5/ Sat, 10 Dec 2016 12:21:42 +0000 http://s3lab.deusto.es/?p=8691 El comportamiento indefinido en C/C++ es causado cuando no existen restricciones en el comportamiento del programa; es decir, cuando el estándar no especifica qué debe hacer la implementación, esta es libre de hacer lo que le parezca. En los tiempos

The post Hardening de binarios (V) – UBSan appeared first on S3lab.

]]>
El comportamiento indefinido en C/C++ es causado cuando no existen restricciones en el comportamiento del programa; es decir, cuando el estándar no especifica qué debe hacer la implementación, esta es libre de hacer lo que le parezca. En los tiempos de Usenet, el grupo comp.std.c acuñó el término nasal demons para referirse al comportamiento indefinido de C, ya que “When the compiler encounters [a given undefined construct] it is legal for it to make demons fly out of your nose”.

Ejemplos típicos de nasal demons en C/C++ son la división por cero, el uso de una variable no inicializada, desreferenciar un puntero a NULL etc, algunos de estos casos ya están corregidos, pero aún es posible compilar programas con comportamiento no definido. Por ejemplo, dado el siguiente programa:


int function() { }
int main(){
int array[1];
array[-1] = 1;
int b;
if (b)
printf("lucky!\n");
printf(“%f\n”, 1.01 / 0.00);
int ret = function();
return 0;}

¿Qué hará el compilador cuando tratemos de asignar 1 a array[-1] ?
¿Tendremos suerte?
¿Qué pasa cuando dividimos por cero, en enteros, floats y doubles?
¿Qué retorna function?

Para detectar este tipo de errores podemos usar UBSan (Undefined Behavior Sanitizer), el detector de comportamiento indefinido en tiempo de ejecución para GCC y Clang. UBSan instrumenta el programa para detectar de forma general el comportamiento indefinido con -fsanitize=undefined, o se pueden instrumentar opciones específicas, como -fsanitize=return para comprobar que no se llegue al final de una función no void sin retornar un valor, -fsanitize=null para asegurar que no de-referenciamos un puntero a NULL, -fsanitize=vprt para que las conversiones entre clases base y derivadas tengan el tipo correcto…

Las vulnerabilidades por comportamiento indefinido en C/C++ están a la orden del día, siendo las más comunes el bad casting y el use-after-free, que afectan gravemente a navegadores, servidores web etc. Además de UBSan, DANGNULL, CaVer y TypeSan son algunos checkers de esta clase de errores.

¿Es esto suficiente? Lo descubriremos en los siguientes posts.

The post Hardening de binarios (V) – UBSan appeared first on S3lab.

]]>
Hardening de binarios (III) – ASan http://s3lab.deusto.es/hardening-binarios-3/ Sat, 17 Sep 2016 14:08:41 +0000 http://s3lab.deusto.es/?p=8430 En entregas anteriores hemos hablado de opciones de GCC que hacen nuestros ejecutables más seguros, en esta entrega en cambio, presentamos opciones de compilación que generan informes, avisando de errores en el código. AddressSanitizer (ASan) es una opción para Clang

The post Hardening de binarios (III) – ASan appeared first on S3lab.

]]>
En entregas anteriores hemos hablado de opciones de GCC que hacen nuestros ejecutables más seguros, en esta entrega en cambio, presentamos opciones de compilación que generan informes, avisando de errores en el código.

AddressSanitizer (ASan) es una opción para Clang (>=3.1) y GCC (>=4.8) que detecta errores de corrupción de memoria. ASan ha sido desarrollado por Google  y fue presentado en la conferencia Usenix ATC en 2012. ASan está formado por dos módulos: (a) un módulo de instrumentación de binarios en tiempo de compilación, que es el encargado de detectar si cada byte de la memoria de la aplicación es seguro de acceder mediante el uso de shadow memory, y (b) una biblioteca que en tiempo de ejecución es la que maneja la shadow memory. En líneas generales, sustituye los malloc y free por su propia implementación, controlando que se accedan a bloques de memoria dentro de las regiones adecuadas, que el espacio que se libere haya sido antes reservado, no accediendo a regiones liberadas etc.

Para usar ASan con GCC tenemos que compilar nuestro programa con la opción -fsanitize=address. Como ASan añade cierta sobrecarga al programa, se recomienda compilar con las opciones 01 ó 02 para tratar de optimizar el programa, y para que los errores que nos muestre sean más descriptivos tenemos que especificar que no queremos que GCC omita guardar el frame pointer en un registro, -fno-omit-frame-pointer. Para comprobar cómo funciona ASan tomamos como ejemplo el siguiente programa que presenta un error de tipo use-after-free:

#include <stdlib.h>
int main()
{
char *foo = (char*) malloc(2 * sizeof(char*));
free(foo);
return foo[0];
}

Primero compilamos sin ASan y ejecutamos:
$ gcc -o use-after-free use-after-free.c
$ ./use-after-free
y no nos enteramos de que algo va mal con nuestro programa.

Mientras que, compilando con ASan de la siguiente manera:
$ gcc -o use-after-free-asan-no-omit -fsanitize=address -O1 -fno-omit-frame-pointer use-after-free.c
$ ./use-after-free-asan-no-omit

asan-exampleEl  compilador nos muestra que tipo de error ha encontrado, diciéndonos que hemos hecho un use-after-free en esta posición: #0 0x4007b1 in main (/[OMITTED]/use-after-free-asan-no-omit+0x4007b1). Que había sido liberada en: #1 0x400793 in main (/[OMITTED]/use-after-free-asan-no-omit+0x400793). Y anteriormente reservada en: #1 0x400788 in main (/[OMITTED]/use-after-free-asan-no-omit+0x400788).

Podemos usar addr2line para hacer corresponder las direcciones del informe (0x4007b1, 0x400793, y 0x40078) a números de línea en nuestro programa y así tener una visión más clara de dónde hemos metido la pata.
$ addr2line -e ./use-after-free-asan-no-omit 0x4007b1 […]/use-after-free.c:8

Finalmente, si tenemos LLVM instalado, los informes de ASan tanto en Clang como en GCC podrán utilizar llvm-symbolizer para trasladar directamente las direcciones a número de línea si compilamos adicionalmente con -g y avisamos a ASan de que queremos que use el symbolizer:

$ which llvm-symbolizer-3.8
/usr/bin/llvm-symbolizer-3.8
$ export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.8
$ export ASAN_OPTIONS=symbolize=1
$ gcc -o use-after-free-asan-no-omit -fsanitize=address -O1 -fno-omit-frame-pointer -g use-after-free.c
$ ./use-after-free-asan-no-omit . . . omitido . . .
#0 0x4007b1 in main /[OMITTED]/use-after-free.c:8 . . .
#1 0x400793 in main /[OMITTED]/use-after-free.c:7 . . .
#1 0x400788 in main /[OMITTED]/use-after-free.c:6 . . . omitido . . .

El ejemplo que hemos tomado, y otros muchos se encuentran en la Wiki de ASan, donde se pueden consultar más detalles sobre el funcionamiento interno de ASan, y otros sanitizers, además la presentación de ASan en Usenix está disponible en su página.

¿Es esto suficiente? Lo descubriremos en los siguientes posts.

The post Hardening de binarios (III) – ASan appeared first on S3lab.

]]>