ARTICULO SOBRE SEGURIDAD EN COMPILADORES GUSTAVO TOLOZA – OSCAR NAVARRO FUNDACION UNIVERSITARIA REMINGTRON INGENIERIA DE SISTEMAS PEREIRA – SEPTIEMBRE 2019 Compiladores y seguridad ¿Afecta o mejora el compilador la seguridad del código? Un compilador traduce el código fuente de un programa en código máquina, utilizando las especificaciones del lenguaje de programación en sí. Los compiladores también pueden optimizar el código, o examinar la lógica del código para buscar formas de ejecutarlo de manera más eficiente, lo que mejoraría el rendimiento del programa en ejecución. El diseño tradicional de compiladores consta de tres partes: Imagen 1. Diseño de un compilador El Frontend traduce código fuente en una representación intermedia (IR) de éste. LLVM IR es un lenguaje de bajo nivel parecido a ensamblador. Sin embargo, omite cualquier información específica del hardware. clang es el frontend de LLVM para la familia de lenguajes de C. El Optimizador analiza la IR y la traduce a una forma más eficiente; opt es la herramienta de optimización de LLVM. El Backend genera código máquina al mapear la IR al conjunto de instrucciones del hardware de destino; llc es la herramienta LLVM de backend. Desde que fueron inventados en el año 1952 por Grace Hopper y posteriormente su uso masificado, los compiladores se han convertido en una herramienta muy utilizada a la hora de ejecutar código que ha sido escrito previamente en un lenguaje de programación. Tanto así que los compiladores actuales son capaces de corregir errores en el código y ejecutar los programas basados en diferentes algoritmos de lectura y corrección que busca optimizar y hacer más rápida la ejecución de un programa, sin embargo, ¿puede esa lectura y optimización de código hacer un programa más o menos seguro? La seguridad informática es un tema álgido dado que basta que una parte del sistema sea inseguro para hacer inseguro a todo el sistema, hoy en día estamos acostumbrados a escribir código y que un compilador haga el resto de tareas por nosotros, compiladores que han sido desarrollados por el equipo de programadores que desarrolla el lenguaje de programación, es necesario precisar por lo tanto que la seguridad de un sistema está ligada directamente a la seguridad que se haya puesto en su compilador. El compilador debe garantizar que el código antes y después de la compilación realice la misma función, el desarrollador del software también ha asumido que el código optimizado se irá la memoria del sistema en el mismo estado que el código no opimizado, sin embargo, se ha suscitado un debate sobre si el compilador debe preservar las garantías de seguridad incorporadas en código fuente, si es responsabilidad del desarrollador comprender el impacto de las optimizaciones del compilador en su código, y si el comportamiento anterior califica como un error del compilador. El compilador puede ayudar de dos formas al programador a hacer más seguro un código en general, la primera forma es emitiendo una advertencia de malas prácticas, es decir avisando al programador cuando está dejando “baches” que hagan que su código sea más inseguro, la segunda forma es automatizando tareas complejas para que sea más fácil para el programador, sin embargo es aquí donde radica el problema de seguridad, según el editor del blog de Microsoft en su publicación del día 22 de julio de 2017, los ataques basados en errores de compilación no son comunes pero tampoco son imposibles, ya desde 1974 se conocen ataques de este tipo, un ejemplo de que este tipo de ataques se pueden realizar, lo hizo el señor Ken Thompson co-creador del sistema operativo UNIX y del lenguaje C La prueba proponía lo siguiente: Tomar el patrón del código fuente del programa login (utilizado para iniciar sesión en entornos UNIX). Modificar el código fuente del propio compilador, de manera que al darse cuenta de que está compilando el programa login, le inserte en su rutina de validación un password válido de manera estática (hardcoded) sólo conocido por el creador. Modificar además el código del compilador para que al detectar que está compilando el propio código del compilador, inserte el código que permita detectar el patrón de login, y además inserte el código que genera este mismo código (o sea, el fragmento de sí mismo que corresponde a este último párrafo). Compilar el compilador modificado, volver a tomar el código limpio y compilarlo con el compilador modificado (binario compilado previamente). ¿Que obtenemos con todo esto? Un compilador que permite insertar un generador de backdoors al compilar otro compilador, o un backdoor al compilar login, pero que en su código fuente no tenía dicho código.1 Por lo tanto garantizar que la compilación sea correcta es necesario para garantizar la integridad del software en general, el desafío para los compiladores es en mayor medida limitar y estructurar posibles errores utilizando u na estructura de código eficiente, que no ralentice la ejecución del programa, pero que permita hacer una segunda verificación a las vulnerabilidades de seguridad sobre todo en aquellos campos donde los usuarios deben ingresar información o tener acceso con una base de datos. Las grandes compañías como Microsoft ya trabajan con herramientas de refinamiento de código verificando que las optimizaciones sean correctas y la salida del código compilado sea correcta. En conclusión, el programador debería conocer si un compilador hace mas o me nos vulnerable el programa realizado, teniendo en cuenta políticas de seguridad de su trabajo y conociendo previamente que ataques de seguridad en compilación a recibido el lenguaje de programación con el que trabaja. 1. Article title: El abuelo de los backdoors | WeLiveSecurity Website title: URL: WeLiveSecurity https://www.welivesecurity.com/la-es/2010/10/19/el-abuelo-de-los-backdoors/ https://www.embecosm.com/2017/02/20/security-enhanced-compilers https://www.microsoft.com/en-us/research/blog/getting-compilers-right-secure-software/ https://www.tripwire.com/state-of-security/security-data-protection/can-compilers-make-codesecure/ https://www.welivesecurity.com/la-es/2010/10/19/el-abuelo-de-los-backdoors/ https://ieeexplore.ieee.org/document/7163211 https://clang.llvm.org/ https://llvm.org/docs/CommandGuide/opt.html https://llvm.org/docs/CommandGuide/llc.html The Correctness-Security Gap in Compiler Optimization