Guía de inicio rápido para usar PaX con Gentoo Hardened
1.
¿Qué es Gentoo Hardened?
El proyecto Hardened de Gentoo trata de añadir características a un
sistema Gentoo que ayuden a evitar compromisos de seguridad. Este
enfoque no es siempre sistemático, y muchas de las características
son añadidas. Algunos de éstas complementan otras (por ejemplo PIE
de la cadena de herramientas reforzada y ASLR del núcleo PaX
reforzado), en cambio otras son mutuamente excluyentes (como SELinux
y el núcleo RSBAC de Grsecurity reforzado). Este documento se centra
en PaX que añade una mejora en la seguridad a ese área entre
el núcleo y la zona de usuario.
2.
¿Qué es PaX?
PaX es un parche para el núcleo Linux que ofrece el reforzamiento del
mismo de tres formas:
1. La primera protección que ofrece PaX es un reforzamiento
juicioso de memoria no ejecutable. Esto evita un tipo común de
ataque en el que el atacante introduce código ejecutable en el
espacio de direcciones de un proceso y a continuación lo ejecuta,
secuestrando el proceso y posiblemente escalando privilegios. El
vector normal de inserción es a traves de datos ofrecidos por el
usuario que encuentran su camino hasta la memoria ejecutable.
Asegurándonos de que los "datos" viven únicamente en memoria que
no es ejecutable y que el "texto" se encuentra en memoria que
es ejecutable, PaX protege de forma preventiva contra esta clase
de ataques.
Ejecute le siguiente código con MPROTECT de PaX reforzado y no
reforzado para ver esta característica en acción:
Listado de Código 2.1: mmap-rwx.c: viola MPROTECT con RWX mmap |
/*
* Compare al compilarlo con:
* gcc -UBAD -o mmap-rw mmap-rwx.c
* gcc -DBAD -o mmap-rwx mmap-rwx.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
int main()
{
size_t *m;
#ifdef BAD
m = mmap( NULL, 1024, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 );
#else
m = mmap( NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 );
#endif
if( m == MAP_FAILED )
printf("mmap failed: %s\n", strerror(errno));
else
printf("mmap succeeded: %p\n", m);
return 0;
}
|
De forma similar, ejecute el siguiente código con EMULTRAMP habilitado
y deshabilitado. Este complicado código fuerza a gcc a preparar un
trampolín para la función anidada f2(). El trampolín es código ejecutable
que vive en la pila y podría permitir que el usuario inyectara su
propio código a través de la variable i.
Listado de Código 2.2: trampoline.c: forzar a gcc a que genere un trampolín |
/*
* Comparar al compilarlo con:
* gcc -DTRAMPOLINE -o trampoline trampoline.c
* gcc -UTRAMPOLINE -o trampoline trampoline.c
*
*/
#include <stdio.h>
typedef void (*fptr)(void) ;
void f0(fptr f)
{
(*f)();
}
void f1()
{
int i ;
printf("Enter an integer: ");
scanf("%d", &i);
void f2()
{
printf("%d: Bouncey bouncey bounce!\n", i);
}
#ifdef TRAMPOLINE
f0(f2);
#endif
}
int main ()
{
f1() ;
return 0;
}
|
2. La segunda protección es la Aleatorización del Esquema del
Espacio de Direcciones (ASLR o Address Space Layout Randomization).
Esta protección ofrece una aleatorización del mapa de memoria de un
proceso (tal y como informa, por ejemplo, pmap) y así, hace que sea
más difícil para un atacante encontrar código que pueda constituir
una amenaza en ese espacio. Cada vez que un proceso se creado desde
un ejecutable ELF en particular, su mapa de memoria es diferente. Así
el código peligroso que podría vivir en 0x00007fff5f281000 para
una instancia del ejecutable, podría encontrarse en
0x00007f4246b5b000 para otra. A pesar que el los fuentes del núcleo
Linux ofrecen alguna forma de ASLR, un núcleo parcheado con PaX
incremente este efecto. Aún más, cuando una aplicación se construye
como un Ejecutable Independiente de la Posición (PIE o
Position Independent Executable), incluso la dirección base se
aleatoriza. Intente ejecutar de forma repetida el siguiente código
tanto en un núcleo Linux sin modificaciones como en uno preparado
con PaX, con y sin PIE:
Listado de Código 2.3: aslr-test.c: aleatorizar la dirección base para PIE |
/*
* Comparar al compilarlo con:
* gcc -o aslr-test-withpie -fPIC -pie aslr-test.c
* gcc -o aslr-test-without -fno-PIC -nopie aslr-test.c
*
*/
#include <stdio.h>
void doit()
{
;
return ;
}
int main()
{
printf("main @ %p\n", main);
printf("doit @ %p\n", doit);
return 0;
}
|
Para obtener más información sobre PIE, lea nuestra documentación
sobre Cadena de Herramientas de
Gentoo Hardened.
3. Por último, los parches de PaX ofrecen algún reforzamiento
extra: borrado de la pila cuando se retorna de una llamada al sistema,
rechazo a la hora de dereferenciar los punteros a la zona de usuario
en algunos contextos, detectando el desbordamiento de ciertos
contadores de referencia, corrigiendo los desbordamientos de algunos
de los contadores de enteros, forzado del tamaño de las copias entre
el núcleo y la zona de usuarios y oferta de entropía extra.
Se puede obtener más información sobre PaX en su página oficial,
http://pax.grsecurity.net.
3.
Comprender PaX
El primer paso para trabajar con PaX es configurar y arrancar un
núcleo parcheado con PaX. Dependiendo de si se ha configurado
PaX para SOFTMODE o no SOFTMODE, el núcleo arrancará automáticamente
el forzado de restricciones de memoria y una aleatorización del
espacio de direcciones de todos los procesos. Idealmente, no
debería de hacer nada más, sin embargo, para ejecutables problemáticos
en no SOFTMODE, se requiere un segundo paso: deberá relajar algunas
restricciones PaX para cada objeto ELF. Esto se hace modificando
los ajustes PaX que lee el núcleo cuando el fichero ELF se carga en
memoria y comienza su ejecución. Este segundo paso normalmente es
directo excepto cuando el objeto ELF que requiere esta relajación
es una librería. En este caso, los ajustes de la librería tienen
que portarse al ejecutable que enlaza a la librería debido a que
cuando PaX fuerza o relaja sus características, lo hace basándose
en los ajustes del ejecutable, no en los de la librería a la cual
enlaza. Discutiremos ambos pasos en detalle más abajo, pero en
primer lugar necesitamos echar un vistazo rápido a las características
de PaX. Las enumeraremos aquí, y para más detalles, remitiremos
al lector a la
documentación
oficial de PaX.
SOFTMODE: Si se selecciona esta opción, la protección de PaX
no se forzará por defecto para aquéllas características que se
pueden habilitar o deshabilitar en tiempo de ejecución, por lo que
este el el modo "permitir por defecto" contrario al "prohibir por
defecto" que se obtiene cuando no se selecciona esta opción. En
SOFTMODE, el usuario debe explícitamente marcar los ejecutables
para forzar las protecciones PaX, mientras que en no SOFTMODE,
el usuario debe marcar explícitamente para relajar las protecciones
PaX.
Forzar páginas no ejecutables:
-
PAX_NOEXEC - Esta opción habilita la protección de las
páginas de memoria reservadas como no ejecutables si no so parte
del segmento de texto del proceso que se está ejecutando
actualmente. Es necesario para PAGEEXEC, SEGMEXEC and KERNEXEC.
-
PAGEEXEC - El núcleo protegerá las páginas no ejecutables
basándose en la característica que posee la CPU. Esto a veces se
denomina "marcar la página con el bit NX" en otros sistemas
operativos. Esta característica se pueden controlar en cada objeto
ELF object basis mediante los ajustes PaX P y p.
-
SEGMEXEC - Esta opción es como PAGEEXEC, pero se basa en
la característica de segmentación que ofrece la CPU y se controla
mediante los ajustes PaX S y s. Observe que
SEGMEXEC únicamente está disponible en CPUs que ofrecen
segmentación de memoria, principalmente x86.
-
EMUTRAMP - El núcleo emulará trampolines (fragmentos
de código escritos sobre la marcha) para los procesos que los
necesiten, por ejemplo, funciones anidadas en C y en algunos
compiladores JIT. Ya que los trampolines tratan de ejecutar el
código escrito por el propio proceso a la memoria marcada como
no ejecutable por PAGEEXEC o SEGMEXEC, el núcleo PaX podría
matar cualquier proceso que intente hacer uso de alguna. EMUTRAMP
permite a estos procesos correr sin tener que deshabilitar
completamente el forzado de memoria no ejecutable. Esta
característica se puede controlar para cada objeto ELF mediante
el ajuste de PaX E y e.
-
MPROTECT - El núcleo evitará la introducción de nuevas
páginas ejecutables en el proceso que se está ejecutando
mediante distintas técnicas: Prohibirá cambiar el estado de
ejecución de las páginas o la creación de mapeos RWX anónimos,
o hacer que las páginas de datos RELRO sean escribibles. Esto
se puede controlar para cada objeto ELF mediante el ajuste PaX
M y m.
-
KERNEXEC - Este el ajuste equivalente a PAGEEXEC y
MPROTECT en la zona del núcleo. No se puede deshabilitar mientras
el núcleo está corriendo.
Aleatorización del Esquema del Espacio de Direcciones Mejorado
(ASLR):
-
PAX_ASLR - El núcleo expandirá el número de bits
aleatorizados para las distintas secciones del espacio de
direcciones. Esta opción es necesaria para RANDMMAP, RANDKSTACK
y RANDUSTACK.
-
RANDMMAP - El núcleo utilizará una base de direcciones
aleatorizada para las peticiones mmap() que no especifiquen
una a través del ajuste MAP_FIXED. Esto se controla mediante
los ajustes PaX R y r.
-
RANDKSTACK - El núcleo aleatorizará cada pila de de
tareas del núcleo en todas las llamadas al sistema. No se
puede deshabilitar mientras el núcleo se está ejecutando.
-
RANDUSTACK - El núcleo aleatorizará cada pila de
tarea de la zona de usuario. Esta característica se puede
controlar para cada binario ELF mediante los ajustes PaX
R y r.
Métodos de protección de memoria misceláneos:
-
Ninguna de las siguientes características se pueden deshabilitar
mientras el núcleo se está ejecutando:
-
STACKLEAK - El núcleo borrará su pila antes de retornar
desde una llamada al sistema. Esta característica no se puede
deshabilitar mientras el núcleo se está ejecutando.
-
UDEREF - El núcleo no dereferenciará punteros en zona de
usuario en contextos en los que se esperan únicamente punteros
del propio núcleo. Esta característica no se puede deshabilitar
mientras el núcleo se está ejecutando.
-
REFCOUNT - El núcleo detectará y evitará el desbordamientos
de varios (pero no todos) los tipos de contadores de referencias
a objetos.
-
USERCOPY - El núcleo forzará el tamaño de los objetos
del montículo cuando se copian en cualquier dirección entre
el núcleo y la zona de usuario.
-
SIZE_OVERFLOW - El núcleo recalculará expresiones de
argumentos de función marcados por un atributo size_overflow
con una precisión de entero doble.
-
LATENT_ENTROPY - El núcleo utilizará el código de arranque
cuanto antes para generar entropía extra, lo cual es especialmente
útil en sistemas empotrados.
Tal y como se describe más arriba, algunas de las características de
PaX se pueden forzar (en el caso de SOFTMODE) o relajar (en el caso
de no SOFTMODE) para cada objeto ELF. Éstos son PAGEEXEC, EMULTRAP,
MPROTECT, RANDMMAP y SEGMEXEC y éstos se controlan respectivamente
mediante los siguientes ajustes: P, E, M, R, S y p, e, m, r, s.
Los ajustes en mayúsculas indican "reforzar" en SOFTMODE y aquéllos
en minúsculas indican "relajar" en no SOFTMODE. Una tercera
posibilidad es que ni los ajustes para reforzar ni para relajar
están habilitados, en cuyo caso el núcleo simplemente utiliza
el valor por defecto para esa protección en particular. Por ejemplo,
is ni P ni p están habilitados para un objeto, entonces el núcleo
no forzará PAGEEXEC en SOFTMODE y lo forzará en no SOFTMODE.
Actualmente, los parches PaX ofrecen tres formas de realizar
marcados PaX: EI_PAX, PT_PAX y XATTR_PAX. EI_PAX coloca los ajustes
PaX en los bytes 14 y 15 del campo e_ident de la cabecera de un
objeto ELF. Sin embargo, esto no funciona así en las versiones
recientes de glibc y ya no se ofrece soporte. Mire la
incidencia #365825.
PT_PAX coloca los ajustes en una cabecera de programa del objeto
ELF llamada PAX_FLAGS. Esto tiene como ventaja que los ajustes
están en el cuerpo del objeto y siempre se conservarán cuando
se copie el mismo. Sin embargo, tiene la desventaja de que
el objeto deberá tener la cabecera de programa PAX_FLAGS para que
funcione. La mayoría de distribuciones Linux no construyen
los ejecutables y librerías con esta cabecera de y el hecho de
añadirlo da problemas: no hay suficiente espacio en el objeto
ELF para añadirlo o, si se convierte a una cabecera de programa
GNU_STACK, que no es utilizada por el núcleo PaX, puede causar
problemas posteriormente bajo otros núcleos si el objeto se
exporta. En el peor de los casos, cambiar el binario ELF romperá
los ejecutables que se autocomprueban ya que comprobarán que han
sido "modificados". Mire la
incidencia
#100507.
Aunque todavía se ofrece soporte para PT_PAX, la forma preferida
es utilizar XATTR_PAX que localiza los ajustes PaX en los atributos
extendidos del sistema de ficheros. Esto tiene la ventaja de que no
modifica el objeto ELF de ninguna forma, sin embargo, tiene la
desventaja de que el sistema de ficheros que aloje estos objetos,
y las utilidades que se empleen para copiarlos, moverlos y
archivarlos, deben ofrecer soporte para atributos extendidos (xattrs).
En el caso de Gentoo y portage, esto significa que tmpfs debe dar
soporte al espacio de nombres xattr de usuario user.pax.* en el cual
se localizan los ajustes PaX, no solo los espacios de nombres
security.* y trusted.* (Nota: user.pax.* es el subespacio
de user.* que se utilizará para la información xattr relacionada
con PaX. No habilitamos completamente el espacio de usuario
user.* en tmpfs para reducir el riesgo de vectores de ataque
enfocados a esa ruta).
Un apunte final sobre los dos métodos soportados para realizar marcados
PaX: el núcleo PaX le permite habilitar tanto PT_PAX como XATTR_PAX,
pero si lo hace, no impondrá los marcados a menos que los mismos
ajustes se hallen en ambas localizaciones. Por esta razón, no
recomendamos habilitar ambos, incluso para la migración que se
describe más abajo.
4.
Construir un núcleo PaX
El equipo Gentoo Hardened mantiene y ofrece soporte para el paquete
hardened-sources, que comentaremos aquí. Otros paquetes del
árbol del núcleo pueden ofrecer PaX, y mucho de lo que se comente
aquí se podrá aplicar a ellos. Sin embargo, tendrá que estudiar
esas diferencias, nosotros no las comentaremos. El paquete
hardened-sources incluye los parches Grsecurity
(http://grsecurity.net/), que incluyen a su vez a los
parches PaX. Si únicamente quiere los parches PaX, los puede obtener
de forma aislada desde http://www.grsecurity.net/~paxguy1/.
Si está interesado en aprender más sobre el reforzado con Grsecurity
en general, lo cubriremos en nuestro
Guía rápida de Grsecurity.
Al hacer emerge del núcleo hardened-sources, el árbol de los fuentes
se localiza en /usr/src, pero no están configurados. Será entonces
el momento de asegurarse de que PaX está configurado de modo que
refuerce o relaje lo que desee. Abajo no concentraremos en las
configuraciones recomendadas, pero si lo desea modifíquelas. La
sección anterior debería haberle dado alguna idea de cada una
de las opciones que se ofrecen para que así pueda elegir las opciones
acertadas. Le recomendamos comenzar con una configuración muy
reforzada y relajar solo cuando no se puede encontrar otra salida.
Como ya se ha comentado, los parches PaX están incluidos en Grsecurity,
por lo que las opciones de configuración de PaX se encuentran bajo
Security Options -> Grsecurity -> Customize Configuration ->
PaX. Tiene también la opción de seleccionar uno de los perfiles
preconfigurados de Grsecurity en
Security Options -> Grsecurity -> Configuration Method.
Éstos le ofrecerán un punto de partida con sentido para la
configuración de PaX.
Si está realizando la configuración únicamente para PT_PAX, lo que
sigue debería ser suficiente. Observe que debido a que estamos
intentando mostrar las opciones de configuración tanto para
x86 como para amd64, hemos marcado estas diferencias con un
símbolo > en la columna que está más a la izquierda.
Listado de Código 4.1: Configuración del núcleo para PT_PAX |
[*] Enable various PaX features
PaX Control ->
[ ] Support soft mode
[ ] Use legacy ELF header marking
[*] Use ELF program header marking
[ ] Use filesystem extended attributes marking
MAC system integration (none) --->
Non-executable page ->
[*] Enforce non-executable pages
[*] Paging based non-executable pages
[*] Segmentation based non-executable pages <--- No está disponible para amd64.
[*] Emulate trampolines
[*] Restrict mprotect()
[ ] Use legacy/compat protection demoting (read help)
[ ] Allow ELF text relocations (read help)
[*] Enforce non-executable kernel pages
Return Address Instrumentation Method (or) ---> <--- No está disponible para x86.
(4) Minimum amount of memory reserved for module code <--- No está disponible para amd64.
Address Space Layout Randomization ->
[*] Address Space Layout Randomization
[*] Randomize kernel stack base
[*] Randomize user stack base
[*] Randomize mmap() base
Miscellaneous hardening features --->
[*] Sanitize all freed memory
[*] Sanitize kernel stack
[*] Prevent invalid userland pointer dereference
[*] Prevent various kernel object reference counter overflows
[*] Harden heap object copies between kernel and userland
[*] Prevent various integer overflows in function size parameters
[*] Generate some entropy during boot
|
Preferentemente, deberíamos optar por los ajustes XATTR_PAX. En
este caso, toda la información de arriba podría incluirse tal y
como está, sin embargo, podríamos también cambiar la configuración
de control de PaX:
Listado de Código 4.2: Configuración del núcleo con ajustes XATTR_PAX |
PaX Control ->
[ ] Support soft mode
[ ] Use legacy ELF header marking
[ ] Use ELF program header marking
[*] Use filesystem extended attributes marking
MAC system integration (none) --->
|
Debido a que los ajustes PaX residen ahora en los atributos extendidos
de su sistema de ficheros, deberemos habilitar xattr en esos sistemas
de ficheros. El equipo de PaX ya ha definido una dependencia. Por
ejemplo, para Ext4 tenemos:
Listado de Código 4.3: Selección automática de EXT4_FS_XATTR mediante XATTR_PAX_FLAGS |
File systems --->
<*> The Extended 4 (ext4) filesystem
-*- Ext4 extended attributes
[ ] Ext4 POSIX Access Control Lists
[ ] Ext4 Security Labels
[ ] EXT4 debugging support
|
Aquí los atributos extendidos de Ext4 se han seleccionado
automáticamente por PAX_XATTR_PAX_FLAGS [=y] &&
GRKERNSEC [=y] && PAX [=y] && EXT4_FS [=y].
Ni que decir tiene que, en caso de que esté utilizando un sistema
de ficheros que no tiene esta dependencia en la selección, deberá
comprobar que la selección se realiza, y si no es así, abrir un
informe de incidencia para que su sistema de ficheros tenga mejor
soporte en lo que se refiere a PaX.
5.
Control de PaX
Como hemos mencionado más arriba, existen cinco protecciones PaX
que pueden ser activada (en SOFTMODE) or relajadas (en no SOFTMODE)
para cada objeto ELF: PAGEEXEC, EMULTRAP, MPROTECT, RANDMMAP y
SEGMEXEC. La última, SEGMEXEC, está disponible únicamente en las
CPUs x86 que ofrecen soporte para segmentación, al contrario que
la paginación que está soportada por todas las CPUs, incluso las
x86. Debido a que algunos programas se rompen por alguna u otra
razón bajo un reforzado PaX completo, tenemos que enfrentarnos
con las alternativas: bien corregir el código para que funcione
con PaX, bien relajar una o más de estas protecciones. En la
praćtica, "corregir el código" puede resultar muy difícil y por
tanto nos decantaremos por la segunda alternativa. El enfoque
general debería consistir en intentar el reforzado completo y,
en caso de que algo se rompa, utilizar dmesg para obtener un
informe del núcleo indicando el porqué y a continuación relajar
esa protección en particular. Esto puede no ser necesario
en un sistema Gentoo debido a que los ebuilds deberían definir
correctamente los ajustes a través de pax-util.eclass. Si
necesita definir sus propios ajustes, le pedimos que informe
de una incidencia.
En general, la definición de los ajustes PaX es sencilla, sin
embargo, el usuario debería tener en cuenta algunas cosas:
1) Uno puede definir los ajustes PT_PAX o XATTR_PAX en un objeto
ELF independientemente de otro objeto. De forma similar, el núcleo
se puede configurar para leer uno, los dos o ninguno de estos
campos. Es su decisión asegurarse de que define los ajustes en el
campo que está utilizando el núcleo para obtener los resultados
deseados. Por ejemplo, si tiene PT_PAX="Pe---" y XATTR_PAX no
está presente en el objeto, pero el núcleo está configurado
para utilizar únicamente XATTR_PAX, ¡podría obtener un resultado
no deseado!
2) El enfoque recomendado es marcar los campos PT_PAX y XATTR_PAX
de forma idéntica en los objetos siempre que sea posible y ajustar
el núcleo para que lea únicamente XATTR_PAX. El paso "siempre que
sea posible" es el paso en el que las cosas se ponen complicadas
y los dos campos puede que no contengan los mismos ajustes. Si
el objeto ELF no contiene una cabecera de programa PAX_FLAGS, el
marcado PT_PAX fallará. Sin embargo, la ausencia de esta cabecera
de programa no afectará a las marcas XATTR_PAX. Si el ELF
está ocupado (esto es, hay un proceso corriendo que utilizar el
texto del ELF), entonces se puede leer los ajustes PT_PAX pero no
definirlos. De nuevo, esto no afectar definir u obtener los ajustes
XATTR_PAX. Por el contrario, si está utilizando sistemas de ficheros
que no ofrecen soporte para atributos extendidos, entonces el
marcado XATTR_PAX fallará en los sistemas de ficheros mientras que
el marcado PT_PAX no se verá afectado, excepto en la situación
ya comentada. Esto puede ser muy sutil ya que, copiar un fichero
desde un sistema de ficheros con xattrs a otro que no los tiene
y volver a copiarlos a su origen hará que se pierdan los ajustes
XATTR_PAX. O empaquetar con una versión antigua de tar que
no conserva los xattrs hará que también perdamos nuestros
ajustes.
3) Los ajustes PaX únicamente son reforzados cuando un proceso se
carga desde un ejecutable ELF. Este ejecutable normalmente enlaza
dinámicamente contra objetos compartidos en memoria. El uso
de `cat /proc/<pid>/status | grep PaX` le ofrece el
reforzamiento resultante del proceso que está corriendo con
PID=<pid>. Pero, ya que el ejecutable y los objetos
compartidos tienen ajustes diferentes, la pregunta surge,
¿Cuáles de ellos se utilizan para determinar los reforzamientos
finales de PaX?. La respuesta es que se utiliza el ejecutable
por razones de control y seguridad. Si las librerías fueran
a definir el reforzado de PaX en tiempo de ejecución, entonces
¿Cuál de las librerías "ganarían" si un ejecutable está enlazado
con todas ellas?. Además una librería demasiado relajada podría
hacer que los privilegios sobre los muchos ejecutables que
enlazan a ella también se relajaran. Por ejemplo, relajar
todas las protecciones sobre glibc implicaría que PaX se
desactivara en el sistema. Por supuesto, es el código de
la propia librería el que necesita la relajación de algún
reforzamiento PaX. En este caso uno tiene que "portar hacia
atrás" los ajustes de la librería al ejecutable que los utiliza.
Abajo, describimos las utilidades ofrecidas en un sistema Gentoo
para trabajar con marcados PaX. Existen varios ya que mientras
PaX evolucionaba, se necesitaban nuevas características. Cada
una hace hincapié en una necesidad diferente con respecto a las
cuestiones planteadas arriba.
1. paxctl
Este es el paquete tradicional para la definición de ajustes
PaX. Está limitado únicamente en el hecho en que solo define
PT_PAX, no XATTR_PAX. Se ofrece mediante el paquete
sys-apps/paxctl. Tiene una funcionalidad que ninguna otra
utilidad posee: puede crear una cabecera de programa
PAX_FLAGS o convertir una GNU_STACK a PAX_FLAGS. Ambos no
se recomiendan ya que pueden romper ELF bajo ciertas
circunstancias. Sin embargo, en el caso extremo en que no
pueda utilizar XATTR_PAX (por ejemplo, no puede utilizar
el sistema de ficheros que soporta los atributos extendidos)
y esté tratando con un objeto ELF que no se construyó con
una cabecera de programa PAX_FLAGS, entonces estas opciones
están disponibles a través de esta utilidad.
A continuación se muestra una sinopsis del su utilización:
Listado de Código 5.1: paxctl -h |
PaX control v0.7
Copyright 2004,2005,2006,2007,2009,2010,2011,2012 PaX Team <pageexec@freemail.hu>
usage: paxctl <options> <files>
options:
-p: disable PAGEEXEC -P: enable PAGEEXEC
-e: disable EMUTRAMP -E: enable EMUTRAMP
-m: disable MPROTECT -M: enable MPROTECT
-r: disable RANDMMAP -R: enable RANDMMAP
-x: disable RANDEXEC -X: enable RANDEXEC
-s: disable SEGMEXEC -S: enable SEGMEXEC
-v: view flags -z: restore default flags
-q: suppress error messages -Q: report flags in short format
-c: convert PT_GNU_STACK into PT_PAX_FLAGS (see manpage!)
-C: create PT_PAX_FLAGS (see manpage!)
|
Observe que paxctl también informa de la antigua protección PaX
llamada RANDEXEC. Esta opción ya no se utiliza. La aleatorización
de la dirección base de un proceso ahora es parte de ASLR en
todos los ejecutables que se construyen con ET_DYN en lugar
de EX_EXEC. Aquí se muestra a paxctl en acción:
Listado de Código 5.2: paxctl en acción |
# paxctl -v /usr/bin/python3.2
PaX control v0.7
Copyright 2004,2005,2006,2007,2009,2010,2011,2012 PaX Team <pageexec@freemail.hu>
- PaX flags: -----m-x-e-- [/usr/bin/python3.2]
MPROTECT is disabled
RANDEXEC is disabled
EMUTRAMP is disabled
# paxctl -P /usr/bin/python3.2
# paxctl -v /usr/bin/python3.2
PaX control v0.7
Copyright 2004,2005,2006,2007,2009,2010,2011,2012 PaX Team <pageexec@freemail.hu>
- PaX flags: P----m-x-e-- [/usr/bin/python3.2]
PAGEEXEC is enabled <--- Nota: Esto se añade a ajustes anteriores, no los sobreescribe.
MPROTECT is disabled
RANDEXEC is disabled
EMUTRAMP is disabled
|
2. getfattr setfattr
No hay utilidades específicas PaX sino utilidades generales
para definir los atributos extendidos de un fichero. En Gentoo
se ofrecen haciendo emerge de sys-apps/attr. Ya que XATTR_PAX
utiliza el espacio de nombres user.* namespace (específicamente
"user.pax.flags"), puede utilizar set/getfattr para trabajar
con este campo. Sin embargo, tenga en cuenta que
setfattr y getfattr no saben nada acerca de PaX, por lo que
no realizarán ninguna comprobación de seguridad sobre lo que
ponga en ese campo. Únicamente si define user.pax.flags
a alguna combinación con sentido de los caracteres
PpEeMmRr, el núcleo respetará su elección, en caso contrario,
volverá a los valores por defecto. El siguiente listado ofrece
algunos ejemplos.
Lo que sigue es un ejemplo de su uso para XATTR_PAX:
Listado de Código 5.3: setfattr y getfattr en acción |
# getfattr -n user.pax.flags /usr/bin/python3.2
getfattr: Removing leading '/' from absolute path names
# file: usr/bin/python3.2
user.pax.flags="em"
# setfattr -n user.pax.flags -v P /usr/bin/python3.2
# getfattr -n user.pax.flags /usr/bin/python3.2
getfattr: Removing leading '/' from absolute path names
# file: usr/bin/python3.2
user.pax.flags="P" <--- Nota: Esto sobreescribe los ajustes anteriores, no los añade.
# setfattr -n user.pax.flags -v "Hola Mamá." /usr/bin/python3.2
# getfattr -n user.pax.flags /usr/bin/python3.2
getfattr: Removing leading '/' from absolute path names
# file: usr/bin/python3.2
user.pax.flags="Hola Mamá." <--- Mamá lo agradece, pero PaX no. No hay comprobación de seguridad.
|
3. paxctl-ng
paxctl-ng el la nueva navaja suiza para trabajar con marcados
PT_PAX y XATTR_PAX. Se puede construir con soporte para uno, otro
o ambos tipos de marcados. Cuando se construye con soporte para
ambos, puede copiar campos PT_PAX a campos XATTRP_PAX o
viceversa, para asegurarse de que hay consistencia. En definitiva,
puede hacer todo lo que paxctl y set/getfattr pueden hacer, salvo
no intentar crear o convertir una cabecera de programa PAX_FLAGS.
Esto no se recomienda y debe emplearse solo en el caso aislado
mencionado arriba. A continuación mostramos un resumen de su
utilización:
Listado de Código 5.4: paxctl-ng -h |
Package Name : elfix 0.7.1
Bug Reports : http://bugs.gentoo.org/
Program Name : paxctl-ng
Description : Get or set pax flags on an ELF object
Usage : paxctl-ng -PpEeMmRrSsv ELF | -Zv ELF | -zv ELF
: paxctl-ng -Cv ELF | -cv ELF | -dv ELF
: paxctl-ng -Fv ELF | -fv ELF
: paxctl-ng -Lv ELF | -lv ELF
: paxctl-ng -v ELF | -h
Options : -P enable PAGEEXEC -p disable PAGEEXEC
: -E enable EMUTRAMP -e disable EMUTRAMP
: -M enable MPROTECT -m disable MPROTECT
: -R enable RANDMMAP -r disable RANDMMAP
: -S enable SEGMEXEC -s disable SEGMEXEC
: -Z all secure settings -z all default settings
:
: -C create XATTR_PAX with most secure setting
: -c create XATTR_PAX all default settings
: -F copy PT_PAX to XATTR_PAX
: -f copy XATTR_PAX to PT_PAX
: -L set only PT_PAX flags
: -l set only XATTR_PAX flags
:
: -v view the flags, along with any accompanying operation
: -h print out this help
Note : If both enabling and disabling flags are set, the default - is used
|
A continuación se muestra un ejemplo de paxctl-ng en acción:
Listado de Código 5.5: paxctl-ng en acción |
# paxctl-ng -v /usr/bin/python3.2 <--- Ver los campos PT_PAX y XATTR_PAX (-v)
/usr/bin/python3.2:
PT_PAX : Pem--
XATTR_PAX: Pem--
# paxctl-ng -lPpv /usr/bin/python3.2 <--- Definir el valor por defecto '-' para PAGEEXEC (-Pp)
/usr/bin/python3.2: <--- Solo para XATTR_FLAGS (-l)
PT_PAX : Pem-- <--- E informar del resultado (-v)
XATTR_PAX: -em--
# paxctl-ng -dv /usr/bin/python3.2 <--- Borrar todo el campo XATTR_PAX (-d)
/usr/bin/python3.2: <--- E informar del resultado (-v)
PT_PAX : Pem--
XATTR_PAX: not found
# paxctl-ng -lemv /usr/bin/python3.2 <--- Definir los ajustes "em" (-em)
/usr/bin/python3.2: <--- Solo para XATTR_FLAGS (-l)
PT_PAX : Pem-- <--- E informar del resultado (-v)
XATTR_PAX: -em--
# paxctl-ng -fv /usr/bin/python3.2 <--- Copiar los ajustes XATTR_PAX a PT_PAX, sobreescribiendo estos últimos (-f)
/usr/bin/python3.2: <--- E informar del resultado (-v)
PT_PAX : -em--
XATTR_PAX: -em--
# paxctl-ng -d /usr/bin/python3.2 <--- Borrar de forma silenciosa el campo XATTR_PAX (-d pero no -v)
# paxctl-ng -v /usr/bin/python3.2 <--- Ver los campos PT_PAX y XATTR_PAX (-v)
/usr/bin/python3.2:
PT_PAX : -em--
XATTR_PAX: not found
|
4.Módulo Python, pax.so, y una interfase simple de
Python, pypaxctl.
También ofrecemos añadidos a python a través de un módulo, pax.so,
el cual se instala haciendo emerge de dev-python/pypax. Este paquete
es una dependencia de sys-apps/elfix ya que tanto revdep-pax como
migrate-pax lo importan. Se puede compilar con soporta tanto para
PT_PAX como para XATTR_PAX o para ambos a la vez. Es similar a
paxctl-ng, per no tiene tantas características como éste, ya que
su alcance está limitado las necesidades de revdep-pax y de
migrate-pax. Esto puede cambiar en el futuro si hay necesidad
de una mejor integración entre el marcado PaX con portage, el cual
está escrito en python.
Actualmente pax.so exporta públicamente lo siguiente:
-
pax.setstrflags(str_flags):
-
Esta función definirá los ajustes PT_PAX y XATTR_PAX para
que tengan el mismo valor. Los ajustes se especifican como
una cadena de los siguientes caracteres: PpEeMmRrSs. Si,
tanto el carácter para activar como para desactivar se
indican para una protección en particular, entonces el
valor por defecto '-' se utiliza en su lugar.
-
pax.setbinflags(bin_flags):
-
Esta función es la misma que pax.setstrflags pero toma
los ajustes como un O lógico bit a bit de la representación
en binario de los ajustes. El campo PT_PAX se almacena
de esta forma, mientras que el campo XATTR_PAX se almacena
como una cadena de los caracteres PpEeMmRrSs.
-
pax.getflags(elf):
-
Esta función devuelve los ajustes PaX como una tupla
representando ambas formas (str_flags, bin_flags), esto
es, se devuelve tanto como una cadena como su representación
equivalente en binario. Si se han definido los dos PT_PAX
y XATTR_PAX, entonces los ajustes XATTR_PAX sobreescribirán
los ajustes PT_PAX.
-
pax.deletextpax(elf):
-
Esta función borrará el campo XATTR_PAX completamente. No
toca el campo PT_PAX, que no se puede eliminar (¡fácilmente!).
-
pax.PaxError:
-
Esta excepción se lanza cada vez que se produce un fallo
al obtener o se definir los ajustes, o cuando el borrado
del campo XATTR_PAX falla.
pypaxctl es una interfase simple para pax.so que simplemente
obtiene y define los valores de los ajustes de PaX utilizando
la misma lógica. Cuando se obtiene el valor de los ajustes,
si ambos PT_PAX y XATTR_PAX están presentes, el segundo tendrá
prioridad sobre el primero. Cuando se define el valor, se
definirán ambos campos siempre que sea posible. Aquí lo
vemos en acción:
Listado de Código 5.6: pypaxctl en acción con PT_PAX y XATTR_PAX |
# pypaxctl -g /usr/bin/python3.2 <--- Recuperar tanto PT_PAX como XATTR_PAX. El segundo tiene prioridad si está definido.
-em-- <--- La orden canónica es PEMRS.
# paxctl-ng -v /usr/bin/python3.2 <--- Resulta que XATTR_PAX no existe, por lo que obtenemos PT_PAX.
/usr/bin/python3.2:
PT_PAX: -em--
XT_PAX: not found
# paxctl-ng -lPMEv /usr/bin/python3.2 <--- Definir algunos ajustes XATTR_PAX.
/usr/bin/python3.2:
PT_PAX: -em--
XT_PAX: PEM--
# pypaxctl -g /usr/bin/python3.2 <--- ¡Ahora está mostrando los ajustes XATTR_PAX!
PEM--
# pypaxctl -s me /usr/bin/python3.2 <--- Definir "me" para PT_PAX y XATTR_PAX
# paxctl-ng -v /usr/bin/python3.2
/usr/bin/python3.2:
PT_PAX: -em-- <--- Al igual que paxctl y paxctl-ng, no sobreescribimos los ajustes, solo los añadimos.
XT_PAX: Pem--
# pypaxctl -s Pp /usr/bin/python3.2 <--- Pero, ¿Qué ocurre si queremos desactivar PAGEEXEC? Entonces definimos Pp al valor por defecto '-'.
# paxctl-ng -v /usr/bin/python3.2
/usr/bin/python3.2:
PT_PAX: -em--
XT_PAX: -em--
|
Si no desea que la lógica de XATTR_PAX tenga precedencia
sobre PT_PAX, is not what you want, se puede compilar
con soporte PT_PAX xor XATTR_PAX. En este caso, el otro
campo nunca se modifica, tal y como se muestra abajo:
Listado de Código 5.7: pypaxctl en acción con solo PT_PAX |
# paxctl-ng -v /usr/bin/python3.2
/usr/bin/python3.2:
PT_PAX: -em--
XT_PAX: PEM--
# pypaxctl -g /usr/bin/python3.2
-em--
# pypaxctl -s p /usr/bin/python3.2
# paxctl-ng -v /usr/bin/python3.2
/usr/bin/python3.2:
PT_PAX: pem--
XT_PAX: PEM--
# pypaxctl -s PpEem /usr/bin/python3.2
# paxctl-ng -v /usr/bin/python3.2
/usr/bin/python3.2:
PT_PAX: --m--
XT_PAX: PEM--
|
5. revdep-pax
Esta utilidad se emplea para mapear los enlaces entre
todos los objetos ELF en su sistema con sus objetos
compartidos en ambas direcciones. Se puede entonces
buscar marcados de ajustes PaX que no corresponden entre
los objetos compartidos y los ejecutables y, opcionalmente,
se permite al usuario migrar los marcados hacia delante o
hacia atrás para cada objeto ELF. Aquí tenemos un resumen
de su utilización:
Listado de Código 5.8: revdep-pax -h |
Package Name : elfix
Bug Reports : http://bugs.gentoo.org/
Program Name : revdep-pax
Description : Get or set pax flags on an ELF object
Usage : revdep-pax -f [-v] print out all forward mappings for all system binaries
: revdep-pax -r [-ve] print out all reverse mappings for all system sonames
: revdep-pax -b OBJECT [-myv] print all forward mappings only for OBJECT
: revdep-pax -s SONAME [-myve] print all reverse mappings only for SONAME
: revdep-pax -l LIBRARY [-myve] print all reverse mappings only for LIBRARY file
: revdep-pax [-h] print out this help
: -v verbose, otherwise just print mismatching objects
: -e only print out executables in shell $PATH
: -m don't just report, but mark the mismatching objects
: -y assume "yes" to all prompts for marking (USE CAREFULLY!)
|
Aquí tenemos a revdep-pax en acción. Debido a que la salida
es larga, la hemos acortado con algunos puntos suspensivos:
Listado de Código 5.9: revdep-pax en acción |
# revdep-pax -f < --- Informar de todos los enlaces hacia delante que no concuerden.
.....
/usr/bin/python3.2 ( --m-- )
libpython3.2.so.1.0 /usr/lib64/libpython3.2.so.1.0 ( -e--- )
libpthread.so.0 /lib64/libpthread-2.16.so ( -e--- )
libc.so.6 /lib64/libc-2.16.so ( -e--- )
libdl.so.2 /lib64/libdl-2.16.so ( -e--- )
libutil.so.1 /lib64/libutil-2.16.so ( -e--- )
libm.so.6 /lib64/libm-2.16.so ( -e--- )
.....
# revdep-pax -m -b /usr/bin/python3.2 < --- Portar los ajustes PaX únicamente para python3.2.
/usr/bin/python3.2 (--m--)
libpython3.2.so.1.0 /usr/lib64/libpython3.2.so.1.0 ( -e--- )
libpthread.so.0 /lib64/libpthread-2.16.so ( -e--- )
libc.so.6 /lib64/libc-2.16.so ( -e--- )
libdl.so.2 /lib64/libdl-2.16.so ( -e--- )
libutil.so.1 /lib64/libutil-2.16.so ( -e--- )
libm.so.6 /lib64/libm-2.16.so ( -e--- )
Will mark libraries with --m--
Set flags for /usr/lib64/libpython3.2.so.1.0 (y/n): n < --- Se solicitará confirmación a no ser que se emplee -y.
Set flags for /lib64/libpthread-2.16.so (y/n): n < --- Contestaremos 'n' a cada pregunta de esta demostración.
Set flags for /lib64/libc-2.16.so (y/n): n
Set flags for /lib64/libdl-2.16.so (y/n): n
Set flags for /lib64/libutil-2.16.so (y/n): n
Set flags for /lib64/libm-2.16.so (y/n): n
# revdep-pax -r < --- Informar de todos los enlaces hacia atrás que no concuerden.
.....
libpython3.2.so.1.0 /usr/lib64/libpython3.2.so.1.0 ( -e--- ) < --- El formato es soname /camino/a/su/objeto_elf (ajustes).
/usr/bin/python3.2 ( --m-- ) < --- Aquí tenemos algo que no concuerda, tal y como esperábamos
..... en el paso anterior.
# revdep-pax -m -s libpython3.2.so.1.0 < --- Migraremos desde los ajustes de la librería al ejecutable
libpython3.2.so.1.0 /usr/lib64/libpython3.2.so.1.0 (-e---) utilizando el soname (-s). Podríamos también haber
utilizado /usr/lib64/libpython3.2.so.1.0 con el ajuste -l.
/usr/bin/python3.2 ( --m-- )
Will mark binaries with -e---
Set flags for /usr/bin/python3.2 (y/n): y < --- Confirmar 'y' que queremos hacer esto.
/usr/bin/python3.2 ( -em-- )
# paxctl-ng -v /usr/bin/python3.2 < --- Comprobar de nuevo.
/usr/bin/python3.2:
PT_PAX: -em--
XT_PAX: -em--
|
6. migrate-pax
Llegados a este punto, probablemente estará harto de tanta gestión
de los campos PT_PAX y XATTR_PAX su relación con la configuración
del núcleo, y simplemente quiera eliminar los antiguos PT_PAX y
¡Continuar con su vida!. La herramienta migrate-pax hace exactamente
eso. Recorrerá todos los objetos ELF en su sistema y migrará el
campo PT_PAX a XATTR_PAX. Para obtener más detalles sobre cómo
migrar, lea nuestra guía
Migración de los ajustes PaX desde PT_PAX a XATTR_PAX .
Listado de Código 5.10: migrate-pax -h |
Package Name : elfix
Bug Reports : http://bugs.gentoo.org/
Program Name : migrate
Description : Migrate PT_PAX to XATTR_PAX Flags on all system ELF objects
Usage : migrate -v print out all system ELF objects
: migrate -m [-v] migrate flags on all system ELF objects
: migrate -d [-v] delete XATTR_PAX on all system ELF objects
: migrate [-h] print out this help
: -v be verbose when migrating
|
El contenido de este documento, a no ser que se especifique
expresamente, está registrado bajo los términos de la licencia
CC-BY-SA-2.5. Se aplican las
Pautas de
Utilización del logotipo y nombre de Gentoo.
|
|