Product Description Files
HP-UX (tanto en su versión Trusted como en la habitual) posee un interesante mecanismo que nos permite verificar si ciertos ficheros han sido o no modificados: se trata de PDF (aquí no significa Portable Document Format sino Product Description File), que no es más que un repositorio de información acerca de todos y cada uno de los archivos que un determinado fileset instala en una máquina. Aunque el uso de los PDFs está desfasado desde la versión 10.20 del operativo (ha sido sustituido por el Software Distributor), la información que contienen es bastante interesante desde el punto de vista de la seguridad, ya que incluye características como el grupo, el propietario, los permisos, el tamaño o un checksum de cada archivo.
En el directorio /system/ de un sistema HP-UX encontramos un subdirectorio por cada fileset instalado en la máquina; dentro de cada uno de estos subdirectorios existe - o ha de existir - un fichero denominado pdf, que contiene justamente la información de la que estamos hablando:
marta:/system/UX-CORE# pwd
/system/UX-CORE
marta:/system/UX-CORE# ls -l pdf
-r--r--r-- 1 bin bin 36199 Jan 10 1995 pdf
marta:/system/UX-CORE# head pdf
% Product Description File
% UX-CORE fileset, Release 9.05
/bin/alias:bin:bin:-r-xr-xr-x:160:1:70.2:4285122165:
/bin/basename:bin:bin:-r-xr-xr-x:16384:1:70.5:3822935702:
/bin/bg:bin:bin:-r-xr-xr-x:151:1:70.2:735613650:
/bin/cat:bin:bin:-r-xr-xr-x:16384:1:70.2:1679699346:
/bin/cd:bin:bin:-r-xr-xr-x:151:1:70.2:525751009:
/bin/chgrp:bin:bin:-r-xr-xr-x:20480:1:70.2:203825783:
/bin/chmod:bin:bin:-r-xr-xr-x:24576:1:70.6:1826477440:
/bin/chown:bin:bin:-r-xr-xr-x:20480:1:70.2:1796648176:
marta:/system/UX-CORE#
Como vemos, cada línea de este fichero (excepto las que comienzan con el carácter `%') es la entrada correspondiente a un cierto archivo que el fileset instala en la máquina; su formato es el siguiente:
- pathname: Ruta absoluta del fichero.
owner: Propietario (nombre o UID) del archivo.
group: Grupo (nombre o GID) al que pertenece.
mode: Tipo y permisos (en formato `ls -l').
size: Tamaño del fichero en bytes.
links: Número total de enlaces en el filesystem.
version: Versión del archivo.
checksum: Comprobación de errores según el algoritmo IEEE 802.3 CRC.
linked_to: Nombres adicionales del fichero (enlaces duros o simbólicos).
Para comprobar que los archivos de un determinado fileset no han sufrido modificaciones que afecten a alguno de los campos anteriores podemos programar un sencillo shellscript que utilizando la salida de órdenes como `ls -l', `what', `ident' o `cksum' compruebe el resultado de las mismas con la información almacenada en el PDF correspondiente:
marta:/# grep ^/bin/cat /system/UX-CORE/pdf
/bin/cat:bin:bin:-r-xr-xr-x:16384:1:70.2:1679699346:
marta:/# ls -l /bin/cat
-r-xr-xr-x 1 bin bin 16384 Jan 10 1995 /bin/cat
marta:/# what /bin/cat
/bin/cat:
$Revision: 70.2 $
marta:/# cksum /bin/cat
1679699346 16384 /bin/cat
marta:/#
De la misma forma, podemos ejecutar la orden `pdfck', que nos informará de cualquier cambio detectado en los ficheros de un fileset:
marta:/# pdfck /system/UX-CORE/pdf
/etc/eisa/HWP0C70.CFG: deleted
/etc/eisa/HWP0C80.CFG: deleted
/etc/eisa/HWP1850.CFG: deleted
/etc/eisa/HWP2051.CFG: deleted
/etc/eisa/HWPC000.CFG: deleted
/etc/eisa/HWPC010.CFG: deleted
/etc/eisa/HWPC051.CFG: deleted
/etc/newconfig/905RelNotes/hpuxsystem: deleted
/etc/newconfig/inittab: size(848 -> 952), checksum(214913737 -> 2198533832)
/usr/lib/nls/POSIX: owner(bin -> root), group(bin -> sys)
marta:/#
La aproximación a los verificadores de integridad que ofrece HP-UX es interesante, pero tiene también importantes carencias; en primer lugar, los algoritmos de CRC están pensados para realizar una comprobación de errores pura, especialmente en el tránsito de datos a través de una red (de hecho, el utilizado por los PDFs es el mismo que el definido por el estándar IEEE 802.3 para redes Ethernet), no para detectar cambios en el contenido de un archivo. Así, es factible - y no difícil - que un atacante consiga modificar sustancialmente un fichero sin afectar a su CRC global, con lo cual este hecho no sería detectado; si realmente queremos verificar que dos archivos son iguales hemos de recurrir a funciones hash como MD5. Por si esto fuera poco, pdfck es incapaz de detectar la presencia de nuevos ficheros en un directorio, con lo que algo tan simple como la aparición de un archivo setuidado en el sistema no sería notificado por esta utilidad; incluso ciertos cambios sobre los archivos de los cuales sí tiene constancia pasan desapercibidos para ella, como la modificación de listas de control de acceso en los ficheros:
marta:/# lsacl /bin/ps
(bin.%,r-x)(%.sys,r-x)(%.%,r-x) /bin/ps
marta:/# chacl "toni.users+rwx" /bin/ps
marta:/# lsacl /bin/ps
(toni.users,rwx)(bin.%,r-x)(%.sys,r-x)(%.%,r-x) /bin/ps
marta:/#
Como vemos, la orden anterior está otorgando a un usuario un control total sobre el archivo /bin/ps, con todo lo que esto implica; evidentemente, si esto lo ha realizado un atacante, estamos ante una violación muy grave de nuestra seguridad. Sin embargo, pdfck ejecutado sobre el PDF correspondiente no reportaría ninguna anomalía, con lo que la intrusió pasaría completamente desapercibida para el administrador.
A la vista de estos problemas, parece evidente que si necesitamos un verificador de integridad `de verdad' no podemos limitarnos a utilizar las facilidades proporcionadas por los PDFs de HP-UX; no obstante, ya que este mecanismo viene `de serie' con el sistema, no está de más usarlo, pero sin basarnos ciegamente en sus resultados. Siempre hemos de tener en cuenta que la información de cada fichero registrada en los archivos /systempdf se almacena igual que se está almacenando el propio archivo, en un cierto directorio de la máquina donde evidentemente el administrador puede escribir sin poblemas. Por tanto, a nadie se le escapa que si un atacante consigue el privilegio suficiente para modificar una herramienta de base (por ejemplo, /bin/ls) y troyanizarla, no tendrá muchos problemas en modificar también el archivo donde se ha guardado la información asociada a la misma, de forma que limitándonos a comparar ambas no nos daremos cuenta de la intrusión. Así, es una buena idea guardar, nada más instalar el sistema, una copia del directorio /system/, donde están los PDFs, en una unidad de sólo lectura; cuando lleguemos al tema dedicado a la detección de intrusos hablaremos con más detalle de los verificadores de integridad y la importancia de esa primera copia, sobre un sistema limpio, de toda la información que posteriormente vamos a verificar.
inetd.sec(4)
Desde hace más de diez años, HP-UX incorpora en todas sus releases un mecanismo de control de acceso a los servicios que el sistema ofrece a través de inetd; se trata de un esquema muy similar al ofrecido por TCP Wrappers, esto es, basado en la dirección IP de la máquina o red solicitante del servicio, y procesado antes de ejecutar el demonio que va a servir la petición correspondiente. De esta forma, se establece un nivel de seguridad adicional al ofrecido por cada uno de estos demonios.
Evidentemente, este esquema basa su configuración en un determinado archivo; el equivalente ahora a los ficheros /etc/hosts.allow y /etc/hosts.deny de TCP Wrappers es /usr/adm/inetd.sec (si no existe, el sistema funciona de la forma habitual, sin ningún nivel de protección adicional). El formato de cada línea del mismo es muy simple:
servicio allowdeny direccion
La directiva `servicio' indica el nombre del servicio a proteger tal y como aparece en el archivo /etc/services (esto es una diferencia con respecto a TCP Wrappers, que se guía por el nombre concreto del demonio y no por el del servicio); `allow' o `deny' (opcionales, si no se indica este campo se asume un `allow') definen si vamos a permitir o denegar el acceso, respectivamente, y por último en el campo `direccion' podemos indicar (también es un campo opcional) la dirección IP de uno o más hosts o redes, así como los nombres de los mismos. Si para un mismo servicio existe más de una entrada, sólo se aplica la última de ellas; aunque a primera vista esto nos pueda parecer una limitación importante, no lo es: si definimos una entrada `allow', a todos los sistemas no contemplados en ella se les negará el acceso, si definimos una `deny' se le permitirá a todo el mundo excepto a los explícitamente indicados, y si para un servicio no existe una entrada en el fichero, no se establece ningún tipo de control.
Imaginemos que el contenido de /usr/adm/inetd.sec es el siguiente:
marta:/# grep -v ^\# /usr/adm/inetd.sec
finger allow localhost 158.42.*
ssh allow localhost 158.42.* 192.168.0.*
pop allow
marta:/#
En este caso lo que estamos haciendo es permitir el acceso al servicio finger a todas las máquinas cuya dirección comience por 158.42., así como a la máquina local, y negarlo al resto, permitir acceso a ssh además de a estas a las que tengan una dirección 192.169.0., y dejar que cualquier sistema (no definimos el tercer campo) pueda consultar nuestro servicio POP3 (la entrada mostrada sería equivalente a un indicar únicamente el nombre del servicio, o a no definir una entrada para el mismo). Así, en el momento que un sistema trate de acceder a un servicio para el que no tiene autorización obtendrá una respuesta similar a la ofrecida por TCP Wrappers (esto es, el cierre de la conexión):
luisa:~# telnet 158.42.2.1 79
Trying 158.42.2.1...
Connected to 158.42.2.1.
Escape character is '^]'.
Connection closed by foreign host.
luisa:~#
Como vemos, se trata de un mecanismo sencillo que, aunque no ofrezca el mismo nivel de protección que un buen cortafuegos (nos podemos fijar que la conexión se establece y luego se corta, en lugar de denegarse directamente como haría un firewall), y aunque no sea tan parametrizable - ni conocido - como TCP Wrappers, puede ahorrar más de un problema a los administradores de una máquina HP-UX; y ya que existe, no cuesta nada utilizarlo junto a cualquier otra medida de seguridad adicional que se nos ocurra (recordemos que en el mundo de la seguridad hay muy pocos mecanismos excluyentes, casi todos son complementarios). Para obtener más información acerca de este, podemos consultar la página de manual de inetd.sec(4).