5.1 KiB
Модель: 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
Анализ кода
-
Уязвимость вытеснения из 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, где они могут быть удалены или затеряться среди адресов атакующего. -
Отсутствие 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), узел подключится только к узлам атакующего. -
Слабая диверсификация исходящих (
protocol.rs): Циклconnection_loop(строки 467-605) используетaddrman.select()для выбора пиров. Хотяaddrmanпытается выбирать из разных бакетов, если большинство бакетов вtried_tableконтролируется атакующим (из-за уязвимости п.1), проверка/16netgroup не поможет, если атакующий имеет IP в разных подсетях (или использует ботнет).
Эксплуатация (Chain of Exploitation)
- Заполнение (Filling): Атакующий отправляет жертве тысячи
Addrсообщений с подконтрольными IP-адресами, заполняяnew_table. - Продвижение (Promotion): Атакующий устанавливает входящие соединения с жертвой с этих IP. Жертва, видя активность, может (в зависимости от логики) попытаться соединиться в ответ или просто обновить timestamp. При успешном исходящем соединении адрес попадает в
tried_table. - Вымывание (Eviction): Атакующий продолжает добавлять новые "свои" адреса, вызывая коллизии в
tried_table. Из-за логикиmove_to_new, старые честные пиры вылетают вnew_table. - Изоляция (Eclipse): Атакующий ждет перезапуска узла жертвы (или провоцирует его DoS-атакой).
- Захват: После рестарта жертва загружает
addresses.dat(гдеtried_tableотравлена) и не имеетanchors.dat. Все 8 исходящих соединений устанавливаются с узлами атакующего.
Рекомендации по исправлению
- Исправить коллизии в Tried: Вместо
move_to_new, тестировать новый адрес. Если он работает, а старый нет — заменять. Если оба работают — оставлять старый (принцип "первый пришел — занял место"). - Внедрить Anchors: Создать
anchors.dat, сохраняющий 2-4 проверенных пира при выключении. При старте пробовать их в первую очередь. - Outbound Eviction: Внедрить защиту от Eclipse для исходящих соединений (мониторинг качества цепи, сравнение заголовков с другими пирами, Feeler connections для проверки новых адресов).