
Demostración de la vulnerabilidad Heartbleed (CVE-2014-0160), incluyendo instrucciones de configuración del laboratorio y código fuente para construir tu propio laboratorio Heartbleed con fines educativos.
Este repositorio pretende servir como una prueba de concepto válida para el CVE Heartbleed, así como contener instrucciones para configurar tu propio desafío Heartbleed sin utilizar un Dockerfile preconstruido.
cd service/heartbleed o cd srcsudo docker build -t heartbleed .sudo docker run -dp 443:443 --name heartbleed heartbleedYa se ha preparado un script de explotación preconstruido para ti en la carpeta solution/. El script de explotación está basado en el script de Heartbleed de Sensepost (https://github.com/sensepost/heartbleed-poc), modificado para funcionar con este desafío específico. Los valores del campo de versión TLS en el payload Client Hello han sido modificados para esta versión del exploit.
Según los comentarios de los participantes del CTF, el/los módulo(s) de Metasploit para Heartbleed también funcionarán. Desafortunadamente, no lo he probado.
En mis pruebas originales del CVE Heartbleed, el binario base de OpenSSL no era consistente al volcar los contenidos de la memoria, y requeriría demasiado tiempo y recursos para forzar bruto adecuadamente la memoria del servidor para obtener las claves secretas, lo que habría llevado a que la infraestructura del CTF fuera DDoS'ada involuntariamente. Por lo tanto, se ha realizado una modificación en el script t1_lib.c, donde se encontraba la vulnerabilidad original.
En la línea 2586, el código original memcpy ha sido comentado y reemplazado por un bucle condicional que insertará la clave del servidor en el cuerpo de la respuesta el 10% de las veces. Esto tiene la intención de simular la naturaleza no determinista original del CVE Heartbleed, al mismo tiempo que asegura que los participantes aún puedan obtener la clave de manera confiable.
if ((rand() % 10) == 0) {
FILE *kf = fopen("/usr/local/apache2/conf/ssl/server.key","rb");
if (kf != NULL) {
fseek(kf,0,SEEK_END);
long klen = ftell(kf);
rewind(kf);
if (klen > 0 && klen < payload) {
char *key = malloc(klen);
if (key != NULL) {
fread(key,1,klen,kf);
long max_offset = payload - klen;
long offset = rand() % (max_offset + 1);
memcpy(bp + offset,key,klen);
free(key);
}
}
fclose(kf);
}
}