Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2008-0166-BTC-satoshi-mining-wallets — Технический анализ CVE-2008-0166 в Bitcoin 2009-2012, исследование слабостей PRNG OpenSSL 0.9.8c, сбоев энтропии Windows и реконструкции ключевого пространства. | Kitploit
Инструменты/GitHubGitHub/ethicbrudhack/cve-2008-0166-btc-satoshi-mining-wallets
Анализ уязвимостейЭксплуатацияАнализ хэшейОбратная инженерияКриптографияСтатьи и ИсследованияОбучение и Образование
GitHubethicbrudhack/cve-2008-0166-btc-satoshi-mining-wallets

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

Технический анализ CVE-2008-0166 в Bitcoin 2009-2012, исследование слабостей PRNG OpenSSL 0.9.8c, сбоев энтропии Windows и реконструкции ключевого пространства.

Репозиторий
114 ч 49 мин назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

GhostRNG — Анализ уязвимости: OpenSSL 0.9.8c (CVE-2008-0166) в Bitcoin 2009-2012

Автор: анализ на основе 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) работал исключительно на Windows, используя OpenSSL 0.9.8c для генерации EC-ключей (EC_KEY_generate_key). В 2008 году в пакете OpenSSL от Debian была обнаружена CVE-2008-0166, но на Windows у проблемы была другая первопричина — не отсутствующий /dev/urandom, а реализация RandAddSeed() в самом исходном коде Bitcoin.


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() использует RAND_bytes(8) для других целей (сетевые nonce, никнеймы IRC), тем самым нарушая состояние PRNG между последовательными вызовами GenerateNewKey().

Версия 0.4.0 (сентябрь 2011) представила TopUpKeyPool() с пулом по умолчанию из 100 ключей (GetArg("-keypool", 100)).


3. Патч: make-OpenSSL-0-9-8c-vulnerable-again.diff

Группа THC (The Hackers Choice) разработала thc-btc-rng-bruteforce, используя модифицированный OpenSSL 0.9.8c. Три критических изменения:

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[] — полный сброс 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 против 16 байт)
  • Внутреннее представление bignum в SHA
  • Весь выходной поток PRNG

Тестовый вектор самопроверки THC (профиль 0.3.24, PID 31337):

  • le32: 1FkLYqPpfKPAR6EZh2RC6sDwTUA6Axb1XQ
  • le64: 1JbxBrkBiSwpJUJN2bXrYJc51pH5rjrzTD

Bitcoin 2009 работал на Windows XP 32-bit, поэтому корректная реконструкция ключа требует компиляции с принудительным THIRTY_TWO_BIT (отредактируйте include/openssl/opensslconf.h перед сборкой).


5. Баг Серхио Лернера (Bitcointalk 2012)

В посте от 27 сентября 2012 года (topic=113496) Серхио Лернер описал:

(a) RandAddSeed() вызывает QueryPerformanceCounter() — требуется выравнивание аргумента по QWORD. Компилятор gcc на Windows мог не выровнять стековую переменную по 8 байт, что приводило к тихому сбою.

(b) RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", ...) использует фиксированный буфер размером 250 000 байт. На Windows XP данные о производительности занимали ~280 КБ — функция возвращала ERROR_MORE_DATA и больше никогда не вызывалась с буфером большего размера. В debug.log не было предупреждения.

Если оба механизма отказывали, единственным источником энтропии был RAND_screen() (растровый снимок экрана). В пропатченном OpenSSL даже RAND_screen не имеет значения, поскольку содержимое буфера игнорируется.

Лернер рекомендовал логировать эти сбои в debug.log — это исправление было включено в более поздние версии Bitcoin Core.


6. Эволюция инициализации RNG в Bitcoin Core (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__)нет
QPC->RAND_add(8), perfmon отдельно каждые 10 мин
0.3.02010то женет
0.3.242011-07perfmon каждые 10 мин, RegQueryValueExAнет
0.4.02011-09то жеTopUpKeyPool 100
0.5.02011-12то же100
0.6.02012-03то же100

Ключевые выводы

  • RAND_screen() использовался на всех версиях Windows вплоть до 2012 года.
  • Keypool (100 ключей, предварительно сгенерированных без сброса PRNG) появился только в 0.4.0 — более ранние версии генерировали один ключ на запрос.
  • Perfmon: 0.1.5 использовал SHA256(pdata) -> RAND_add(32), более поздние версии передавали сырой pdata в RAND_add (разный размер num имеет значение в пропатченном OpenSSL, поскольку на состояние влияет только размер, а не содержимое).

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." — они не нашли никаких ключей в блокчейне. Анализ подтверждает их вывод: вероятность существования уязвимого ключа в блокчейне полностью зависит от того, был ли какой-либо биткоин-кошелёк действительно сгенерирован на системе Windows XP со сломанным OpenSSL и тихо отказывающими perfmon/QPC.


Ссылки

[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 — технический отчёт, 2026-09-10

Скачать инструмент