domingo, 19 de septiembre de 2010

Error de regresión en el kernel Linux resucita una elevación de privilegios

El investigador de seguridad Ben Hawkes se hallaba diseccionando el modo de compatibilidad del kernel Linux de 64 bits para aplicaciones de 32 cuando dio con algo que llamó su atención:

En el 2007 fue publicada una vulnerabilidad que permitía elevar privilegios en el kernel Linux de 64 bits. El problema residía en el archivo 'arch/x86_64/ia32/ia32entry.S', dentro de un procedimiento para emular las llamadas de la arquitectura de 32 bits.

Dicho procedimiento usa el registro eax como índice a una tabla donde están las llamadas del sistema correspondientes a IA32 y comprueba que eax está dentro de los límites de la tabla. Si es así llama a la macro IA32_ARG_FIXUP que realizará una conversión de registros de 64 bits a registros de 32.

Finalmente se realiza la llamada a través de ia32_sys_call_table pero usando el registro 'rax' completo y sin comprobar. Esto permite, si podemos controlar 'rax', efectuar llamadas a direcciones fuera de la tabla de llamadas y con privilegios del sistema (elevación de privilegios).

Dicho fallo, originalmente descubierto por Wojciech Purczynski, fue corregido añadiendo la macro LOAD_ARGS32 para cargar de manera segura los registros previniendo su explotación. En su día fue publicado el exploit correspondiente y se asignó el CVE-2007-4573 a la vulnerabilidad.

Lo que Ben observó fue que en las nuevas versiones del kernel, los desarroladores habían eliminado una linea concreta de la macro LOAD_ARGS32: "movl \offset+72(%rsp),%eax".

Curiosamente se trata de la que efectuaba una asignación segura del valor de 'eax'. Esto puede verse en el commit correspondiente del repositorio del kernel.

De nuevo la vulnerabilidad estaba viva. Ben se lo comunicó a Robert Swiecki, quien creo el exploit original y el cual sólo tuvo que modificarlo para que fuese funcional una vez más.

El fallo ha sido nuevamente parcheado y asignado el CVE-2010-3301.


David García
dgarcia@hispasec.com


Más información:

linux compat vulns (part 2)
http://sota.gen.nz/compat2/

isec-0025-syscall-emulation
http://isec.pl/vulnerabilities/isec-0025-syscall-emulation.txt

CVE-2010-3301 kernel: IA32 System Call Entry Point Vulnerability
https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2010-3301

No hay comentarios:

Publicar un comentario en la entrada