PoC local de CVE-2015-0235

Como pequeña prueba de concepto para explotación local, la Universidad de Chicago ha liberado un pequeño código escrito en c que permite comprobar de forma sencilla si tu equipo es vulnerable al fallo en la librería glibc y que afecta a la función gethostbyname. Puedes leer más acerca de este fallo aquí.
Por el momento, vamos a ver en qué estado se encuentra el equipo y en caso de que sea vulnerable, la recomendación es actualizar lo antes posible. El código en cuestión es el siguiente:
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define CANARY "in_the_coal_mine"

struct {
  char buffer[1024];
  char canary[sizeof(CANARY)];
} temp = { "buffer", CANARY };

int main(void) {
  struct hostent resbuf;
  struct hostent *result;
  int herrno;
  int retval;

  size_t len = sizeof(temp.buffer) -
               16*sizeof(unsigned char) -
               2*sizeof(char *) - 1;
  char name[sizeof(temp.buffer)];
  memset(name, '0', len);
  name[len] = '\0';

  retval = gethostbyname_r(name,
                           &resbuf,
                           temp.buffer,
                           sizeof(temp.buffer),
                           &result,
                           &herrno);

  if (strcmp(temp.canary, CANARY) != 0) {
    puts("vulnerable");
    exit(EXIT_SUCCESS);
  }
  if (retval == ERANGE) {
    puts("not vulnerable");
    exit(EXIT_SUCCESS);
  }
  puts("should not happen");
  exit(EXIT_FAILURE);
}
Tras copiarlo en un fichero de texto plano, por ejemplo /tmp/test_ghost.c, debemos compilarlo. Siendo código c:
shell> gcc /tmp/test_ghost.c -o /tmp/test_ghost
Y ejecutándolo ya podemos comprobar si el sistema está o no afectado por la vulnerabilidad Ghost in Linux (CVE-2015-0235).
shell> /tmp/test_ghost 
vulnerable
En caso de que no esté, la salida será tal que así,
shell> /tmp/test_ghost 
not vulnerable
Leer más

Ghost in Linux (CVE-2015-0235)

Investigadores de la empresa Qualys han reportada una grave vulnerabilidad en la librería glibc
(biblioteca C de GNU Linux), que permite obtener un acceso no lícito al sistema sin la necesidad de usuario y contraseña.
Dicha vulnerabilidad ya está reportada y se ha identificado como CVE-2015-0235 y afecta a la mayoría de los sistemas ya que lleva 14 años ahí. Afecta a todos aquellos sistemas que tenga glibc-2.2 instalado, liberado en el año 2000! En mucho sitios ya comparan esta vulnerabilidad a heartbleed, que también movió cielo y tierra en su momento.
Las principales distribuciones GNU/Linux ya fueron notificadas de este bug antes de que se publicase, y ya hay parches al respecto para ellas.

Bug y explicación

Este fallo de seguridad afecta a la función gethostbyname, presente en glibc. Dicha función es usada en casi todos los sistemas Linux cuando se intenta acceder a otro equipo conectado en red. O dicho de otra forma, cuando se intenta resolver un nombre de dominio vía DNS.
El fallo se puede aprovechar si el atacante provoca un desbordamiento de buffer al usar un argumento hostname no válido. Es ahí cuando se permite ejecutar código arbitrario y con los permisos del usuario que está ejecutando DNS.
Qualys creó una prueba de concepto sobre un servidor Exim al enviarle un comando SMTP inválido. Un simple correo electrónico mal intencionado permite abrir una shell remota en el sistema.

Solución

Aplicar las actualizaciones de seguridad de los sistemas y reiniciar.

Más información




Leer más

add-apt-repository: command not found

Ubuntu incluyó una forma muy simple de añadir nuevos repositorios de software para disponer de paquetes específicos o más recientes. Esto permite a muchas personas y empresas ofrecer repositorios de fácil instalación en el sistema, para dejar así sus paquetes disponibles. La forma de instalar estos nuevos repositorios es gracias al comando add-apt-repository. Aunque, una vez finalizada la instalación básica del sistema, éste nos puede fallar por que no tiene los paquetes necesarios instalado. Si obtenéis el siguiente error agregando un origen.
shell> add-apt-repository ppa:oisf/suricata-stable
  -su: add-apt-repository: command not found
La solución es sencilla, únicamente hay que instalar el paquete python-software-properties.
shell> apt-get install python-software-properties
Y volver a probar,
shell> add-apt-repository ppa:oisf/suricata-stable
You are about to add the following PPA to your system:
 suricata IDS stable packages
 More info: https://launchpad.net/~oisf/+archive/suricata-stable
Press [ENTER] to continue or ctrl-c to cancel adding it
...
En la última versión de Ubuntu Server, la 14.04, encontré un problema a la hora de usar add-apt-repository e instalar las dependencias para que funcionase. En éste caso, tuve que instalar el paquete software-properties-common,
shell> apt-get install software-properties-common
Y ya luego todo funcionó correctamente.
Leer más

Bloquear IPs automáticamente

En la anterior entrada, Bloquear múltiples IPs eficientemente comentamos cómo poder emplear IPSet para crear listas de fácil acceso y que simplifiquen el proceso de bloqueo de IPs o rangos de IPs que no nos interesen. Esto simplifica mucho el trabajo de mantener un firewall, pero como se prometió al final de la entrada, existen páginas en la red que ofrecen un listado de IPs consideradas maliciosas y que sería un buen trabajo poder mantenerlas y bloquearlas. Un ejemplo es la web iblocklist, que ofrece listados de IPs de diferentes consideraciones y que podríamos emplear conjuntamente con IPSet para tener una mejor protección. Un ejemplo de esta unión sería poder bloquear todas aquellas IPs que se consideren que tienen presencia de la BotNet ZeuS, por ejemplo.
Esto es posible hacerlo y vamos a ver cómo.

Instalación

Lo primero que necesitamos es instalar las herramientas necesarias para manejar el listado que nos vamos a descargar.
shell> pip install iblocklist2ipset

Uso

Con el software instalado, ya podemos comenzar a generar las tablas que nos interesen para cargarlas en IPSet.
shell> iblocklist2ipset generate --ipset zeus \
"http://list.iblocklist.com/...archiveformat=gz" \
> /backup/zeus.list
Este comando generará un fichero, /backup/zeus.list, que tendrá todas aquellas IPs que se sabe que tienen la BotNet Zeus. Lógicamente, hay que actualizarlo cada cierto tiempo, pero de base la protección es bastante bueno, pues a día de hoy, por ejemplo, tiene más de 237k entradas. Lo cual, ya nos saca muchas probabilidades.
Ahora toca cargar el fichero como una tabla de IPSet, por lo que empleamos la opción de restore.
shell> ipset restore < /backup/zeus.list
Si cuando estás intentando cargar la nueva lista obtienes un fallo similar a este,
ipset v6.11: Error in line 1: Set cannot be created: set with the same name already exists
Es debido a que la lista que intentas cargar ya existe, por lo que tendrás que destruirla para poder cargarla nuevamente.
shell> ipset destroy zeus
shell> ipset restore < /backup/zeus.list
Con esta lista, ya puedes poner la regla de IPTables que consideres oportuna para manejarla.

Referencias

Leer más

Fail2ban: proteger servidor SSH

Fail2ban es una aplicación, escrita en Python, con la intención de prevenir la intrusión en nuestros sistemas por fuerza bruta. Para hacerlo, penaliza el bloqueo de conexiones remotas que intenten accesos por fuerza bruta. Trabaja conjuntamente con un sistema de firewall, por ejemplo IPTables y lo que realiza es una consulta constante de los ficheros de logs del sistema para detectar ataques de fuerza bruta. Si detecta uno, bloquea la IP por un tiempo limitado o permanentemente.
Actualmente Fail2ban tiene soporte de filtros para apache, ssh, qmail, vsftp, lighttp, postfix y courier mail. Cada uno de estos filtros es llamado "jail" y en realidad no es más que una tupla de filtro + acción.
Hoy, vamos a ver cómo proteger nuestro sistema de ataques por fuerza bruta a SSH con Fail2ban y para cambiar un poco las reglas, vamos a ver cómo hacerlo en un sistema CentOS.

Instalación

La instalación en CentOS es muy similar a la realizada en sistemas Debian, ya que ambos sistemas tienen el paquete disponible en sus repositorios. En el caso de CentOS, lo primero que debemos es instalar el repositorio EPEL.
shell> yum install epel-release
Y tras ello, ya podemos instalar Fail2ban.
shell> yum install fail2ban
Y nos garantizamos de que arranque al inicio del sistema,
shell> chkconfig fail2ban on

Configuración

Por defecto, Fail2ban trae la configuración de varios "jail" por defecto, que deberemos de eliminar o sobrescribir para tener el funcionamiento que nos interesa. El fichero de configuración a manejar es /etc/fail2ban/jail.conf y en él tenemos la sección [DEFAULT], que contiene los parámetros por defecto y genéricos y luego cada una de las tuplas de los servicios a monitorizar. Puesto que nos interesa tener el servicio SSH controlado, tenemos que definir el "jail" [ssh-iptables] y un ejemplo, puede ser el siguiente,
[DEFAULT]
ignoreip = 127.0.0.1 192.168.1.0/24
bantime = 86400
maxretry = 5
findtime = 600
mta = sendmail

[ssh-iptables]
enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
sendmail-whois[name=SSH, dest=you@local.com, sender=ban@local.com]
logpath = /var/log/secure
maxretry = 3
Acorde con la configuración anteriormente descrita, si alguien intenta acceder más de 3 (maxretry) veces al servicio SSH en 10 minutos (findtime), la IP origen será automáticamente bloqueada por el servicio y estará bloqueada durante 1 día (bantime).
Con la configuración ya lista, lo que debemos es de arrancar el servicio.
shell> /etc/init.d/fail2ban restart

Prueba

Inicial

Lo primero es saber que el sistema está funcionando correctamente. Para ello existe el comando fail2ban-client que nos asegura que el servicio Fail2ban está iniciado y funcionando. Al llamarlo, la respuesta esperada si todo está correcto es la siguiente,
shell> fail2ban-client ping
Server replied: pong

Check Fail2ban Status

[ssh-iptables] emplea IPTables para realizar los bloqueos, por lo que, para comprobar su estado, lo podemos hacer directamente desde IPTables.
shell> iptables --list -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
fail2ban-SSH  tcp  --  0.0.0.0/0         0.0.0.0/0           tcp dpt:22 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain fail2ban-SSH (1 references)
target     prot opt source               destination         
DROP       all  --  172.16.0.92          0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
Aunque también el propio Fail2ban tiene su propio status interno para saber el estado de una "jail".
shell> fail2ban-client status ssh-iptables
Status for the jail: ssh-iptables
|- filter
|  |- File list: /var/log/secure 
|  |- Currently failed: 0
|  `- Total failed: 0
`- action
   |- Currently banned: 1
   |  `- IP list: 172.16.0.92
   `- Total banned: 1

Desbloquear IP bloqueada

Si ahora nos interesa desbloquear una IP bloqueada, lo podemos hacer directamente desde IPTables,
shell> iptables -D fail2ban-SSH -s 172.16.0.92 -j DROP
Y desde el interfaz de Fail2ban sería...
shell> fail2ban-client set ssh-iptables unbanip 172.16.0.92
Leer más

Instalación de Oracle Java en Ubuntu

Una de las tareas que en su época se dio como más tediosa en sistemas GNU/Linux, fue la instalación de Java. Java la versión oficial, no el paquete libre, que ese viene en los repositorios, por lo que su instalación también es sencilla.
Sin embargo, gracias a la expansión de Ubuntu, la gente de Oracle creó una PPA que simplifica y mucho el proceso de instalación de Java. Los pasos a realizar, a continuación.

Instalación del nuevo repositorio

Como ya de dijo, Java está disponible para sistemas Debian desde el Oracle Java PPA, por lo que en primer lugar debemos de importarlo en nuestro sistema.
shell> add-apt-repository -y ppa:webupd8team/java
gpg: keyring `/tmp/tmp6gk849hs/secring.gpg' created
gpg: keyring `/tmp/tmp6gk849hs/pubring.gpg' created
gpg: requesting key EEA14886 from hkp server keyserver.ubuntu.com
gpg: /tmp/tmp6gk849hs/trustdb.gpg: trustdb created
gpg: key EEA14886: public key "Launchpad VLC" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
OK

Actualización de las fuentes

Como hemos añadido un nuevo lugar de fuentes, actualizamos el listado de paquetes,
shell> apt-get update

Instalación de Oracle Java

Ahora ya tenemos disponibles las diferentes versiones de Java que hay en los repositorios,
shell> apt-cache search oracle java
...
oracle-java6-installer - Oracle Java(TM) Development Kit 6
oracle-java6-set-default - Set Oracle JDK 6 as default Java
oracle-jdk7-installer - Oracle JDK7 Installer meta package
oracle-java7-installer - Oracle Java(TM) Development Kit 7
oracle-java7-set-default - Set Oracle JDK 7 as default Java
oracle-java8-installer - Oracle Java(TM) Development Kit 8
oracle-java8-set-default - Set Oracle JDK 8 as default Java
Por lo que seleccionamos la que queremos instalar y el resto será automático. Únicamente debemos de aceptar el acuerdo de licencia.
shell> apt-get install oracle-java7-installer

Comprobación

Cuando finalice la instalación, ya tenemos java y javac, entre otros, disponibles en el sistema
shell> javac -version
javac 1.7.0_72

shell> java -version
java version "1.7.0_72"
Leer más

Opciones por defecto en conexiones SSH

Muchos de los que leéis este blog usáis con frecuencia SSH para establecer conexiones a vuestras máquinas y me imagino que la gran mayoría sabrá de la existencia del fichero ~/.ssh/config de SSH. En él se pueden configurar y establecer opciones por defecto para algunas conexiones y que por lo tanto simplificarían mucho el día a día.
El ejemplo típico de estos casos es el de la necesidad de establecer un puerto diferente para la conexión SSH (por defecto, puerto 22). Así que imaginémonos que tenemos que establecer conexión con una máquina en el puerto 2222. Realizar esto implicaría pasarle unos parámetros y acordarse de hacerlo de cada vez.
shell> ssh -p 2222 db.local.net
Haciendo uso del fichero local de configuración de SSH se puede convertir esa llamada en la siguiente
shell> ssh db.local.net
Con únicamente añadir esto,
Host db.local.net
   Port 2222
Si te parece interesante esta opción, échale un vistazo al resto que comentaremos.

Simplificar conexión

Esta es quizás una de las opciones más comúnmente usadas en el fichero ~/.ssh/config. Simplifica con un nombre de conexión todas aquellas opciones que le debamos de pasar para tener una conexión satisfactoria. Un ejemplo,
Host database
   Hostname db.local.net
   User generic_user
   Port 2222
   GSSAPIAuthentication no
   GSSAPIDelegateCredentials no
   IdentityFile ~/.ssh/ssh

KeepAlive en conexiones

Esta es una buena opción a emplear si al equipo al que te conectas tiene un tiempo máximo de conexión sin actividad. Es decir, si pasado un tiempo sin hacer nada, la conexión SSH se cierra, esta es tu opción.
ServerAliveInterval 10
Lo que hará, no será más que enviar cada X segundos un paquete dummy para que la conexión detecte actividad y no se cierre por el servidor.

Multiplexar conexiones y mantenerlas persistentes

Imagínate que necesitas establecer varias conexiones a un mismo equipo remoto. Cada vez que te conectas, pierdes tiempo entre que se establece la conexión y te autenticas. Para solucionarlo, SSH permite multiplexar conexiones, o lo que es lo mismo, establecer una conexión y que el resto de conexiones a ese host empleen el socket abierto por la primera para realizarse. Todo el tráfico irá por la misma conexión y el servidor únicamente tendrá una conexión presente.
Del mismo modo, la opción de crear una conexión persistente indica que aunque la sesión se cierre, quedará un proceso en segundo plano manteniendo la conexión 1 hora (en este caso) y por lo tanto el socket seguirá disponible ese tiempo.
Host firewall
   ControlMaster auto
   ControlPath ~/.ssh/server-%r@%h:%p
   ControlPersist 1h
Ventajas: Acceso y autenticación mucho más rápidos.

Port forwardings

Hay veces que es necesario tener en tu equipo un puerto de un equipo remoto y viceversa. SSH para hacer esto ofrece las opciones -L y -R. El problema es que establecer estas conexiones implica escribir bastante y acordarse del nombre del equipo remoto, y del puerto local y remoto. ~/.ssh/config lo puede hacer por ti.
Host 192.168.1.15
   RemoteForward 8080 localhost:1030

Host 192.168.1.121
   LocalForward 3306 database:3306
Leer más

Formulario de contacto

Nombre

Correo electrónico *

Mensaje *

Últimos comentarios