
Demonstration des Heartbleed CVE (CVE-2014-0160), einschließlich Anweisungen zum Einrichten des Labors und Quellcode zum Erstellen Ihres eigenen Heartbleed-Labors für Bildungszwecke
Dieses Repository dient als gültiger Proof-of-Concept für die Heartbleed CVE und enthält Anleitungen zum Einrichten Ihrer eigenen Heartbleed-Herausforderung ohne Verwendung eines vorgefertigten Dockerfiles.
cd service/heartbleed oder cd srcsudo docker build -t heartbleed .sudo docker run -dp 443:443 --name heartbleed heartbleedEin vorgefertigtes Exploit-Skript wurde für Sie im Ordner solution/ vorbereitet. Das Exploit-Skript basiert auf Senseposts Heartbleed-Exploit-Skript (https://github.com/sensepost/heartbleed-poc) und wurde angepasst, um für diese spezifische Herausforderung zu funktionieren. Die Werte des TLS-Version-Feldes im Client-Hello-Payload wurden für diese Version des Exploits geändert.
Laut Rückmeldungen von CTF-Teilnehmern funktionieren auch die Metasploit-Module für Heartbleed. Leider habe ich dies nicht ausprobiert.
Bei meinen ursprünglichen Tests der Heartbleed CVE war das Basis-OpenSSL-Binärprogramm nicht konsistent beim Auslesen der Speicherinhalte und würde zu viel Zeit und Ressourcen in Anspruch nehmen, um den Serverspeicher ordnungsgemäß zu brute-forcen, um die geheimen Schlüssel zu erhalten, was zu einer unbeabsichtigten DDoS-Angriff auf die CTF-Infrastruktur geführt hätte. Daher wurde eine Änderung im t1_lib.c-Skript vorgenommen, wo sich die ursprüngliche Sicherheitslücke befand.
In Zeile 2586 wurde der ursprüngliche memcpy-Code auskommentiert und stattdessen durch eine bedingte Schleife ersetzt, die in 10 % der Fälle den Serverschlüssel in den Antwortkörper einfügt. Dies soll die ursprüngliche nicht-deterministische Natur der Heartbleed CVE simulieren und gleichzeitig sicherstellen, dass die Teilnehmer den Schlüssel zuverlässig erhalten können.
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);
}
}