montana/Русский/Совет/Google/атака_затмения_07.01.2026_14:50.md

5.1 KiB
Raw Permalink Blame History

Модель: Gemini 3 Pro Компания: Google Дата: 07.01.2026 14:50 UTC


TIER 0: КРИТИЧЕСКИЕ

1. Eclipse Attack: Отравление AddrMan и отсутствие Anchor Connections

Файлы: montana/src/net/addrman.rs, montana/src/net/connection.rs, montana/src/net/protocol.rs

Анализ кода

  1. Уязвимость вытеснения из Tried Table (addrman.rs): В методе mark_good (строка 181) при коллизии в таблице проверенных адресов (tried_table) вызывается move_to_new (строка 207).

    // Handle collision
    if let Some(existing_idx) = self.tried_table[idx] {
        // Move existing back to new
        self.move_to_new(existing_idx);
    }
    

    Это классическая уязвимость. Атакующий может намеренно создавать коллизии в бакетах (зная алгоритм SipHash и ключ или методом перебора), заставляя узел перемещать "хорошие" легитимные адреса обратно в таблицу new_table, где они могут быть удалены или затеряться среди адресов атакующего.

  2. Отсутствие Anchor Connections (protocol.rs, connection.rs): В protocol.rs (строки 206-207) явно указано:

    // NOTE: Montana does NOT use anchor connections (see Network struct comment).
    

    В Bitcoin Core файл anchors.dat сохраняет активные исходящие соединения при выключении и пробует подключиться к ним первыми при старте. В Montana этого нет. При рестарте узел полностью полагается на содержимое addrman (addresses.dat). Если tried_table была отравлена (см. п.1), узел подключится только к узлам атакующего.

  3. Слабая диверсификация исходящих (protocol.rs): Цикл connection_loop (строки 467-605) использует addrman.select() для выбора пиров. Хотя addrman пытается выбирать из разных бакетов, если большинство бакетов в tried_table контролируется атакующим (из-за уязвимости п.1), проверка /16 netgroup не поможет, если атакующий имеет IP в разных подсетях (или использует ботнет).

Эксплуатация (Chain of Exploitation)

  1. Заполнение (Filling): Атакующий отправляет жертве тысячи Addr сообщений с подконтрольными IP-адресами, заполняя new_table.
  2. Продвижение (Promotion): Атакующий устанавливает входящие соединения с жертвой с этих IP. Жертва, видя активность, может (в зависимости от логики) попытаться соединиться в ответ или просто обновить timestamp. При успешном исходящем соединении адрес попадает в tried_table.
  3. Вымывание (Eviction): Атакующий продолжает добавлять новые "свои" адреса, вызывая коллизии в tried_table. Из-за логики move_to_new, старые честные пиры вылетают в new_table.
  4. Изоляция (Eclipse): Атакующий ждет перезапуска узла жертвы (или провоцирует его DoS-атакой).
  5. Захват: После рестарта жертва загружает addresses.dat (где tried_table отравлена) и не имеет anchors.dat. Все 8 исходящих соединений устанавливаются с узлами атакующего.

Рекомендации по исправлению

  1. Исправить коллизии в Tried: Вместо move_to_new, тестировать новый адрес. Если он работает, а старый нет — заменять. Если оба работают — оставлять старый (принцип "первый пришел — занял место").
  2. Внедрить Anchors: Создать anchors.dat, сохраняющий 2-4 проверенных пира при выключении. При старте пробовать их в первую очередь.
  3. Outbound Eviction: Внедрить защиту от Eclipse для исходящих соединений (мониторинг качества цепи, сравнение заголовков с другими пирами, Feeler connections для проверки новых адресов).