El proyecto grsecurity, alojado en http://www.grsecurity.org, ofrece varios parches al núcleo de Linux que mejoran la seguridad global de su sistema. En el siguiente capítulo se discuten las variadas características provistas por grsecurity, una lista completa de estas se encuentra en la página de características de grsecurity.
Como la características de grsecurity están basadas principalmente en el núcleo, la mayor parte de este documento explica las diversas características del núcleo y sus respectivos operandos "sysctl" (si es aplicable).
El Proyecto Gentoo Hardened mantiene las características de mejoras de seguridad para Gentoo, incluyendo pero no limitándose a grsecurity.
A lo largo de este documento hablaremos sobre la configuración del núcleo usando las variables de este, por ejemplo: CONFIG_GRKERNSEC_PAX_NO_ACL_FLAGS. Estas son las variables que usa el proceso de construcción del núcleo para determinar si cierta característica necesita ser compilada.
Cuando configure su núcleo mediante make menuconfig o algo similar, puede observar una interfaz de usuario a través de la cual puede seleccionar las opciones del núcleo. Si elige el botón de Ayuda (Help) en alguna característica del núcleo, verá en la parte superior que menciona el nombre de la variable.
Por lo tanto, puede configurar su núcleo como guste - pensando un poco. Si no puede encontrar cierta opción, siempre está la posibilidad de editar a mano el archivo /usr/src/linux/.config
Por supuesto, para seleccionar las variadas opciones del núcleo de grsecurity debe activarlo en su núcleo:
Listado de Código 1.1: Activando grsecurity |
CONFIG_GRKERNSEC=y CONFIG_GRKERNSEC_CUSTOM=y |
Luchando contra la explotación de bugs en el software
PaX introduce un par de mecanismos de seguridad que hacen más difíciles a los atacantes explotar bugs de software que involucren corrupción de memoria (pero note que PaX no protege contra todos los posibles bugs de software). El documento introductorio a PaX habla sobre tres técnicas posibles de explotación:
Un método de prevención no permite que se almacene código ejecutable en la memoria modificable (writable). Cuando miramos un proceso, este requiere de cinco regiones de memoria:
El primer método de prevención de PaX, llamado NOEXEC, tiene como objetivo dar control sobre la generación de código en tiempo de ejecución. Este marca como "no ejecutable" a las páginas de memoria que no contienen código ejecutable. Esto significa que el heap y la pila, que solamente contienen datos variables y no deberían contener código ejecutable, sean marcadas como "no ejecutables". Los exploits que coloque código en esas áreas con la intención de ejecutarlo simplemente fallarán.
NOEXEC hace más que eso en realidad, los lectores interesados deberían enfocar su atención a la documentación de NOEXEC de PAX (en inglés).
El segundo método de prevención de PAX, denominado ASLR (Address Space Layout Randomization, Aleatorización de Distribución del Espacio de Memoria), aleatoriza las direcciones dadas a peticiones de memoria. ASLR aleatoriza la asignación donde la memoria era previamente asignada contiguamente (lo que significa que los exploits saben donde están situadas las regiones de memoria de las tareas), haciendo inútiles las técnicas que dependen de esta información.
Se puede encontrar más información sobre ASLR en línea.
La configuración del núcleo recomendada para PaX es:
Listado de Código 2.1: Configuración del núcleo recomendada para PaX |
# # PaX Control # # CONFIG_GRKERNSEC_PAX_SOFTMODE is not set CONFIG_GRKERNSEC_PAX_EI_PAX=y CONFIG_GRKERNSEC_PAX_PT_PAX_FLAGS=y CONFIG_GRKERNSEC_PAX_NO_ACL_FLAGS=y # CONFIG_GRKERNSEC_PAX_HAVE_ACL_FLAGS is not set # CONFIG_GRKERNSEC_PAX_HOOK_ACL_FLAGS is not set # # Address Space Protection # CONFIG_GRKERNSEC_PAX_NOEXEC=y # CONFIG_GRKERNSEC_PAX_PAGEEXEC is not set CONFIG_GRKERNSEC_PAX_SEGMEXEC=y CONFIG_GRKERNSEC_PAX_EMUTRAMP=y CONFIG_GRKERNSEC_PAX_MPROTECT=y # CONFIG_GRKERNSEC_PAX_NOELFRELOCS is not set CONFIG_GRKERNSEC_PAX_ASLR=y CONFIG_GRKERNSEC_PAX_RANDKSTACK=y CONFIG_GRKERNSEC_PAX_RANDUSTACK=y CONFIG_GRKERNSEC_PAX_RANDMMAP=y CONFIG_GRKERNSEC_PAX_RANDEXEC=y # CONFIG_GRKERNSEC_KMEM is not set # CONFIG_GRKERNSEC_IO is not set CONFIG_GRKERNSEC_PROC_MEMMAP=y CONFIG_GRKERNSEC_HIDESYM=y |
Si está usando un sistema no x86, observará que no existe CONFIG_GRKERNSEC_PAX_NOEXEC. Debería en cambio seleccionar CONFIG_GRKERNSEC_PAX_PAGEEXEC ya que es la única implementación de NOEXEC que hay por el momento.
No todas las aplicaciones de Linux están contentas con las restricciones de seguridad de PaX. Entre estas están xorg-x11, java, mplayer, xmms y otros. Si planea usarlas puede alzar las protecciones para esas aplicaciones usando chpax y paxctl.
Listado de Código 2.2: Instalando las herramientas chpax y paxctl |
# emerge app-admin/chpax # emerge app-admin/paxctl |
chpax provee un script de inicio que maneja por Ud. la mayoría de configuraciones de las aplicaciones más conocidas:
Listado de Código 2.3: Agregando el script de inicio chpax al nivel de ejecución default |
# rc-update add chpax default
|
pax-utils en un pequeño conjunto de utilitarios que contiene aplicaciones útiles para administrar un servidor que use PaX.
Listado de Código 2.4: Instalando pax-utils |
# emerge pax-utils
|
Entre sus interesantes herramientas están scanelf y pspax:
Verificando las configuraciones de PaX
Peter Busser escribió una suite de pruebas de regresión llamada paxtest. Esta herramienta chequeará diversos casos de posibles vectores de ataque y le informa del resultado. Cuando la ejecuta, dejará un archivo de bitácora denominado paxtest.log en el directorio de trabajo actual.
Listado de Código 2.5: Instalando y corriendo paxtest |
# emerge paxtest # paxtest Executable anonymous mapping : Killed Executable bss : Killed Executable data : Killed Executable heap : Killed Executable stack : Killed Executable anonymous mapping (mprotect) : Killed Executable bss (mprotect) : Killed Executable data (mprotect) : Killed Executable heap (mprotect) : Killed Executable stack (mprotect) : Killed Executable shared library bss (mprotect) : Killed Executable shared library data (mprotect): Killed Writable text segments : Killed Anonymous mapping randomisation test : 16 bits (guessed) Heap randomisation test (ET_EXEC) : 13 bits (guessed) Heap randomisation test (ET_DYN) : 25 bits (guessed) Main executable randomisation (ET_EXEC) : 16 bits (guessed) Main executable randomisation (ET_DYN) : 17 bits (guessed) Shared library randomisation test : 16 bits (guessed) Stack randomisation test (SEGMEXEC) : 23 bits (guessed) Stack randomisation test (PAGEEXEC) : No randomisation Return to function (strcpy) : Vulnerable Return to function (memcpy) : Vulnerable Return to function (strcpy, RANDEXEC) : Killed Return to function (memcpy, RANDEXEC) : Killed Executable shared library bss : Killed Executable shared library data : Killed |
Del ejemplo mostrado arriba puede observar que:
Control de Acceso Basado en Roles (Role Based Access Control)
Existen dos tipos de mecanismos de control de acceso usados para prevenir el acceso desautorizado a archivos (o información en general): DAC (Control de Acceso Discrecional) y MAC (Control de Acceso Obligatorio). Linux usa por defecto un mecanismo DAC: el creador del archivo puede definir quién tiene acceso a este. Un sistema MAC por su parte fuerza a que todos sigan las reglas establecidas por el administrador.
La implementación MAC que soporta grsecurity es llamada Control de Acceso Basado en Roles. RSBAC asocia roles a cada usuario. Cada rol define qué operaciones pueden ser llevadas a cabo sobre ciertos objetos. Dada una colección bien escrita de roles y operaciones, sus usuarios estarán restringidos a hacer solamente aquellas tareas que Ud. le dice que pueden hacer. La restricción por defecto "deny-all" (negar todo) le asegura que un usuario no pueda realizar una acción de la cual no haya pensado.
La configuración del núcleo recomendada para RBAC es:
Listado de Código 3.1: Configuración del núcleo recomendada para RBAC |
#
# Role Based Access Control Options
#
CONFIG_GRKERNSEC_ACL_HIDEKERN=y
CONFIG_GRKERNSEC_ACL_MAXTRIES=3
CONFIG_GRKERNSEC_ACL_TIMEOUT=30
|
gradm es una herramienta que le permite administrar y mantener un política para su sistema. Con ella puede activar o desactivar el sistema RBAC, recargar los roles RBAC, cambiar su rol, configurar un contraseña para el modo de administración, etcétera.
Cuando instala gradm se dejará la política por defecto en /etc/grsec/policy:
Listado de Código 3.2: Instalando gradm |
# emerge gradm
|
Por defecto, las políticas RBAC no están activadas. Es tarea del administrador y no de Gentoo determinar cuándo el sistema debería poner en vigor una política RBAC. Antes de activar el sistema RBAC debería ajustar una contraseña de administración.
Listado de Código 3.3: Activando el sistema RBAC |
# gradm -P admin Setting up grsecurity RBAC password (Ingrese una astuta contraseña) Password: (Ingrese la misma contraseña para confirmar) Re-enter Password: Password written in /etc/grsec/pw # gradm -E |
Para desactivar el sistema RBAC, ejecute gradm -D. Si no se le permite, primero necesita cambiarse al rol de administrador:
Listado de Código 3.4: Desactivando el sistema RBAC |
# gradm -a admin (Ingrese su contraseña del rol administrador) Password: # gradm -D |
Si desea salir del rol de administrador, ejecute gradm -u admin:
Listado de Código 3.5: Saliendo del rol de administrador |
# gradm -u admin
|
El sistema RBAC viene con una excelente característica denominada "modo de aprendizaje". Dicho modo puede generar una política previsora de mínimos privilegios para su sistema. Esto permite ahorros de tiempo y dinero para poder instalar múltiples servidores seguros.
Para usar el modo de aprendizaje, actívelo usando gradm:
Listado de Código 3.6: Activanado el modo de aprendizaje de RBAC |
# gradm -F -L /etc/grsec/learning.log
|
Ahora use sistema, haga las cosas que normalmente haría. Intente evitar hacer una resincronizacion, ejecutar locate u otra operación de archivos pesada en términos de E/S ya que esto realmente puede ralentizar el tiempo de procesamiento.
Cuando crea que ha usado su sistema lo suficiente para obtener una buena política, deje que gradm la procese y le preponga roles en /etc/grsec/learning.roles:
Listado de Código 3.7: Procesando las bitácoras del modo de aprendizaje |
# gradm -F -L /etc/grsec/learning.log -O /etc/grsec/learning.roles
|
Audite el archivo /etc/grsec/learning.roles y guárdelo como /etc/grsec/policy (con permisos 0600) cuando esté listo.
Listado de Código 3.8: Guardando las políticas |
# mv /etc/grsec/learning.roles /etc/grsec/policy # chmod 0600 /etc/grsec/policy |
Ahora ya puede activar el sistema RBAC con su nueva e instruida política.
Una interesante característica de grsecurity2 es el Soporte de Operación de Conjuntos en el archivo de configuración. Actualmente se reconocen uniones, intersecciones y diferencias de conjuntos (de objetos en este caso).
Listado de Código 3.9: Conjuntos de ejemplo |
define objset1 {
/root/blah rw
/root/blah2 r
/root/blah3 x
}
define somename2 {
/root/test1 rw
/root/blah2 rw
/root/test3 h
}
|
Aquí hay un ejemplo de uso, y los objetos resultantes que serán añadidos a su sujeto:
Listado de Código 3.10: Ejemplo de intersección |
subject /somebinary o $objset1 & $somename2 |
Lo de arriba se expandiría a:
Listado de Código 3.11: Ajustes de resultado al sujeto |
subject /somebinary o /root/blah2 r |
Este es el resultado del operador de intersección & el cual toma ambos conjuntos y retorna los archivos que existen en ambos conjuntos y los permisos para esos archivos que existen en ambos conjuntos.
Listado de Código 3.12: Ejemplo de unión |
subject /somebinary o $objset1 | $somename2 |
Este ejemplo se expandiría a:
Listado de Código 3.13: Ajustes de resultado al sujeto |
subject /somebinary o /root/blah rw /root/blah2 rw /root/blah3 x /root/test1 rw /root/test3 h |
Este es el resultado del operador de unión "|" el cual toma ambos conjuntos y entrega los archivos que existen en alguno de los conjuntos. Si un archivo existe en ambos conjuntos también se retorna y el modo contiene las banderas que existen en alguno de los conjuntos.
Listado de Código 3.14: Ejemplo de diferencia |
subject /somebinary o $objset1 - $somename2 |
Este ejemplo se expandiría a:
Listado de Código 3.15: Ajustes de resultado al sujeto |
subject /somebinary o /root/blah rw /root/blah2 h /root/blah3 x |
Este es el resultado del operador de diferencia "-" que toma dos conjuntos y retorna los archivos que existen en el conjunto de la izquierda pero no en el calce del archivo en el conjunto de la derecha. Si un archivo existe en el conjunto izquierdo y se encuentra un calce en el de la derecha (ya sea que los nombres de archivos son iguales, o el directorio padre existe en el conjunto de la derecha) entonces se retorna el archivo y el modo del segundo conjunto se borra del primero, y ese archivo se retorna.
En algún oscuro pseudo lenguaje podría ver esto como:
Listado de Código 3.16: Explicación en Pseudolenguaje |
si ( ($objset1 contiene /tmp/blah rw) y ($objset2 contiene /tmp/blah r) ) entonces $objset1 - $objset2 contendría /tmp/blah w si ( ($objset1 contiene /tmp/blah rw) y ($objset2 contiene/ rwx) ) entonces $objset1 - $objset2 contendría /tmp/blah h |
El orden de prioridad (de mayor a menor) es: "-, & |".
Si no quiere preocuparse de recordar la precedencia, también se incluye reconocimiento de paréntesis, así que puede hacer cosas como:
Listado de Código 3.17: Ejemplo de uso de paréntesis |
(($set1 - $set2) | $set3) & $set4 |
4. Protección del Sistema de Archivos
Luchando contra el enjaulamiento (chroot) y abuso del sistema de archivos
Grsecurity2 incluye muchos parches que prohiben a los usuarios de obtener conocimiento innecesario acerca del sistema. Estos incluyen restricciones sobre el uso de /proc, enjaulado (chrooting), enlazado, etcétera.
Recomendamos la siguiente configuración de grsecurity en el núcleo para protección del sistema de archivos:
Listado de Código 4.1: Activando la protección del sistema de archivos |
# # Protecciones del sistema de archivos # CONFIG_GRKERNSEC_PROC=y # CONFIG_GRKERNSEC_PROC_USER is not set CONFIG_GRKERNSEC_PROC_USERGROUP=y CONFIG_GRKERNSEC_PROC_GID=10 CONFIG_GRKERNSEC_PROC_ADD=y CONFIG_GRKERNSEC_LINK=y CONFIG_GRKERNSEC_FIFO=y CONFIG_GRKERNSEC_CHROOT=y CONFIG_GRKERNSEC_CHROOT_MOUNT=y CONFIG_GRKERNSEC_CHROOT_DOUBLE=y CONFIG_GRKERNSEC_CHROOT_PIVOT=y CONFIG_GRKERNSEC_CHROOT_CHDIR=y CONFIG_GRKERNSEC_CHROOT_CHMOD=y CONFIG_GRKERNSEC_CHROOT_FCHDIR=y CONFIG_GRKERNSEC_CHROOT_MKNOD=y CONFIG_GRKERNSEC_CHROOT_SHMAT=y CONFIG_GRKERNSEC_CHROOT_UNIX=y CONFIG_GRKERNSEC_CHROOT_FINDTASK=y CONFIG_GRKERNSEC_CHROOT_NICE=y CONFIG_GRKERNSEC_CHROOT_SYSCTL=y CONFIG_GRKERNSEC_CHROOT_CAPS=y |
Gatillando el mecanismo de seguridad
Cuando está usando el núcleo compilado con las opciones mostradas arriba (o similares), obtendrá la opción de activar/desactivar muchas de las opciones a través del sistema de archivos /proc o vía sysctl.
El ejemplo a continuación muestra un extracto típico de /etc/sysctl.conf:
Listado de Código 4.2: Ejemplo de configuraciones dentro de /etc/sysctl.conf |
kernel.grsecurity.chroot_deny_sysctl = 1 kernel.grsecurity.chroot_caps = 1 kernel.grsecurity.chroot_execlog = 0 kernel.grsecurity.chroot_restrict_nice = 1 kernel.grsecurity.chroot_deny_mknod = 1 kernel.grsecurity.chroot_deny_chmod = 1 kernel.grsecurity.chroot_enforce_chdir = 1 kernel.grsecurity.chroot_deny_pivot = 1 kernel.grsecurity.chroot_deny_chroot = 1 kernel.grsecurity.chroot_deny_fchdir = 1 kernel.grsecurity.chroot_deny_mount = 1 kernel.grsecurity.chroot_deny_unix = 1 kernel.grsecurity.chroot_deny_shmat = 1 |
Puede activar o desactivar a voluntad las opciones usando el comando sysctl:
Listado de Código 4.3: Activando las opciones vía sysctl |
(Activa la característica exec_logging) # sysctl -w kernel.grsecurity.exec_logging = 1 (Desactiva la característica exec_logging) # sysctl -w kernel.grsecurity.exec_logging = 0 |
Existe una opción de configuración muy importante de sysctl, a saber, kernel.grsecurity.grsec_lock. Cuando está activada, no es posible hacer futuros cambios.
Listado de Código 4.4: Cerrando la posibilidad de usar la interfaz sysctl |
# sysctl -w kernel.grsecurity.grsec_lock = 1
|
Extendiendo las facilidades de generación de bitácoras (logging) de su sistema
grsecurity añade a su núcleo funcionalidad extra relativa a la generación de bitácoras. Con la Auditoría del Núcleo de grsecurity, el núcleo le informa cuando se inician las aplicaciones, si los dispositivos son (des)montados, etc.
Las diversas configuraciones de Auditoría del Núcleo
La siguiente sección de configuración del núcleo puede ser usada para activar las opciones de Auditoría del Núcleo:
Listado de Código 5.1: Activando la Auditoría del Núcleo |
#
# Kernel Auditing
#
# CONFIG_GRKERNSEC_AUDIT_GROUP is not set
CONFIG_GRKERNSEC_EXECLOG=y
CONFIG_GRKERNSEC_RESLOG=y
CONFIG_GRKERNSEC_CHROOT_EXECLOG=y
CONFIG_GRKERNSEC_AUDIT_CHDIR=y
CONFIG_GRKERNSEC_AUDIT_MOUNT=y
CONFIG_GRKERNSEC_AUDIT_IPC=y
CONFIG_GRKERNSEC_SIGNAL=y
CONFIG_GRKERNSEC_FORKFAIL=y
CONFIG_GRKERNSEC_TIME=y
CONFIG_GRKERNSEC_PROC_IPADDR=y
CONFIG_GRKERNSEC_AUDIT_TEXTREL=y
|
6. Restricciones a los procesos
Con grsecurity puede restringir los ejecutables. Debido a que la mayoría de los exploits funcionan mediante uno o más procesos en ejecución, esta protección puede salvar la salud de su sistema.
La pila TCP/IP de Linux es vulnerable a ataques basados en predicciones. Grsecurity incluye parches de aleatorización para contrarrestar esos ataques. Aparte de esos parches, también puede activar restricciones a los sockets, con lo que se prohibe completamente el acceso a la red a ciertos grupos.
Las siguientes opciones del núcleo activan varias protecciones de red y ejecutables:
Listado de Código 6.1: Configuraciones del Núcleo |
# # Protecciones de Ejecutables # CONFIG_GRKERNSEC_EXECVE=y CONFIG_GRKERNSEC_DMESG=y CONFIG_GRKERNSEC_RANDPID=y CONFIG_GRKERNSEC_TPE=y CONFIG_GRKERNSEC_TPE_ALL=y CONFIG_GRKERNSEC_TPE_GID=100 # # Protecciones de Red # CONFIG_GRKERNSEC_RANDNET=y CONFIG_GRKERNSEC_RANDISN=y CONFIG_GRKERNSEC_RANDID=y CONFIG_GRKERNSEC_RANDSRC=y CONFIG_GRKERNSEC_RANDRPC=y # CONFIG_GRKERNSEC_SOCKET is not set |
Aunque está fuera del alcance de este documento, mencionamos el uso del toolchain de Hardened que completa el modelo grsec/PaX desde el espacio del usuario (userspace). Como consejo rápido puede hacer:
Listado de Código 7.1: Usando el toolchain de Hardened |
# cd /etc # rm make.profile # ln -s ../usr/portage/profiles/hardened/x86 make.profile # emerge -e world |
Si no quiere usar este perfil, agregue estas banderas USE hardened pic a su variable USE en /etc/make.conf.