DoS sobre renegociación SSL/TLS (CVE-2011-1473)

Siempre que hablamos de conexión segura en internet solemos hablar de HTTPS, la diferencia básica entre HTTP y HTTPS es que mediante el protocolo HTTP la información viaja en plano por lo que cualquier intermediario puede husmear nuestra información cosa que no nos interesa, a raíz de la necesidad de mayor seguridad nació HTTPS que añade una capa de cifrado en la comunicación de nuestros datos en la capa de transporte, este cifrado se realiza a través del estándar SSL/TLS. Netscape desarrolló en 1996 SSLv3 que más tarde sirvió para asentar las bases del desarrollo del estándar TLSv1.0, la versión actual es TLSv1.1. En el post de hoy intentaremos explicar como realizar un ataque de denegación de servicio aprovechando que un sitio acepte la renegociación SSL/TLS.

Normalmente cuando alguien desarrolla una web en la que se necesita un nivel de seguridad, ya sea por un login, o por que se realizan tareas delicadas como operaciones bancarias, intranet de una empresa o compras online; es necesario implementar HTTPS, como ya hemos comentado hay diferentes versiones de SSL/TLS y muchas veces las versiones antiguas de los navegadores no son compatibles con las versiones más nuevas de los protocolos de cifrado que HTTPS puede implementar, estas versiones antiguas tienen problemas como niveles de cifrado débiles para la actualidad, menores de 128bits o como en el caso que nos ocupa, tener activada la renegociación de la conexión puede hacer que seamos víctimas de un ataque DoS. En muchas ocasiones esto es permitido por las webs para que sus clientes no tengan problemas de acceso, y puedan navegar aunque estén usan un protocolo de cifrado de hace 10 años. O simplemente por un despiste del desarrollador del sitio.

Para poder explicar como funciona este ataque D.o.S. es importante primero entender como funciona el handshake de HTTPS:

  1. En la primera parte se establece la versión del protocolo sobre la que se trabajará; se establece un id de sesión; el servidor envía su cipher suite que es una lista de protocolos, versiones y métodos de cifrados que acepta; se decide el método de compresión y se intercambian una serie de valores aleatorios.
  2. Este paso es opcional, el servidor envía su certificado y la verificación del mismo.
  3. Este paso va de la mano del paso 2, el cliente responde al servidor con su certificado y la verificación del mismo.
  4. En este paso se produce el intercambio final de los certificados del cliente y servidor y de sus espeficaciónes correspondientes. A partir de ahora la comunicación cliente-servidor es cifrada.

La base de este ataque se encuentra en el consumo de recursos que le supone al servidor en relación con el cliente, para que nos hagamos una idea un servidor puede negociar entre 150-300 handshakes por segundo (según la potencia del mismo), mientras que un cliente puede solicitar hasta 1000 handshakes por segundo, por lo que no es necesario una botnet ni un súper ordenador para realizar este ataque. Pero para que este ataque surta el efecto deseado el servidor tiene que tener habilitada la renegociación de SSL/TLS.
Como podemos observar, es fácil darse cuenta de por donde van los tiros en este ataque, pedir N peticiones de renegociación de cifrado a nuestro servidor víctima.

Hay varia formas de detectar esta vulnerabilidad, si usamos Nessus existe un plugin (ID53491), aunque también se puede comprobar de forma manual con el comando openssl:

openssl s_client -connect IP:PUERTO
HEAD / HTTP/1.0
R

Si nos devuelve “RENEGOTIATING” podemos tener claro que el servidor es vulnerable.

Los chicos de The Hackers Choice han desarrollado una herramienta para poder explotar esta vulnerabilidad a fondo, la podeis encontrar aquí.

Para prevenir este tipo de ataques y otros como MiTM es muy importante tener siempre desactivadas las versiones mas desfasadas de los protocolos de cifrado, tener el software siempre actualizado, las últimas versiones de Apache no son vulnerables y tiene la renegociación SSL desactivada, al igual que las últimas versiones de Microsoft IIS. Por otro lado también es interesante implementar reglas de forma que una determinada IP tenga un número máximo de renegociaciones SSL por segundo, por ejemplo 5, ya que muchas veces como en el caso de querer que los clientes tengan que autenticarse en ciertas paginas con certificados X509 es necesaria tener activada la renegociación.

Es importante comentar que el fallo no está en el protocolo en si, sino en la opción de renegociación de la conexión cifrada.

Post también disponible en: blog.buguroo.com

 Fuentes:
– Especificaciones de cifrado
– Protocolo SSL/TLS
– Protocolo HTTPS
www.orchilles.com
– RFC’s: RFC2818, RFC4346, RF5746

Acerca de dan1t0

Conocete a ti mismo
Esta entrada fue publicada en seguridad y etiquetada , , , , , , , . Guarda el enlace permanente.

3 respuestas a DoS sobre renegociación SSL/TLS (CVE-2011-1473)

  1. Pingback: DoS sobre renegociación SSL/TLS (CVE-2011-1473)

  2. Mario Díaz dijo:

    @mariodi de twitter🙂 prueba esto, con eso debería valer para cualquier conexión.

    #include stdio.h
    #include string.h
    #include netinet/in.h
    #include netdb.h
    #include sys/types.h
    #include unistd.h
    #include stdlib.h
    //por motivos de filtrado de caracteres de WP no se visualizan los menor y mayor que

    int conecta (struct in_addr *addr, int puerto) {
    int conn;

    struct sockaddr_in dirr;
    int sock;

    sock = socket (AF_INET, SOCK_STREAM, 0);
    if (sock == -1) perror (“socket()”);

    //bzero (dirr,sizeof(dirr));

    dirr.sin_family = AF_INET;
    dirr.sin_addr.s_addr=addr->s_addr;
    dirr.sin_port = htons(puerto);

    conn = connect(sock, (struct sockaddr *) &dirr, sizeof(dirr));
    if (conn == -1) perror (“connect()”);

    return sock;
    }

    main(int argc, char *argv[])
    {
    struct hostent *theHost;
    int th = 0;

    if (argc < 4)
    {
    printf("Usage: %s \n”, argv[0]);
    exit(0);
    }

    th = atoi (argv[3]);

    //Resolucion
    theHost = gethostbyname(argv[1]);
    if (theHost == NULL) {
    perror (“gethostbyname()”);
    exit(0);
    }
    if (theHost->h_addr_list[0] == ‘\x0’) {
    printf (“host no encontrado”);
    exit (1);
    }

    //Ataque
    while(th > 0)
    {
    conecta ((struct in_addr *) theHost->h_addr_list[0], atoi(argv[2]));
    th–;
    //fork();
    }
    }

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s