
Heartbleed CVE(CVE-2014-0160) 데모, 교육 목적으로 자체 Heartbleed 랩을 구축하기 위한 랩 설정 지침 및 소스 코드 포함
이 저장소는 Heartbleed CVE에 대한 유효한 개념 증명을 제공하고, 사전 빌드된 Dockerfile 없이 자체 Heartbleed 챌린지를 설정하는 방법에 대한 지침을 포함하는 것을 목표로 합니다.
cd service/heartbleed 또는 cd src 명령어를 사용하여 source/service 디렉토리로 이동합니다.sudo docker build -t heartbleed .sudo docker run -dp 443:443 --name heartbleed heartbleedsolution/ 폴더에 미리 준비된 익스플로잇 스크립트가 이미 준비되어 있습니다. 이 익스플로잇 스크립트는 Sensepost의 Heartbleed 익스플로잇 스크립트(https://github.com/sensepost/heartbleed-poc)를 기반으로 하며, 이 특정 챌린지에 맞게 수정되었습니다. Client Hello 페이로드의 TLS 버전 필드 값이 이 버전의 익스플로잇에 맞게 수정되었습니다.
CTF 참가자들의 피드백에 따르면, Heartbleed를 위한 Metasploit 모듈도 작동할 것입니다. 아쉽게도 저는 직접 시도해보지 않았습니다.
Heartbleed CVE에 대한 초기 테스트에서 기본 OpenSSL 바이너리는 메모리 내용을 일관되게 덤프하지 않았으며, 비밀 키를 얻기 위해 서버 메모리를 제대로 무차별 대입하는 데 너무 많은 시간과 리소스가 소요되어 CTF 인프라가 의도치 않게 DDoS 공격을 받을 수 있었습니다. 이에 따라 원래 취약점이 위치한 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);
}
}