Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2008-0166-BTC-satoshi-mining-wallets — 비트코인 2009-2012에서의 CVE-2008-0166 기술 분석으로, OpenSSL 0.9.8c PRNG 취약점, Windows 엔트로피 실패, 키 공간 재구성을 검토합니다. | Kitploit
도구/GitHubGitHub/ethicbrudhack/cve-2008-0166-btc-satoshi-mining-wallets
Vulnerability AnalysisExploitationHash AnalysisReverse EngineeringCryptographyPapers & ResearchLearning & Education
GitHubethicbrudhack/cve-2008-0166-btc-satoshi-mining-wallets

CVE-2008-0166-BTC-satoshi-mining-wallets

비트코인 2009-2012에서의 CVE-2008-0166 기술 분석으로, OpenSSL 0.9.8c PRNG 취약점, Windows 엔트로피 실패, 키 공간 재구성을 검토합니다.

저장소 보기
115시간 33분 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

GhostRNG — 취약점 분석: Bitcoin 2009-2012에서의 OpenSSL 0.9.8c (CVE-2008-0166)

작성자: bitcoin-code-r252 (0.1.5 / 0.2.0 / 0.3.24) 및 원본 make-OpenSSL-0-9-8c-vulnerable-again.diff (THC)를 기반으로 한 분석 날짜: 2026-09-10


1. 서론

Bitcoin 0.1.5 (2009년 1월)는 Windows에서만 실행되었으며, EC 키 생성 (EC_KEY_generate_key)을 위해 OpenSSL 0.9.8c를 사용했다. 2008년에 CVE-2008-0166이 Debian의 OpenSSL 패키지에서 발견되었지만, Windows에서는 문제의 근본 원인이 달랐다 — /dev/urandom의 부재가 아니라, Bitcoin 소스 코드 자체의 RandAddSeed() 구현이었다.


2. 키 생성 이전의 PRNG 상태 (0.1.5)

bitcoin-code-r252 (tags-0.1.5)에서 RNG 초기화 순서 (util.cpp):

root@kitploit:~
CInit::CInit() {
    RAND_screen();                    // (a) screen bitmap scrape
    RandAddSeed(true);                // (b) QPC + PerfMon
}

RandAddSeed (util.cpp:57-92):

  • QueryPerformanceCounter -> RAND_add(&PerformanceCount, 8, 1.5)
  • RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", ..., buf=250000) -> if ERROR_SUCCESS: SHA256(pdata) -> RAND_add(&hash, 32, entropy)

키 생성 (key.h:75-78):

root@kitploit:~
CKey::MakeNewKey() {
    EC_KEY_generate_key(pkey);  // internally: RAND_bytes(32)
}

중요: 0.1.5부터 0.3.24까지의 버전에는 keypool이 없었다. GetRand()는 다른 목적(네트워크 nonce, IRC 닉네임)으로 RAND_bytes(8)을 사용하므로, 연속된 GenerateNewKey() 호출 사이에 PRNG 상태를 교란시킨다.

버전 0.4.0 (2011년 9월)은 기본 100개의 키 풀 (GetArg("-keypool", 100))을 가진 TopUpKeyPool()을 도입했다.


3. 패치: make-OpenSSL-0-9-8c-vulnerable-again.diff

THC 그룹 (The Hackers Choice)은 수정된 OpenSSL 0.9.8c를 사용하여 thc-btc-rng-bruteforce를 개발했다. 세 가지 중요한 변경 사항:

A. THC_hitme()의 도입 (md_rand.c:133-180)

  • THC_hitme(0): state_num, state_index, entropy, initialized, stirred_pool, md_count[0..1], md[], state[]를 0으로 초기화 — 완전한 PRNG 리셋.
  • THC_hitme(pid): pid를 정적 변수 thc_pid에 저장.

B. ssleay_rand_add() — 버퍼 내용 무시 (344행)

root@kitploit:~
- MD_Update(&m, buf, j);
+ //MD_Update(&m, buf, j);   // commented out!

RAND_add는 여전히 state_index를 num만큼 진행시키고 md_count[1]을 증가시키지만, 버퍼 내용은 PRNG 상태에 영향을 미치지 않는다.

C. ssleay_rand_bytes() — PID 대체 (550-561행)

  • 원래의 getpid() 호출 제거됨.
  • curr_pid = thc_pid — THC_hitme로부터의 상수 값.
  • 추가적인 MD_Update(&m, &curr_pid, sizeof(curr_pid))가 PID를 유일한 외부 변수 입력으로 주입한다.

결론

패치된 OpenSSL에서 PRNG 상태는 오직 다음에만 의존한다:

  1. PID 값 (THC_hitme를 통해)
  2. RAND_add 호출의 순서와 크기 (num 매개변수, 버퍼 내용이 아님)
  3. 키 생성 이전의 RAND_bytes 호출 횟수

4. 아키텍처 차이: le32 vs le64

OpenSSL 0.9.8c에서 BN_ULONG은 opensslconf.h에 의해 정의된다:

root@kitploit:~
#ifdef SIXTY_FOUR_BIT_LONG   -> BN_ULONG = unsigned long (64-bit)
#ifdef THIRTY_TWO_BIT        -> BN_ULONG = unsigned long (32-bit)

64비트 Linux에서 OpenSSL은 기본적으로 SIXTY_FOUR_BIT_LONG을 사용하여 sizeof(BN_ULONG)을 4바이트에서 8바이트로 변경한다. 이는 다음에 영향을 미친다:

  • static long md_count[2]의 크기 (8 vs 16 바이트)
  • SHA 내부의 bignum 표현
  • 전체 PRNG 출력 스트림

THC SelfCheck 테스트 벡터 (프로파일 0.3.24, PID 31337):

  • le32: 1FkLYqPpfKPAR6EZh2RC6sDwTUA6Axb1XQ
  • le64: 1JbxBrkBiSwpJUJN2bXrYJc51pH5rjrzTD

Bitcoin 2009는 Windows XP 32비트에서 실행되었으므로, 올바른 키 복원을 위해서는 THIRTY_TWO_BIT을 강제하여 컴파일해야 한다 (빌드 전에 include/openssl/opensslconf.h 편집).


5. Sergio Lerner의 버그 (Bitcointalk 2012)

2012년 9월 27일 게시물 (topic=113496)에서 Sergio Lerner는 다음과 같이 설명했다:

(a) RandAddSeed()는 QueryPerformanceCounter()를 호출하는데, 이는 인수의 QWORD 정렬을 요구한다. Windows의 gcc 컴파일러는 스택 변수를 8바이트로 정렬하지 못하여 조용히 실패할 수 있었다.

(b) RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", ...)는 250,000 바이트의 고정 버퍼를 사용한다. Windows XP에서 성능 데이터는 ~280 KB였고 — 함수는 ERROR_MORE_DATA를 반환했으며 더 큰 버퍼로 다시 호출되지 않았다. debug.log에는 어떤 경고도 없었다.

두 메커니즘이 모두 실패하면, 유일한 엔트로피 소스는 RAND_screen() (화면 비트맵)이었다. 패치된 OpenSSL에서는 버퍼 내용이 무시되므로 RAND_screen조차 무의미하다.

Lerner는 이러한 실패를 debug.log에 기록할 것을 권장했으며 — 이 수정 사항은 이후 Bitcoin Core 버전에 반영되었다.


6. Bitcoin Core에서의 RNG 초기화 진화 (2009-2012)

bitcoin-code-r252 (tags: 0.1.5, 0.2.0, 0.3.0) 및 bitcoin/bitcoin 저장소 (tags: 0.3.24, 0.4.0, 0.5.0, 0.6.0)에서 검증됨:

버전날짜RNG 초기화 (Windows)Keypool
0.1.52009-01RAND_screen + RandAddSeed(true)없음
QPC->RAND_add(8) + perfmon->SHA256->RAND_add(32)
0.2.02009-12RAND_screen (__WXMSW__ only)없음
QPC->RAND_add(8), perfmon separate every 10 min
0.3.02010동일없음
0.3.242011-07perfmon every 10 min, RegQueryValueExA없음
0.4.02011-09동일TopUpKeyPool 100
0.5.02011-12동일100
0.6.02012-03동일100

주요 발견 사항

  • RAND_screen()은 2012년까지 모든 Windows 버전에서 사용되었다.
  • keypool (PRNG 리셋 없이 사전 생성된 100개의 키)은 0.4.0에서만 등장했다 — 이전 버전은 요청당 하나의 키를 생성했다.
  • Perfmon: 0.1.5는 SHA256(pdata) -> RAND_add(32)를 사용했고, 이후 버전은 원시 pdata를 RAND_add에 전달했다 (패치된 OpenSSL에서는 내용이 아닌 크기만이 상태에 영향을 미치므로 다른 num 크기가 중요하다).

7. 결론

공격을 위한 키 공간 (패치된 OpenSSL에서):

root@kitploit:~
  PID (1..32767)
  x poll (count of RAND_add calls in init, modeling Toolhelp32 on WinXP)
  x keypool position (1 for pre-0.4.0, 100 for 0.4.0+)
  x profile (RAND call sequence for each Bitcoin version)
  x architecture (le32 / le64)

tick, screen, cursor, hwnd, queue 매개변수는 이 모델에서 무의미하다. 왜냐하면 RAND_add 버퍼 내용이 무시되기 때문이다.

원래 THC 저자들은 다음과 같이 썼다: "We did not find any." — 그들은 블록체인에서 어떤 키도 찾지 못했다. 이 분석은 그들의 발견을 확인한다: 취약한 키가 온체인에 존재할 확률은 Bitcoin 지갑이 실제로 손상된 OpenSSL과 조용히 실패하는 perfmon/QPC를 가진 Windows XP 시스템에서 생성되었는지 여부에 전적으로 달려 있다.


참고 문헌

[1] Sergio Lerner, "Possible new vulnerability: poor entropy in Windows generated keypairs", Bitcointalk 2012-09-27: link

[2] Bitcoin StackExchange — "Was Satoshi using Windows or Linux?": link

[3] THC, thc-btc-rng-bruteforce: link

[4] Bitcoin Core tags (0.1.5, 0.2.0, 0.3.0, 0.3.24, 0.4.0, 0.5.0, 0.6.0): link

[5] OpenSSL 0.9.8c + patch make-OpenSSL-0-9-8c-vulnerable-again.diff

[6] Analiza_entropy_win.txt — technical report, 2026-09-10

도구 다운로드