Información de Seguridad en FreeBSD
Introducción
El objetivo de esta página es orientar a los usuarios, tanto noveles como
experimentados, en el área de seguridad del Sistema Operativo FreeBSD. El equipo de
Desarrollo de FreeBSD se toma la seguridad muy en serio y trabaja constantemente para
hacer el Sistema Operativo tan seguro como sea posible.
Aquí podrás encontrar información adicional, o enlaces a información, acerca de cómo
proteger tu sistema contra varios tipos de ataque del exterior, con quién contactar si
encuentra un error de software relacionado con la seguridad, etc. También hay una sección
que trata de las distintas formas en que el programador de sistemas puede concienciarse
acerca de la seguridad, de modo que sea menos probable la introducción de defectos de
seguridad en el software.
Contenidos
El FreeBSD Security Officer
Con el objetivo de coordinar mejor el intercambio de información con otras personas o
entidades relacionadas con el ámbito de la seguridad, FreeBSD tiene un punto focal para
las comunicaciones relacionadas con la seguridad: el FreeBSD security officer. El puesto está
actualmente ocupado por un equipo de security officers dedicados, siendo sus tareas
principales emitir advisories cuando hay defectos de seguridad conocidos y actuar ante
los informes de posibles problemas de seguridad con FreeBSD.
Si necesitas contactar con alguien del equipo de FreeBSD acerca de un posible error de
software relacionado con la seguridad por favor hazlo por correo al Security Officer, incluyendo una
descripción de lo que has encontrado y el tipo de vulnerabilidad que representa. El
Security Officer también está en contacto con los diferentes equipos CERT y FIRST en todo
el mundo, con los que comparte información acerca de posibles vulnerabilidades en FreeBSD
o programas de utilidad usados por FreeBSD. Los Security Officers también son miembros
activos de dichas organizaciones.
Si necesitas contactar con el Security Officer acera de algún asunto especialmente
delicado, usa su clave
PGP para encriptar el mensaje antes de enviarlo.
FreeBSD Security Advisories
Los FreeBSD Security Officers proporcionan security advisories para las releases de
FreeBSD siguientes:
- La release oficial de FreeBSD más reciente.
- FreeBSD-current.
- FreeBSD-stable, cuando hay al menos 2 releases basadas en él.
- FreeBSD-stable anterior cuando un "nuevo stable" aun no tiene 2 releases basadas en
él.
En este momento hay disponibles security advisories para:
- FreeBSD 2.2.8
- FreeBSD 3.1
- FreeBSD 3.2
- FreeBSD-current
- FreeBSD-stable
No hay mantenimiento para releases anteriores a estas. Se recomienda a los usuarios se
actualicen a una de las releases arriba mencionadas.
Como todos los esfuerzos de desarrollo, las reparaciones de seguridad se incorporan
primero en la rama FreeBSD-current. Después de un par de
días de prueba la reparación se incorpora en las ramas FreeBSD-stable soportadas y se
emite un advisory.
Los advisories se envían a las siguientes listas de distribución de FreeBSD:
- FreeBSD-security-notifications@FreeBSD.org
- FreeBSD-security@FreeBSD.org
- FreeBSD-announce@FreeBSD.org
Los advisories se firman siempre usando la clave PGP del FreeBSD
Security Officer y se archivan, junto con los patches asociados, en nuestro repositorio FTP CERT. En el
momento de escribir esto están disponibles los advisories siguientes:
Información acerca de las Listas de Distribución sobre Seguridad en FreeBSD
Si eres administrador o usuario de uno o más sistemas FreeBSD, quizás quieras
suscribirte a alguna de las listas siguientes:
FreeBSD-security Discusiones relacionadas con la seguridad en general
FreeBSD-security-notifications Notificaciones sobre seguridad (lista moderada)
Envíe un mensaje a
majordomo@FreeBSD.ORG con
subscribe <nombre_de_la_lista> [<dirección_email_opcional>]
en el cuerpo del mensaje para suscribirse. Por ejemplo:
% echo "subscribe FreeBSD-security" | mail majordomo@FreeBSD.org
y si quieres desuscribirte de una lista de distribución:
% echo "unsubscribe FreeBSD-security" | mail majordomo@FreeBSD.org
Pautas para la Programación Segura
- Nunca te fíes de ninguna fuente de entrada, i.e. argumentos en la línea de comando,
variables de entorno, ficheros de configuración, paquetes TCP/UDP/ICMP entrantes,
argumentos de funciones, etc. Si la longitud o el contenido de los datos recibidos están
sujetos, siquiera mínimamente, al control desde el exterior, el programa o la función
debería tenerlo en cuenta cuando maneja dichos datos. Podemos considerar los apartados
siguientes desde el punto de vista de la seguridad:
- Llamadas a strcpy() y sprintf() para datos de longitud ilimitada. Usa strncpy() y
snprintf() cuando la longitud sea conocida (o implementa algun otro método de control de
límites cuando sea desconocida). No uses nunca gets() ni sprintf(), punto. Si lo haces,
te acosarán sin tregua duendes malvados.
- Si tienes que validar los datos de entrada del usuario para evitar que contengan
caracteres erróneos de cualquier clase, NO valides la presencia de dichos caracteres
erróneos. Simplemente verifica que la entrada consiste SOLO en los caracteres permitidos.
La idea es: todo lo que no está explícitamente permitido está prohibido.
- Lee las páginas del manual para las llamadas strncpy() y strncat(). Asegúrate de
entender cómo funcionan!!! Así como strncpy() puede no añadir un \0 final, strncat() sí
lo añade.
- Vigila el abuso de strvis() y getenv(). Con strvis() es fácil cometer un error con la
cadena de destino, y getenv() podría devolver cadenas mucho más largas de lo que el
programa espera. Estas dos funciones son, a menudo, una de las vías principales de ataque
contra un programa, provocando que este sobreescriba la pila o las variables al recibir
variables de entorno con valores no contemplados. Si tu programa lee variables de
entorno, se paranoico. Se muy paranoico!
- Cada vez que uses las llamadas open() o stat() pregúntate: " Y si es un enlace
simbólico ?"
- Asegúrate de usar mkstemp() en lugar de mktemp(), tempnam(), etc. Asegúrate también
de buscar problemas de acceso concurrente en general en /tmp, teniendo en cuenta que hay
muy pocas cosas que pueden ser atómicas en /tmp:
- Crear un directorio. O funciona o no funciona.
- Abrir un fichero O_CREAT | O_EXECL
Si se usa mkstemp() la función tratará por tí estos casos adecuadamente. De aquí que
todos los ficheros temporales deberían usar mkstemp() para garantizar que no se produzcan
problemas de acceso concurrente y que los permisos son correctos.
- Un atacante que consiga que los paquetes vayan a/vengan de un sistema arbitrario
tendrá el control completo de los datos que recibimos, por lo tanto NINGUNO de
estos datos será de fiar.
- Nunca dés por hecho que un fichero de configuración estará correctamente formateado o
que habrá sido generado por el programa de utilidad apropiado. No confíes en que las
entradas del usuario tales como nombres de terminal o cadenas del lenguaje estarán libres
de '/' o '../../../' si hay la mínima posibilidad de que puedan ser usadas en un nombre
de path. No confíes en NINGUN path proporcionado por el usuario cuando el programa
se ejecuta setuid root.
- Busca fallos o puntos débiles en la forma de almacenar los datos. Todos los ficheros
temporales deberían tener permisos de la forma 600 para protegerlos de ojos
curiosos.
- No te limites a buscar con grep los sospechosos habituales en programas que se
ejecutan con privilegios elevados. Busca los posibles desbordamientos línea a línea, hay
muchísimas más formas de provocar un desbordamiento de memoria además de mediante el
abuso de strcpy() y sus amigos.
- El simple hecho de restringir privilegios en algún punto no significa que no haya
manera de explotar el recurso en cuestión. El atacante podría colocar el código necesario
en la pila para recuperar los privilegios antes de ejecutar /bin/sh.
- Administra los uid. Elimina privilegios tan pronto como sea posible, y elimínalos de
verdad. Cambiar entre euid y uid NO es suficiente. Usa setuid() siempre que puedas.
- Nunca muestres el contenido de ficheros de configuración cuando ocurra un error. Un
número de línea y quizás un contador de posición es suficiente. Esto mismo es igualmente
cierto para todas las librerías y todos los programas suid/gid.
- Consejos para quienes revisen código existente debido a problemas de seguridad:
- Si no estás seguro de tus reparaciones de seguridad, envíalas para ser revisadas a
alguien con quien así lo hayas acordado previamente. No entregues código del que no estás
seguro, llegar a estropear algo en nombre de las reparaciones de seguridad resulta
bastante embarazoso.
- Aquellos con privilegios de entrega ("commit") para CVS deberían asegurarse de que
alguien con dichos privilegios esté entre los últimos en revisar los cambios. Dicha
persona revisará e incorporará la versión final que se desea tener en el árbol.
- Cuando distribuyas cambios para ser revisados usa siempre diffs con formato context o
unidiff. De este modo los diffs pueden ser fácilmente proporcionados como entrada a
patch(1). No te limites a enviar los ficheros enteros. Los diffs son más fáciles de leer
y aplicar al código fuente local (especialmente a aquel en el que podrían tener lugar
múltiples cambios simultáneamente). Todos los cambios deberían referirse a la rama de
desarrollo -current.
- Prueba tu mismo todos los cambios (i.e. compila y ejecuta el código fuente afectado)
antes de enviarlos a otra persona para que los revise. A nadie le gusta que le envíen
material averiado para revisar, y además produce la impresión de que el remitente ni
siquiera se fijó en lo que estaba haciendo (lo que no contribuye precisamente a dar una
sensación de confianza). Si necesita una cuenta en una máquina donde hay una versión
específica que no tienes a mano, simplemente pregunta. El proyecto tiene recursos
asignados para ese propósito en concreto.
- Nota para los responsables de la entrega de código ("commit"): no se debe olvidar
incorporar a la rama -stable los patches hechos sobre -current, de la forma que sea
adecuada.
- No reescribas código innecesariamente para acomodarlo a tu estilo/ gustos. Esto sólo
hace el trabajo de quienes lo revisan más difícil. Hazlo sólo si hay razones claras para
ello.
- Busca programas que hagan cosas complicadas con los gestores de señales. Muchas
rutinas en varias bibliotecas no son lo suficientemente reentrantes como para hacerlo con
seguridad.
- Presta especial atención al uso de realloc(). Lo habitual es no usar la función
correctamente.
- Cuando uses áreas de memoria de longitud fija use sizeof() para evitar pérdidas
cuando se cambia el tamaño del área pero no el código que la usa. Por ejemplo:
char buf[1024];
struct foo { ... };
...
MAL:
xxx(buf, 1024)
xxx(yyy, sizeof(struct foo))
BIEN:
xxx(buf, sizeof(buf))
xxx(yyy, sizeof(yyy))
Ten cuidado al aplicar sizeof a un puntero cuando lo que quieres es el tamaño del objeto
referenciado!
- Siempre que veas "char foo[###]", comprueba cada uso de foo para asegurarte de que no
se desbordará. Si no puedes evitar el desbordamiento (se han dado casos), usa malloc como
mal menor para ubicar el área de memoria, de este modo evitarás sobreescribir la
pila.
- Cierra siempre los descriptores de ficheros tan pronto como puedas, lo que hará más
probable que los contenidos del área de memoria de entrada de stdio() sean desechados. En
rutinas de biblioteca, dispon siempre los descriptores de ficheros que abras de modo que
se cierren tras lanzar con éxito otro proceso.
Consejos sobre seguridad en FreeBSD
Se deben ejecutar varios pasos para hacer seguro un sistema FreeBSD (para el caso,
cualquier sistema UNIX®):
- Inhabilitar todo software potencialmente peligroso
Gran cantidad de software debe ser ejecutado con un usuario privilegiado especial para
poder hacer uso de recursos específicos, haciendo el ejecutable set-uid. Un ejemplo es el
software UUCP o PPP, que hacen uso del puerto serie, o sendmail, que tiene que escribir
en el spool de correo y conectar con un puerto de red privilegiado. Si no usas UUCP de
poco sirve tener en su sistema el software asociado; sería prudente inhabilitarlo. Desde
luego, esto requiere saber a ciencia cierta lo que puede ser eliminado y lo que no, así
como tener claro si se va a necesitar o no dicha funcionalidad en el futuro.
Lo mismo se puede decir de aquellos programas de utilidad que no consideres lo bastante
útiles y que supongan un posible riesgo para la seguridad, como swapinfo. Si elminas el
bit set-uid del ejecutable (por medio del comando "chmod ug-s nombre-de-fichero") siempre
habrá la posibildad de que el usuario root pueda usar swapinfo. Sin embargo no es una
buena idea elminar tantos sbits que se haga necesario ser root contínuamente.
No sólo elimines programas que no uses, elimina también servicios que no quieras o
necesites suministrar. Esto se puede hacer editando los ficheros /etc/inetd.conf
y /etc/rc.conf e inhabilitando los servicios que no quieras usar.
- Reparar el software con errores que afecten a la seguridad (o cómo mantenerse un paso
por delante de los crackers)
Asegúrate de suscribirte a las diferentes Listas de ditribución sobre
seguridad en FreeBSD para obtener actualizaciones relacionadas con los errores que
afectan a la seguridad y reparaciones. Aplica las reparaciones inmediatamente.
- Copias de seguridad. Repare su sistema si una violación de la seguridad llegara a
ocurrir
Disponga siempre de copias de seguridad y de una versión limpia del sistema operativo
(por ejemplo en CD-Rom). Asegúrese de que sus copias de seguridad no contienen datos
alterados o modificados por el atacante.
- Instala software pare vigilar el estado del sistema
Programas como tcp wrappers y tripwire (ambos en packages/ports) pueden ayudarte a
monitorizar la actividad en tu sistema. Esto hace más fácil la detección de irrupciones.
Lee también la salida de los scripts de /etc/security, que se ejecutan diariamente y se
envían por correo a la cuenta root.
- Educa a la gente que trabaja en el sistema
Los usuarios deberían ser conscientes de lo que hacen. Deberías indicarles que nunca
revelen su password a nadie y que usen passwords difíciles de adivinar. Hazles entender
que la seguridad del sistema/de la red está parcialmente en sus manos.
También hay un documento PASO a PASO ("HowTo") sobre seguridad en FreeBSD disponible
que proporciona algunos consejos avanzados acerca de cómo mejorar la seguridad de su
sistema. Puede ser consultado en http://www.FreeBSD.org/~jkb/howto.html.
La seguridad es un proceso contínuo. Asegúrate de estar al día con los avances en el
campo de la seguridad.
Qué hacer si detectas que la seguridad ha sido comprometida
- Determina el alcance de la violación de seguridad
Qué privilegios consiguió el atacante ? Consiguió acceso de root ? Consiguió acceso sólo
en el nivel de usuario ?
- Determina si se ha alterado el estado del sistema (ámbito del kernel o de
usuario)
Qué software ha sido alterado? Se instaló un nuevo kernel ? Ha sido modificado alguno de
los archivos binarios del sistema (tales como telnetd, login, etc.) ? Si sospechas que un
atacante puede haber causado cualquier alteración en un sistema operativo, podrías
considerar conveniente reinstalar el sistema operativo desde un medio seguro.
- Averigua cómo se logró la irrupción
Ocurrió por medio de un error de seguridad bien conocido ? Si este es el caso, asegúrate
de instalar los patches correctos. Tuvo éxito la irrupción debido a una mala
configuración ? Fue el resultado de un error desconocido hasta el momento ? Si sospechas
que la irrupción ocurrió por medio de un error nuevo, deberías advertir al FreeBSD Security Officer.
- Repara el defecto de seguridad
Instala nuevo software o aplica patches al antiguo para reparar los problemas. Inhabilita
las cuentas que ya han sido comprometidas.
- Otros recursos
CERT también ofrece información detallada acerca de qué
pasos seguir en caso de que un sistema se vea comprometido.
Otra Información Relacionada Con La Seguridad