. App-Armor: Defensa en profundidad contra ataques nuevos y desconocidos en plataformas Linux. Lic. Pablo Milano - Consultor CYBSEC ([email protected]) La carrera de las vulnerabilidades Uno de los mayores problemas que enfrentan las organizaciones, en cuanto a sus sistemas informáticos, es la protección contra vulnerabilidades en las aplicaciones de software. En primer lugar, hay un tiempo que necesariamente transcurre desde que un fabricante lanza un parche de seguridad hasta que cada organización lo testea y luego lo instala en todos los equipos necesarios. Muchas veces, este tiempo es suficiente para que en el mundo de los atacantes subrepticios se generen los “exploits” correspondientes y se comiencen a utilizar sobre los sistemas vulnerables. Incluso, muchas veces las vulnerabilidades se publican antes de que el fabricante lance los parches adecuados, aumentando el tiempo de “ventana” en el que los sistemas se ven expuestos por vulnerabilidades conocidas. Para terminar de empeorar las cosas, en muchas ocasiones, hay atacantes que descubren y explotan vulnerabilidades antes incluso de que los fabricantes las conozcan. A estas vulnerabilidades se las denominan “zero-days” y son las más peligrosas, ya que al no conocerlas, es muy difícil saber cómo protegerse de ellas. Por tal motivo, es necesario adoptar medidas de protección preventivas, desde un enfoque diferente. Y ahora, ¿Quién podrá ayudarme? App-armor es una implementación relativamente simple de Control de Acceso Mandatorio (MAC) sobre Linux. Está incluída en la distribución SUSE, pero también puede utilizarse en otras distribuciones. Su función es la de aplicar restricciones de acceso sobre las aplicaciones que, a diferencia del Control de Acceso Discrecional (DAC), no se basa en privilegios de los usuarios sino en políticas del sistema, implementadas como perfiles. En estos perfiles, se especifican explícitamente las acciones que la aplicación puede realizar dentro del sistema. Dado que las restricciones sobre las aplicaciones se basan en las políticas del sistema y no en los permisos de los usuarios, la aplicación se encontrará restringida independientemente del usuario que la esté ejecutando, incluso si fuera el super-usuario “root”. Por otro lado, el cumplimiento de las políticas no es responsabilidad de una aplicación o servicio, sino del propio Kernel de Linux, (como en el caso del Firewall “iptables”) lo cual dificulta las posibilidades de saltear los mecanismos de control de acceso. 1 Existen otras implementaciones de MAC sobre Linux (ej: SELinux 1), pero en este caso hemos elegido App-Armor debido a su facilidad de configuración y administración. ¿Cómo funciona? Para cada aplicación que se desee proteger, se debe generar un perfil en el que se explicita el rango de acción de la aplicación en dos aspectos a saber: 1- Capabilities POSIX2: Es un conjunto de “capacidades” que se le pueden otorgar a un proceso para interactuar con el sistema operativo. Estas capacidades incluyen acciones como por ejemplo: cambiar la hora del sistema, bloquear memoria, modificar la tabla de ruteo, abrir un socket en un puerto menor a 1024, cargar y descargar módulos del sistema, reiniciar el equipo, etc. Al listar explícitamente las “Capabilities” POSIX que se le otorgan a una aplicación, se restringe el rango de acción de la misma ante eventuales ataques que pudieran realizarse sobre la misma. 2- Control de acceso al sistema de archivos: Se especifica una lista exhaustiva de todos los archivos y directorios a los que la aplicación o proceso tendrán acceso, indicando el tipo de acceso a cada uno de ellos. Esta restricción es independiente de los permisos de acceso que dichos archivos y directorios tengan en el sistema de archivos. Así entonces, si por ejemplo en el perfil de App-armor para la utilidad “syslog” especificamos que dicho binario tenga acceso de sólo lectura al archivo “/etc/syslog.conf”, dicha utilidad no podrá escribir en el archivo por más que los permisos en el sistema de archivo se lo permitan. El Perfil en detalle Para entender mejor la estructura de los perfiles, utilizaremos como ejemplo el siguiente perfil para la utilidad de sincronización remota de hora “NTPD” 3 /usr/sbin/ntpd { #include <abstractions/base> #include <abstractions/nameservice> capability capability capability capability capability capability capability ipc_lock, net_bind_service, setgid, setuid, sys_chroot, sys_resource, sys_time, /drift/ntp.drift rwl, /drift/ntp.drift.TEMP rwl, /etc/ntp.conf r, 1 2 3 Para más info sobre SELinux: http://www.nsa.gov/selinux/ Para más info sobre Capabilities Posix: http://man.cx/capabilities(7) Para mas información sobre NTPD: http://www.ntp.org/ 2 /etc/ntp/drift* rwl, /etc/ntp/keys r, /etc/ntp/step-tickers r, /tmp/ntp* rwl, /var/lib/ntp/etc/ntp.conf.iburst r, /var/lib/ntp/drift rwl, /var/lib/ntp/drift.TEMP rwl, /var/lib/ntp/drift/ntp.drift r, /var/lib/ntp/var/run/ntp/ntpd.pid w, /var/log/ntp w, /var/log/ntp.log w, /var/run/ntpd.pid w, } La primer sección contiene inclusiones de archivos llamados “abstracciones”. Las mismas, están agrupadas por tipo de aplicación y sirven para definir de manera global los permisos de acceso a librerías y archivos básicos del sistema operativo (ej: /dev/null, /lib/libc.so.6, /dev/random, etc.) simplificando así la escritura de los perfiles mediante la modularización. De esta forma, varios perfiles que comparten funcionalidades similares pueden utilizar los mismos archivos de abstracción. La segunda sección contiene las “Capabilities POSIX” que se le otorgan a la aplicación. En este caso, entre otras cosas, se le está otorgando a NTPD capacidad para cambiar la hora del sistema, bloquear memoria, abrir un Socket en un puerto menor a 1024, manejar los ID´s de usuario y grupo del proceso y cambiar el directorio raíz del proceso (chroot). Por último, la tercer sección contiene la lista de los archivos a los que NTPD tendrá acceso junto con el tipo de acceso a los mismos. Aquí entonces, por ejemplo se le permite a NTPD permiso de escritura al archivo “/var/log/ntp” y permiso de lectura, escritura y manejo de links simbólicos a todos los archivos del directorio “/tmp” cuyo nombre comience con “ntp”. Es importante notar que para que la aplicación tenga acceso efectivo a los archivos, además de contar con una entrada correspondiente en el perfil de App-Armor, también el archivo debe tener los permisos necesarios en el sistema de archivos. Así entonces, la restricción efectiva del proceso para el acceso a los archivos es la intersección de las restricciones de acceso del sistema de archivos y las de App-Armor. Este perfil asegura que, en la eventualidad de un ataque exitoso a una vulnerabilidad en la utilidad “NTPD”, el atacante podrá acceder únicamente a los archivos listados en el perfil, y tendrá únicamente las capacidades de interacción con el sistema operativo especificadas en la sección de “Capabilities”. Si esta vulnerabilidad, por ejemplo permitiera la ejecución de comandos arbitrarios pasados como parámetro, el atacante no podrá ejecutar ninguno, ya que no hay ningún archivo con permisos de ejecución listado en el perfil. Un valor agregado de los perfiles de Control de Acceso Mandatorio, es que nos permiten listar en un único lugar, todos los permisos necesarios para una aplicación, lo cual nos facilita la revisión de seguridad de los mismos y la aplicación del “criterio de menor privilegio”. 3 Ejecución encadenada Cuando la aplicación que estamos asegurando, necesita a su vez ejecutar otra aplicación, tenemos varias posibilidades de permisos de acceso para la aplicación “hija”: Modo de ejecución por perfil discreto (px): En este modo, le indicamos a App-Armor que utilice un perfil separado y diferente para la ejecución de la aplicación “hija”. Esto sirve para aplicaciones grandes que requieren configuraciones complejas, como por ejemplo una instancia de Apache ejecutando Sendmail para el envío de e-mails. Modo de ejecución heredada (ix) En este modo, la aplicación “hija” hereda la configuración del perfil de la aplicación madre. Esto es útil para aplicaciones menores con funciones específicas, como por ejemplo un “Shell Script” que copia un archivo de un lugar a otro. Modo “unconstrained” (ux) Este modo permite la ejecución irrestricta a la aplicación hija. Se recomienda utilizar únicamente en casos estrictamente necesarios, ya que dicha aplicación deja de estar protegida por App-Armor. La principal utilidad de este modo es al momento de realizar “debugging” de una aplicación, sin que las restricciones de App-Armor interfieran el funcionamiento de la misma. ¿Cómo lograr una configuración adecuada? Si estamos asegurando una aplicación pequeña y sencilla, es probable que podamos determinar la lista exacta de “Capabilities” y archivos necesarios para nuestra aplicación. En cambio, cuando necesitamos crear un perfil para una aplicación más compleja, esta tarea se torna sumamente difícil. Por tal motivo, App-Armor provee herramientas para facilitar la creación de perfiles. Una de estas herramientas se llama “autodep”, y su función es verificar cuáles son las librerías necesarias para la ejecución de una aplicación utilizando la herramienta “ldd”, repitiendo luego este proceso de manera recursiva sobre las librerías hasta obtener el conjunto completo de las mismas. Con esto, se puede realizar un perfil inicial aproximado para la aplicación. Modo de aprendizaje y modo “enforce” Una vez que se tiene un perfil aproximado, se puede configurar al mismo en modo “aprendizaje”. En este modo, App-Armor permite el acceso irrestricto (unconstrained) a la aplicación, pero cada vez que la misma se excede del perfil actual, (Ej: utilizando una nueva “Capability” no listada en el perfil, o abriendo un archivo en modo de escritura cuando el mismo estaba listado en modo lectura), se genera una entrada de Log de auditoría, de la misma forma que se generaría si la aplicación estuviese restringida. Este modo sirve para “aprender” cuáles son los permisos necesarios para el uso normal de una aplicación. Una vez que se utilizó toda la funcionalidad de una aplicación cuyo perfil se encontraba en modo “aprendizaje”, se puede utilizar la herramienta “genprof”. Esta 4 herramienta revisa las entradas de los Logs de auditoría y mediante un menú interactivo, permite agregar al perfil todos los archivos y “Capabilities” que no estaban incluidos y que fueron utilizados por la aplicación durante el modo de “aprendizaje”. Conclusión App-Armor permite reforzar la seguridad de las aplicaciones y servicios Linux mediante herramientas sencillas, configurándole a las aplicaciones restricciones a los recursos del sistema basados en políticas. App-Armor no es un sustituto de los parches y “hot-fixes” ni de las medidas de seguridad “tradicionales”, tales como control de acceso discrecional, jaulas “chroot”, etc. Por el contrario, es un complemento para dichas medidas que aumenta la seguridad de las aplicaciones, protegiéndolas “en profundidad” ante eventuales vulnerabilidades futuras o desconocidas y reduciendo el impacto que la explotación de las mismas pudiera llegar a causar. Referencias The App-Armor project: http://es.opensuse.org/AppArmor Lic. Pablo Milano - Consultor CYBSEC CYBSEC S.A. desde 1996 se dedica exclusivamente a prestar servicios profesionales especializados en Seguridad de la Información. Su área de servicios cubre Latinoamérica y más de 200 clientes acreditan la trayectoria empresaria. Para más información: www.cybsec.com. © 2007 CYBSEC S.A. 5