
Демонстрация уязвимости Heartbleed (CVE-2014-0160), включающая инструкции по настройке лабораторной среды и исходный код для создания собственной лаборатории Heartbleed в образовательных целях.
Этот репозиторий служит валидным proof-of-concept для уязвимости Heartbleed CVE, а также содержит инструкции по созданию собственного испытания Heartbleed без использования готового Dockerfile.
source/service с помощью cd service/heartbleed или cd srcsudo docker build -t heartbleed .sudo docker run -dp 443:443 --name heartbleed heartbleedГотовый скрипт эксплойта уже подготовлен для вас в папке solution/. Скрипт основан на эксплойте Heartbleed от Sensepost (), модифицированном для работы с этим конкретным испытанием. Значения поля версии TLS в полезной нагрузке Client Hello изменены для этой версии эксплойта.
Согласно отзывам участников CTF, модули Metasploit для Heartbleed также будут работать. К сожалению, я это не проверял.
При моем первоначальном тестировании уязвимости Heartbleed CVE базовая бинарная сборка OpenSSL не давала стабильного дампа содержимого памяти, и требовалось слишком много времени и ресурсов для корректного перебора памяти сервера с целью получения секретных ключей, что могло бы привести к непреднамеренной DDoS-атаке на инфраструктуру CTF. Поэтому в скрипт t1_lib.c, где находилась исходная уязвимость, была внесена модификация.
В строке 2586 исходный код memcpy был закомментирован и заменен условным циклом, который вставляет серверный ключ в тело ответа в 10% случаев. Это предназначено для имитации исходного недетерминированного характера уязвимости Heartbleed CVE, при этом гарантируя, что участники все равно смогут надежно получить ключ.
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);
}
}