Sistemas operativos, seguridad, redes, programación, robótica y astronomía
seguridad
Incrementado la seguridad en SSH
6 mar 2010
SSH (Secure SHell, en español: intérprete de órdenes segura) es el nombre de un protocolo y del programa que lo implementa, y sirve para acceder a máquinas remotas a través de una red. Permite manejar por completo la computadora mediante un intérprete de comandos, y también puede redirigir el tráfico de X para poder ejecutar programas gráficos si tenemos un Servidor X (en sistemas Unix y Windows) corriendo.
Cuando instalamos un servidor de ssh, por ejemplo OpenSSH (sudo aptitude install ssh), en ocasiones solemos dejarlo con las opciones de configuración que vienen por defecto, sobre todo en entornos domésticos, asumiendo que como ssh es un shell seguro, no necesitamos realizar más ajustes que los que vienen por defecto. Nada más lejos de la realidad. Vamos a ver algunas de las opciones del archivo de configuración (/etc/ssh/sshd_config) que nos pueden ayudar a comprender mejor como funciona ssh y lo expuestos que podemos estar frente a ataques basados en diccionario si no se toman las medidas oportunas.
Para editar el archivo necesitamos permisos de administrador:
sudo gedit /etc/ssh/sshd_config
Al editarlo podremos observar hay multitud de opciones de configuración, pero sólo nos vamos a centrar en las siguientes:
Port 20022 Protocol 2 LoginGraceTime 30 PermitRootLogin no MaxAuthTries 2 MaxStartups 1 AllowUsers pepito AllowUsers juanito@80.25.14.14
Veámos el significado de ellas:
- Port 20022 indica el puerto de escucha de ssh, es decir, donde estará esperando conexiones el servicio de ssh. El puerto por defecto es el 22 y es importante cambiarlo, ya que muchos scripts de ataques están dirigidos a este puerto. Cambiar de puerto no garantiza que no pueda ser localizado por dichos scripts, pero desde luego se lo ponemos más complicado. ¿Piensas que no es necesario cambiar el puerto? ¿Por qué no le hechas un vistazo a los registros de log de autentificación en /var/log/auth.log? ¿Sorprendido? Si tienes una máquina conectada a Internet, con el puerto 22 abierto y redirigido a una máquina con acceso ssh, seguro que tienes mucho que mirar en dicho fichero, como por ejemplo intentos de conexión fallidos. Por ejemplo, unas cuantas líneas como estas:
Feb 28 11:57:04 distantsuns sshd[25055]: Invalid user kid from 220.108.89.55
Feb 28 11:57:13 distantsuns sshd[25111]: Failed password for root from 220.108.89.55 port 44336 ssh2
Feb 28 11:58:25 distantsuns sshd[25775]: Failed password for invalid user kes from 220.108.89.55 port 48097 ssh2
Mi recomendación es que utilicéis un puerto alto, por encima del 10000. La mayoría de los escaners de puertos buscan por defecto en los puertos bien conocidos (hasta el 1024) y algunos puertos por encima, pero no los revisan todos.
Evidentemente, cambiar el puerto no nos asegura nada, pero pone las cosas un poco más difíciles a los scripts automáticos. - Protocol 2 existen 2 versiones de ssh, versión 1 y versión 2. La primera se mantiene sólo por compatibilidad y no debería ser usada ya que está obsoleta y tiene algunas vulnerabilidades bien conocidas.
- LoginGraceTime 30 indica el número de segundos que estará disponible la pantalla de login. Pasados los segundos la conexión se cerrará. De esta forma evitamos que alguien esté intentando acceder mediante un script varias veces para adivinar un usuario y contraseña. El valor por defecto de este campo es 130, demasiado tiempo en mi opinión, se pueden realizar muchas pruebas automáticas en ese tiempo. Para cualquier ser humano con 30 segundos debería ser más que suficiente.
- PermitRootLogin no muy importante no permitir conexiones remotas con el usuario root. Todos los ataques basados en diccionario saben que en los sistemas en UNIX, existe un usuario en el sistema llamado root. Por tanto una parte de la combinación usuario-contraseña ya la tendrían y no sólo eso, sino con acceso de administrador. Sorprendentemente esta opción estaba por defecto en mi máquina con el valor yes. Desde luego es un agujero de seguridad tremendo. Si necesitamos acceder vía ssh con permisos de administrador, podemos entrar al sistema con cualquier usuario estándar y una vez dentro cambiamos a root con el comando su.
- MaxAuthTries 2 indica la cantidad de veces que podemos equivocarnos al validarnos como usuario, en este caso después de dos intentos, se perderá o cerrará la conexión. Si se diera el caso podemos volver a intentarlo, pero de esta forma evitamos ataques basados en la persistencia de la conexión.
- MaxStartups 1 indica la cantidad de conexiones simultáneas de login que permitirá el sshd por ip que intente conectarse. Muchos de los ataques dividen su esfuerzo abriendo múltiples pantallas de login, llegando incluso a saturar el sistema. Es decir, el ataque se divide en una gran cantidad de logins, aumentando las posibilidades de obtener un usuario y contraseña más rápidamente. Tener este parámetro con el valor 1 no significa que no podamos tener varios shells remotos abiertos, simplemente cuenta pantallas de login. Una vez validados, podemos abrir otro shell sin problemas.
- AllowUsers indica los usuarios que tienen permiso para acceder por ssh al sistema. Muy útil cuando tenemos muchos usuarios en el sistema y no podemos tener un control sobre la seguridad de las contraseñas que se hayan puesto dichos usuarios. Por tanto sólo daremos permiso a aquellos usuarios que sepamos que tienen una combinación de usuario y contraseña fuertes. Con esta opción también podemos indicar desde que máquinas permitimos el acceso. Por ejemplo podríamos hacer que el usuario juanito sólo pudiése acceder desde la ip 80.25.14.14 añadiendo la siguiente línea:
AllowUsers juanito@80.25.14.14
También podemos usar comodines para indicar que se permite acceso desde una red entera. Por ejemplo supongamos que nuestra red privada utiliza direcciones ip privadas de clase C del tipo 192.168.0.X (máscara por defecto 255.255.255.0). Podríamos añadir la siguiente línea para indicar que se permite el acceso al usuario alicia únicamente desde la red privada:
AllowUsers alicia@192.168.0.*
Con este mini tutorial sobre la configuración podremos tener un sistema más seguro que unido al tutorial de verificación de rootkits, nos permite estar un poco más tranquilos.
Verificar Linux contra rootkits con rkhunter y chkrootkit
9 ene 2010
De acuerdo a la definición en wikipedia un rootkit es una herramienta, o un grupo de ellas que tiene como finalidad esconderse a sí misma y esconder otros programas, procesos, archivos, directorios, llaves de registro, y puertos que permiten al intruso mantener el acceso a un sistema para remotamente comandar acciones o extraer información sensible, a menudo con fines maliciosos o destructivos.
De hecho que un hacker (black hat) te instale un root kit en tu equipo Linux es la máxima intrusión a la que estarías expuesto. Recuerda que en GNU/Linux el peligro no son virus como en el mundo Windows sino las vulnerabilidades que se descubren a diario en los muy distintos programas que usa el sistema. Por eso la importancia de verificar y actualizar lo más continuo posible el sistema en su totalidad.
Se presentan dos utilerías que te permitirán verificar tu equipo por posibles cambios en los archivos y programas más comunes, ya que ha menudo los rootkits se disfrazan como programas de uso muy comun como ls o ps, incluso conservan la misma funcionalidad (que es el objetivo, que el usuario no se entere que ya ha sido hackeado con un rootkit) pero a la vez de manera furtiva realizan su trabajo de ejecutar comandos remotos, abrir puertos, realizar ataques DoS, instalar servidores Web ocultos, utilizar ancho de banda para transferencia de archivos, monitorear con keylogers, etc., etc.
chkrootkit
chkrootkit muy popular checador de rootkits, verifica localmente por señales de estos. Es una buena opción para equipos Desktop, laptops, incluso para servidores como un complemento más de este tipo de programas.
Para instalarlo (en Ubuntu):
sudo aptitude install chkrootkit
Se ejecuta sin argumentos de la siguiente manera:
$ chkrootkit ROOTDIR is `/' Checking `amd'... not found Checking `basename'... not infected Checking `biff'... not found Checking `chfn'... not infected Checking `chsh'... not infected Checking `cron'... not infected Checking `crontab'... not infected Checking `date'... not infected Checking `du'... not infected Checking `dirname'... not infected Checking `echo'... not infected Checking `egrep'... not infected Checking `env'... not infected Checking `find'... not infected ...
Es posible ver la lista de pruebas que chkrootkit puede realizar mediante la opción -l y ejecutar solo una o varias a la vez:
rkhunter
rkhunter es un checador de rootkits mucho más completo y potente que chkrootkit, es ideal para ser usado en servidores. En su página de descarga sostiene (a modo de broma) que verifica en eun 99.9% que estás libre de indeseables rootkits, es decir, realmente se trata de una capa más de seguridad. rkhunter verifica el sistema por:
- Comparación de hashes MD5
- Busca por archivos comunes usados por rootkits
- Permisos equivocados para binarios
- Busca por cadenas de texto sospechosoas en módulos LKM (Loadable Kernel Modules) y KLD (Kernel Loadable Device)
- Busca por archivos ocultos
- Opciones de escaneo dentro de archivos binarios y planos
Para instalarlo (en Ubuntu):
$ sudo aptitude install rkhunter
Una vez instalado, la manera más básica de ejecutar rkhunter es asi:
$ rkhunter -c
[ Rootkit Hunter version 1.3.2 ]
Checking system commands...
Performing 'strings' command checks
Checking 'strings' command [ OK ]
Performing 'shared libraries' checks
Checking for preloading variables [ None found ]
Checking for preload file [ Not found ]
Checking LD_LIBRARY_PATH variable [ Not found ]
Performing file properties checks
Checking for prerequisites [ OK ]
/bin/awk [ OK ]
/bin/basename [ OK ]
/bin/bash [ OK ]
/bin/cat [ OK ]
/bin/chmod [ OK ]
/bin/chown [ OK ]
/bin/cp [ OK ]
/bin/csh [ OK ]
/bin/cut [ OK ]
/bin/date [ OK ]
/bin/df [ OK ]
.... (varias líneas más)
rkhunter con la opción -c realiza un escaneo muy completo del sistema, no es posible apreciarlo aquí, pero en cada sección del escaneo la salida se interrumpe como para poder analizarlo, y hasta que no se presiones ‘Enter’ continua. Puedes deshacerte de este comportamiento interactivo con la opción –sk, por cierto, la lista de opciones o ayuda, la obtienes invocando rkhunter sin ningún argumento.
Si hubiera algo que reportar, el archivo /var/log/rkhunter.log, pero puedes cambiar la salida del archivo a otro que tu desees:
$ rkhunter -c --sk --logfile /root/rkhunter20100109.txt
Lo anterior enviará toda la salida al archivo indicado y sin hacer pausas para continuar. También es posible realizar pruebas personalizadas y no todas a la vez.
$ rkhunter --list (lista de pruebas posibles) Available test names: additional_rkts all apps attributes deleted_files filesystem group_accounts group_changes hashes hidden_procs immutable known_rkts local_host malware network none os_specific other_malware packet_cap_apps passwd_changes ports possible_rkt_files possible_rkts possible_rkt_strings promisc properties rootkits running_procs scripts shared_libs shared_libs_path startup_files startup_malware strings suspscan system_commands system_configs trojans Grouped test names: additional_rkts => possible_rkt_files possible_rkt_strings group_accounts => group_changes passwd_changes local_host => filesystem group_changes passwd_changes startup_malware system_configs malware => deleted_files hidden_procs other_malware running_procs suspscan ... (varias líneas más) $ rkhunter --enable hidden_procs,system_commands (se ejecutan solo las pruebas deseadas) $ rkhunter --disable system_commands (lo contrario, se ejecutan todas las pruebas menos la indicada(s))
Como ya se mencionó previamente, es conveniente que se ejecute periódicamente a través de un cron y con un control por fechas de los reportes que se generan, asi se teendrá una bitacora muy completa de cuando pudieron ocurrir cambios en el sistema.
También, recuerda que estos anti-rootkits son solo una medida de seguridad más para la protección de tu sistema, hay que actualizar continuamente, apagar los servicios que no se usen, configurar adecuadamente ssh, apache, servidores de correo, etc.
Login con el DNI electrónico
14 sep 2008
Aparte del habitual uso para identificarse en sitios web con el navegador, el DNIe puede usarse para más cosas, por ejemplo, firmar ficheros, o autenticarse (hacer “login”) en el PC. En este artículo describo cómo implementar esta última aplicación…
Para autenticarnos con el DNIe en Linux utilizaremos un módulo PAM (“Pluggable Authentication Module”) desarrollado también por el grupo OpenSC. El proyecto en cuestión al que nos referimos se llama Pam PKCS#11.
Seguidamente explicaré el proceso para utilizar esta herramienta, paso por paso.
1. ¿Qué son los módulos PAM?
En las distribuciones modernas de Linux el mecanismo de autenticación de los usuarios es un servicio modular, proporcionado a las aplicaciones por el propio sistema.
Por ejemplo, cuando una aplicación como “login” requiere la autenticación de un usuario, no la realiza ella misma sino que “solicita” al sistema que autentique al usuario. La parte del sistema que realiza la autenticación es una pila de módulos PAM, que se van ejecutando encadenadamente hasta devolver el resultado del proceso (autenticación OK o incorrecta) a la aplicación. Una vez que la aplicación obtiene este resultado, puede seguir realizando acciones (mostrar un mensaje de rechazo o ejecutar los scripts de arranque del usuario autenticado, por ejemplo).
Cada módulo PAM de la pila puede realizar distintas funciones, como autenticación propiamente dicha, gestión de contraseñas, gestión de la sesión…
Asimismo, cada aplicación que utiliza PAM tiene su configuración personalizada (incluyendo qué modulos y en qué orden se ejecutarán) en el fichero correspondiente del directorio /etc/pam.d/.
Lo interesante de esta arquitectura es que para cambiar el esquema de autenticación de múltiples aplicaciones basta con insertar un módulo adicional, o cambiar un módulo existente por uno nuevo.
Para más información, se puede consultar la página principal de PAM, aquí.
2. ¿Qué hace pam_pkcs11?
Precisamente, lo que permite el módulo pam_pkcs11 es introducir un paso de autenticación adicional (o alternativo), en el que se accede a los certificados de nuestra tarjeta (DNIe) y después de la pertinente verificación devuelve el correspondiente resultado indicando si la autenticación fue correcta o no.
En concreto, este módulo nos pedirá el PIN del DNIe, si es correcto accederá a los certificados del mismo y, comparando los datos que contienen con un “mapeo” configurado previamente en el sistema, determinará quién es el usuario (y la cuenta correspondiente).
El “mapeo” consiste simplemente en un fichero que contiene, para cada usuario, una línea del tipo:
dato del certificado -> usuario
El dato del certificado dependerá del “mapeador” que utilicemos. Para el mapeador más simple, por ejemplo, el dato que se utiliza es el DN del usuario contenido en el certificado.
Para más información, se puede consultar el manual de pam_pkcs11.
3. Instalando pam_pkcs11
(Asumimos que ya tenemos correctamente configurado el
DNI electrónico, de lo contrario ver el artículo citado al principio.)
Este módulo puede descargarse en forma de archivo fuente (.tar.gz) que hay que compilar…
El proceso sería tedioso de explicar aquí, así que un buen amigo mío se ha tomado la molestia de crear un paquete Debian para instalarlo directamente…
Desde aquí podemos descargarnos un comprimido .tar.gz que contiene tanto el paquete fuente Debian, como el paquete binario ya compilado (el que nos interesa): libpam-pkcs11_0.5.3-1_i386.deb
Para instalarlo, escribimos desde una consola:
sudo dpkg -i libpam-pkcs11_0.5.3-1_i386.deb
Esto instalará el paquete y creará un directorio de configuración en /etc/pam_pkcs11. (Si no tenemos instalado algún paquete requerido, dpkg se “quejará”: instalaremos el paquete adicional necesario, y volveremos a intentar la instalación anterior).
4. Configurando pam_pkcs11
Podemos dejar la configuración (fichero /etc/pam_pkcs11/pam_pkcs11.conf) por defecto intacta. De esta forma utilizaremos el “subject mapper”, que nos mapea el DN de un certificado del DNIe a una cuenta de usuario.
A continuación descargaremos todos los certificados de las Autoridades de Certificación del DNIe, en el directorio /etc/pam_pkcs11/cacerts.
Los certificados pueden obtenerse de los enlaces de esta página (están comprimidos, los guardamos descomprimidos: tienen extensión .crt).
En ese directorio, ejecutamos la herramienta “make_hash_link.sh” que crea unos enlaces (utilizados por nuestro módulo) a dichos certificados:
cd /etc/pam_pkcs11/cacerts
sudo make_hash_link.sh
cd ..
Seguidamente, conectaremos el lector, introduciremos el DNIe, y ejecutaremos el comando siguiente:
pkcs11_inspect
Esta utilidad nos pedirá el PIN del DNIe, y mostrará la información que necesitamos para crear el archivo de mapeo: los DNs de los dos certificados del DNIe (el de autenticación y el de firma).
Creamos el fichero de texto /etc/pam_pkcs11/subject_mapping:
sudo gedit /etc/pam_pkcs11/subject_mapping
(si usamos el editor de texto de gnome.)
Y añadimos una línea con uno de los DNs obtenidos con la utilidad anterior, asociándolo a nuestra cuenta de usuario. Por ejemplo, si nuestra cuenta es “fulanito” escribiremos algo así:
/C=ES/serialNumber=00000019L/SN=PEREZ/GN=FULANITO/CN=PEREZ SANCHEZ, FULANITO (AUTENTICACI\xC3\x93N) -> fulanito
(Es una sola línea, aunque pueda aparecer partida aquí.)
Con todo esto ya estaría configurado el módulo.
5. Cambiando la configuración PAM de la aplicación
El último paso que nos queda es cambiar la configuración PAM de la aplicación de control de acceso. En nuestro caso, cambiaremos la configuración de “gdm” (el gestor de entrada de gnome):
(Para la aplicación “login” propiamente dicha, de la consola, el proceso es equivalente.)
Editamos el archivo /etc/pam.d/gdm, y justo encima de la línea:
@include common-auth
Introducimos esta otra (incluimos un comentario si queremos):
# Autenticación PKCS#11 con DNIe
auth sufficient pam_pkcs11.so
De esta forma, añadimos un mecanismo de autenticación adicional (y opcional) con el DNIe.
Con “sufficient” indicamos que es una autenticación opcional: si la autenticación con DNIe falla, permitimos de momento introducir la contraseña habitual. Si funciona, no se preguntará la contraseña habitual y nos “loguearemos” directamente. También la podemos poner como “required”.
6. Probando la autenticación con el DNIe
Si queremos, podemos reiniciar el sistema.
Si utilizamos gnome (con gdm) se presentará la pantalla de bienvenida habitual.
Conectaremos el lector e introduciremos el DNIe.
En el campo de nombre de usuario de gdm pulsaremos ENTER directamente (el módulo pam detectará automáticamente nuestro usuario, como veremos).
A continuación, gdm nos pedirá el PIN del DNI electrónico. Lo introduciremos…
Si el PIN era correcto, y estamos “mapeados”, gdm iniciará el login con nuestra cuenta… y fin de la historia: habremos accedido a nuestro entorno de escritorio habitual.
7. Observaciones finales
Aparte del “mapeador” que hemos utilizado, este módulo PAM contiene otros mapeadores más avanzados (incluido uno para acceso a ldap). Es recomendable consultar la documentación.
Hay que hacer notar que la versión actual de esta herramienta tal vez no esté demasiado madura. Asimismo, los mecanismos de comprobación que se utilizan puede que no estén a la altura de unas exigencias de seguridad demasiado altas.
Sin embargo, aun como prueba de concepto únicamente, el proceso mostrado en este artículo resulta interesante. Puede tomarse como referencia para implementar mecanismos de autenticación más avanzados, usando PAM.
Vía: www.kriptopolis.org