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

271 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ECLIPSE ATTACK НА СЕТЬ MONTANA - ДЕТАЛЬНЫЙ АНАЛИЗ
**Модель:** Grok 3
**Компания:** xAI
**Дата:** 07.01.2026 17:00 UTC
## ВВЕДЕНИЕ
Проведен детальный анализ сетевого слоя Montana на предмет возможности Eclipse Attack согласно шаблону из `PROMPT_COUNSIL_TEMPLATE.md`. Анализ включает проверку всех трех критических аспектов: netgroup diversity для outbound, anchor connections, и bucket collision handling.
## КРИТИЧЕСКАЯ НАХОДКА: ECLIPSE ATTACK ВОЗМОЖЕН
**Статус:** 🔴 **КРИТИЧЕСКАЯ УЯЗВИМОСТЬ - ECLIPSE ATTACK РЕАЛИЗУЕМ**
## АНАЛИЗ КОДА
### 1. ANCHOR CONNECTIONS - ОТСУТСТВУЮТ
**Файл:** `protocol.rs`, строка 206
```rust
// NOTE: Montana does NOT use anchor connections (see Network struct comment).
```
**Анализ:**
-**НЕТ механизма anchor connections** между рестартами
- ❌ После рестарта все адреса загружаются из `addresses.dat` без приоритизации
- ❌ Нет "trusted" адресов, которые гарантированно сохраняются между рестартами
- ❌ Нет механизма сохранения надежных outbound соединений
**Уязвимость:**
После рестарта жертвы все outbound соединения выбираются из AddrMan без гарантии, что они не контролируются атакующим.
### 2. NETGROUP DIVERSITY - НЕДОСТАТОЧНА ДЛЯ OUTBOUND
**Файлы:** `connection.rs`, `protocol.rs`, `addrman.rs`
**Анализ кода:**
```517:519:Montana ACP/montana/src/net/protocol.rs
// Check netgroup diversity
if !connections.can_connect(&socket_addr).await {
continue;
```
```264:270:Montana ACP/montana/src/net/connection.rs
/// Check if we can connect to this address (netgroup diversity)
pub async fn can_connect(&self, addr: &SocketAddr) -> bool {
let netgroup = get_netgroup(addr);
let counts = self.netgroup_counts.lock().await;
let current = counts.get(&netgroup).copied().unwrap_or(0);
current < MAX_PEERS_PER_NETGROUP
```
**Проблема:**
- ✅ Netgroup diversity проверяется **ПОСЛЕ** выбора адреса из AddrMan
-`select()` в AddrMan **НЕ гарантирует** выбор из разных netgroups
-`select_from_new()` и `select_from_tried()` используют случайный bucket выбор
- ❌ Если NEW table заполнена адресами из 4-х /16 подсетей атакующего, все 8 outbound могут быть из этих подсетей
**Уязвимость:**
MAX_PEERS_PER_NETGROUP=2 защищает только от превышения лимита, но не гарантирует разнообразие при выборе адресов.
### 3. BUCKET COLLISION HANDLING - УЯЗВИМОСТЬ
**Файл:** `addrman.rs`, строки 201-208
```201:208:Montana ACP/montana/src/net/addrman.rs
// Handle collision
if let Some(existing_idx) = self.tried_table[idx] {
// Move existing back to new
self.move_to_new(existing_idx);
}
self.tried_table[idx] = Some(addr_idx);
self.tried_count += 1;
```
**Анализ:**
- При `mark_good()` если bucket занят, старый адрес перемещается обратно в NEW table
- Атакующий может использовать это для:
1. Вытеснения легитимных адресов из TRIED table
2. Заполнения TRIED table своими адресами через повторные `mark_good()` вызовы
**Уязвимость:**
Коллизии в TRIED table могут быть использованы для вытеснения легитимных адресов.
### 4. ЗАПОЛНЕНИЕ NEW TABLE - БЕЗ ЗАЩИТЫ
**Файл:** `addrman.rs`, строки 408-416
```408:416:Montana ACP/montana/src/net/addrman.rs
/// Add multiple addresses (from addr message)
pub fn add_many(&mut self, addrs: Vec<NetAddress>, source: SocketAddr) -> usize {
let mut added = 0;
for addr in addrs {
if self.add(addr, Some(source)) {
added += 1;
}
}
added
}
```
**Анализ:**
- ❌ Нет rate limiting на `add_many()`
- ❌ Нет проверки разнообразия netgroups при добавлении
- ❌ Атакующий может отправить 1000 адресов за раз (MAX_ADDR_SIZE)
- ❌ NEW table: 1024 buckets × 64 slots = 65,536 возможных адресов
**Уязвимость:**
Атакующий может заполнить NEW table вредоносными адресами через множественные Addr сообщения.
### 5. ВЫБОР АДРЕСОВ - СЛУЧАЙНЫЙ, БЕЗ ГАРАНТИЙ
**Файл:** `addrman.rs`, строки 230-245
```230:245:Montana ACP/montana/src/net/addrman.rs
fn select_inner(&mut self, new_only: bool) -> Option<NetAddress> {
let mut rng = ChaCha20Rng::from_entropy();
// 50% chance to try new address (or 100% if new_only)
let use_new = new_only || rng.gen_bool(0.5);
if use_new && self.new_count > 0 {
self.select_from_new(&mut rng)
} else if self.tried_count > 0 {
self.select_from_tried(&mut rng)
} else if self.new_count > 0 {
self.select_from_new(&mut rng)
} else {
None
}
}
```
**Проблема:**
- `select_from_new()` и `select_from_tried()` используют случайный выбор bucket
- Нет гарантии выбора из разных netgroups
- Если NEW table заполнена адресами атакующего, вероятность выбора легитимного адреса низка
## ЭКСПЛУАТАЦИЯ ECLIPSE ATTACK
### ФАЗА 1: ЗАПОЛНЕНИЕ NEW TABLE
**Цель:** Заполнить NEW table вредоносными адресами
**Шаги:**
1. Подключиться к жертве как inbound peer
2. Отправить множественные `Addr` сообщения с вредоносными адресами:
- До 1000 адресов за сообщение (MAX_ADDR_SIZE)
- Использовать разные /16 подсети (минимум 4 для обхода MAX_PEERS_PER_NETGROUP=2)
- Каждый адрес должен быть routable (не private/loopback)
3. Повторить с разных IP адресов для обхода rate limiting
4. Цель: заполнить как можно больше buckets в NEW table
**Код эксплуатации:**
```rust
// Создать 65k+ вредоносных адресов в разных /16 подсетях
let mut malicious_addrs = Vec::new();
for subnet in 0..4 { // 4 разные /16 подсети
for i in 0..16384 { // 16k адресов на подсеть
let ip = Ipv4Addr::new(
subnet as u8,
(i / 256) as u8,
(i % 256) as u8,
1
);
malicious_addrs.push(NetAddress::new(
IpAddr::V4(ip),
19333,
NODE_FULL
));
}
}
// Отправить через Addr сообщения (по 1000 за раз)
for chunk in malicious_addrs.chunks(1000) {
send_addr_message(chunk.to_vec());
}
```
### ФАЗА 2: ПРОДВИЖЕНИЕ В TRIED TABLE
**Цель:** Переместить вредоносные адреса из NEW в TRIED table
**Шаги:**
1. Установить 8 outbound соединений от жертвы к атакующим адресам
2. Для каждого соединения:
- Успешно завершить handshake
- Поддерживать соединение активным
- Отправлять полезные сообщения (slices, transactions)
3. Жертва вызывает `mark_connected()``mark_good()` для каждого соединения
4. Адреса перемещаются из NEW в TRIED table
**Проблема с bucket collisions:**
- Если bucket в TRIED table занят легитимным адресом, он перемещается обратно в NEW
- Атакующий может повторно вызывать `mark_good()` для вытеснения легитимных адресов
### ФАЗА 3: ОЖИДАНИЕ РЕСТАРТА
**Цель:** Дождаться рестарта жертвы
**Шаги:**
1. Поддерживать вредоносные соединения активными
2. Мониторить жертву на предмет рестарта
3. После рестарта:
- AddrMan загружается из `addresses.dat`
- Все адреса в TRIED table сохраняются
- Anchor connections отсутствуют
### ФАЗА 4: ECLIPSE УСПЕШЕН
**Результат:**
1. После рестарта жертва выбирает outbound адреса из AddrMan
2. Все 8 outbound соединений идут к атакующему (из TRIED table)
3. Жертва изолирована в контролируемой сети атакующего
4. Атакующий может:
- Блокировать транзакции
- Предоставлять ложную информацию о chain state
- Проводить double-spend атаки
- Манипулировать consensus
## ПРОВЕРКА ЧЕКЛИСТА
Согласно шаблону:
```
[ ] Eclipse: netgroup diversity работает ❌ НЕ РАБОТАЕТ для outbound выбора
[ ] Eclipse: anchor connections есть ❌ ОТСУТСТВУЮТ
[ ] Eclipse: bucket collision handling ⚠️ УЯЗВИМО
```
## МИТИГАЦИИ И РЕКОМЕНДАЦИИ
### КРИТИЧЕСКИЕ ИСПРАВЛЕНИЯ:
1. **Добавить Anchor Connections:**
- Сохранять 2-3 надежных outbound соединения между рестартами
- Приоритизировать эти адреса при выборе
- Использовать отдельную таблицу для anchor адресов
2. **Улучшить Netgroup Diversity для Outbound:**
- Гарантировать выбор из разных netgroups при `select()`
- Требовать минимум 4 разных /16 подсети для 8 outbound соединений
- Проверять diversity ДО выбора адреса, а не после
3. **Защита от Bucket Collision Abuse:**
- Ограничить частоту `mark_good()` вызовов
- Защищать старые адреса в TRIED table от вытеснения
- Использовать более сложную логику для collision handling
4. **Rate Limiting для Addr Messages:**
- Ограничить количество адресов, принимаемых от одного peer
- Проверять разнообразие netgroups при добавлении
- Требовать подтверждение адресов перед добавлением в TRIED
## ЗАКЛЮЧЕНИЕ
**Eclipse Attack на сеть Montana РЕАЛИЗУЕМ** из-за:
1. Отсутствия anchor connections
2. Недостаточной netgroup diversity при выборе outbound адресов
3. Возможности заполнения NEW table вредоносными адресами
4. Уязвимости bucket collision handling в TRIED table
**Критичность:** 🔴 **КРИТИЧЕСКАЯ**
**Вероятность успешной атаки:** ВЫСОКАЯ при наличии достаточных ресурсов (4+ /16 подсетей, множественные IP адреса)
**Время до эксплуатации:** Среднее (требует времени на заполнение таблиц и ожидание рестарта)