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

271 lines
12 KiB
Markdown
Raw Permalink Normal View History

# 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 адреса)
**Время до эксплуатации:** Среднее (требует времени на заполнение таблиц и ожидание рестарта)