Guía Grsecurity v2 de Gentoo
1.
Acerca de Grsecurity
El Proyecto Grsecurity
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).
Integración en Gentoo Hardened
El Proyecto Gentoo Hardened
mantiene las características de mejoras de seguridad para Gentoo, incluyendo
pero no limitándose a grsecurity.
Configuración del Núcleo
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 el
archivo /usr/src/linux/.config a mano :)
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
|
2.
PaX
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:
- introducir/ejecutar código arbitrario
- ejecutar código existente fuera del orden del programa original
- ejecutar código existente en el orden original del programa con datos
arbitrarios
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:
-
Una sección de datos que contiene los datos asignados estáticamente y
los datos globales
-
Una región BSS (Block Started by Symbol) que contiene información de
los datos inicializados en cero del proceso
-
Una región de código, también llamada segmento de texto, que
contiene las instrucciones ejecutables
-
El heap que contiene la memoria asignada dinámicamente
-
Una pila que contiene las variables locales
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.
Activando PaX
La configuración del núcleo recomendada para PaX es:
Listado de Código 2.1: Configuración del núcleo recomendada para PaX |
CONFIG_GRKERNSEC_PAX_EI_PAX=y
CONFIG_GRKERNSEC_PAX_PT_PAX_FLAGS=y
CONFIG_GRKERNSEC_PAX_NO_ACL_FLAGS=y
CONFIG_GRKERNSEC_PAX_NOEXEC=y
CONFIG_GRKERNSEC_PAX_SEGMEXEC=y
CONFIG_GRKERNSEC_PAX_EMUTRAMP=y
CONFIG_GRKERNSEC_PAX_MPROTECT=y
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_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.
Controlando PaX
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 ofrece un guión de inicio que maneja la mayoría de configuraciones
de las aplicaciones más conocidas:
Listado de Código 2.3: Agregando el guión 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:
-
Con scanelf puede revisar los directorios de bibliotecas y binarios y
listar los diferentes permisos y tipos ELF relevantes para correr una
configuración ideal de pax/grsec.
-
Con pspax puede desplegar las banderas/capacidades/xattr PaX desde la
perspectiva del núcleo.
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:
-
strcpy y memcpy se listan como Vulnerables. Esto es esperable y
normal - simplemente muestra la necesidad de usar una tecnología como
ProPolice/SSP.
-
No hay aleatorización para PAGEEXEC. Esto es normal debido a que nuestra
configuración recomendada para el núcleo x86 no activó la opción de
PAGEEXEC. Sin embargo, en las arquitecturas que soporten (casi todas
incluyendo x86_64) realmente el bit NX (no ejecutable), PAGEEXEC es el único
método disponible para NOEXEWC y no afecta el rendimiento.
3.
RBAC
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 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.
Configurando el Núcleo
La configuración del núcleo recomendada para RBAC es:
Listado de Código 3.1: Configuración del núcleo recomendada para RBAC |
CONFIG_GRKERNSEC_ACL_HIDEKERN=y
CONFIG_GRKERNSEC_ACL_MAXTRIES=3
CONFIG_GRKERNSEC_ACL_TIMEOUT=30
|
Trabajando con gradm
gradm es una herramienta que le permite administrar y
mantener una directriz 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 directriz por defecto en
/etc/grsec/policy:
Listado de Código 3.2: Instalando gradm |
# emerge gradm
|
Por defecto, las directrices RBAC no están activadas. Es tarea del
administrador y no de Gentoo determinar cuándo el sistema debería
poner en vigor una directriz 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
Setting up grsecurity RBAC password
Password:
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
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
|
Generando una Directriz
El sistema RBAC viene con una excelente característica denominada
"modo de aprendizaje". Dicho modo puede generar una directriz
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 el sistema, haga las cosas que normalmente haría. Intente evitar
hacer una resincronización, 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
directriz, 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
|
Nota:
Necesitará deshabilitar el modo de aprendizaje de RBAC antes de hacer esto.
Puede usar gradm -D para conseguirlo.
|
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 directrices |
# 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
directriz.
Refinando su Directriz
Una interesante característica de grsecurity 2.x 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 del operador interesecció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 & 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 del operador 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.
Configuración del Núcleo
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 |
CONFIG_GRKERNSEC_PROC=y
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 la orden
sysctl:
Listado de Código 4.3: Activando las opciones vía sysctl |
# sysctl -w kernel.grsecurity.exec_logging = 1
# 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
|
5.
Auditando el Núcleo
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 de grsecurity:
Listado de Código 5.1: Activando la Auditoría del Núcleo |
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
Protección a los ejecutables
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.
Protección de la red
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.
Configuraciones del Núcleo
Las siguientes opciones del núcleo activan varias protecciones de red y
ejecutables:
Listado de Código 6.1: Configuraciones del Núcleo |
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
CONFIG_GRKERNSEC_RANDNET=y
CONFIG_GRKERNSEC_RANDISN=y
CONFIG_GRKERNSEC_RANDID=y
CONFIG_GRKERNSEC_RANDSRC=y
CONFIG_GRKERNSEC_RANDRPC=y
|
7.
El toolchain de Hardened
Aunque está fuera del alcance de este documento, mencionamos el uso
de la cadena de
herramientas de hardened que completa el modelo grsec/PaX
del espacio de usuario.
8.
Recursos
|