6.2 KiB
Модель: Gemini 3 Pro Компания: Google Дата: 07.01.2026 14:45 UTC
TIER 0: КРИТИЧЕСКИЕ
1. Eclipse Attack: Poisoning TRIED & No Anchors
Файлы: net/addrman.rs, net/connection.rs
Анализ: Код содержит критические уязвимости, позволяющие изолировать узел (Eclipse Attack):
- Отсутствие Anchor Connections: В
addrman.rsиconnection.rsнет механизма сохранения активных соединений ("anchors") для немедленного переподключения после перезапуска. Узел полагается только наaddresses.dat. ЕслиTRIEDтаблица отравлена, после рестарта узел подключится только к атакующему. - Слабая защита TRIED таблицы: В методе
mark_good(addrman.rs) при коллизии вtried_tableиспользуется стратегияmove_to_new, которая вытесняет существующий (легитимный) адрес обратно вnew_table. Атакующий может намеренно создавать коллизии (зная алгоритм SipHash ключа или просто флудом), вымывая честные узлы из доверенного списка.
Эксплуатация:
- Атакующий заполняет
NEWтаблицу своими IP. - Атакующий устанавливает соединения, чтобы попасть в
TRIED. - Атакующий вызывает коллизии, вытесняя легитимные пиры в
NEW, где они могут быть удалены. - Жертва перезагружается -> подключается к адресам из
TRIED(которые теперь принадлежат атакующему).
2. Memory Exhaustion: Unbounded Event Channel & Read Timeout
Файлы: net/protocol.rs
Анализ:
- Event Channel Flooding: Канал
mpsc::channel(10000)вNetwork::newпередает сообщенияNetEvent. СобытиеNetEvent::SliceсодержитBox<Slice>. РазмерSliceдо 4MB.- Атакующий может отправить 10,000 сообщений
Slice(нет rate limit, см. ниже). - Потребление памяти: 10,000 * 4MB = 40 GB. Это приведет к OOM (Out of Memory) падению.
- Атакующий может отправить 10,000 сообщений
- No Read Timeout (Post-Handshake): В
handle_connectionтаймаут 30 сек действует только на handshake. После этогоread_messageвызывается без таймаута.- Атакующий отправляет заголовок сообщения (Length = 4MB) и останавливает передачу.
- Узел выделяет 4MB буфер (
vec![0u8; len]) и вечно ждет данные. - При 117 слотах это ~470MB "мертвой" памяти, плюс блокировка потоков tokio.
Эксплуатация:
- Vector A: Открыть соединение, handshake, отправить 10,000 сообщений
Sliceмаксимально быстро. - Vector B: Открыть 117 соединений, отправить заголовки 4MB сообщений и перестать слать байты.
TIER 1: ВЫСОКИЕ
3. Connection Slot Exhaustion: Dead Eviction Logic
Файлы: net/protocol.rs, net/eviction.rs
Анализ:
В файле net/eviction.rs реализована сложная логика вытеснения (select_peer_to_evict), но она НИГДЕ НЕ ИСПОЛЬЗУЕТСЯ.
В protocol.rs в listener_loop:
if !connections.can_accept_inbound() {
debug!("Max inbound reached, rejecting: {}", addr);
continue; // Просто отклоняет, не пытаясь освободить место!
}
Эксплуатация:
- Атакующий открывает 117 соединений (max inbound).
- Узел перестает принимать любые новые входящие соединения.
- Легитимные пиры не могут подключиться.
4. Sync DoS: GetSlices Amplification
Файлы: net/protocol.rs, net/sync.rs
Анализ:
Обработчик Message::GetSlices в protocol.rs не имеет проверки Rate Limit (в отличие от Inv или GetData).
Message::GetSlices { start, count } => {
let count = count.min(500); // Limit count per req, but NOT req rate
let _ = event_tx.send(...).await;
}
Атакующий может слать тысячи запросов GetSlices в секунду. Каждый запрос заставляет узел (в другом потоке) читать с диска и сериализовать до 500 слайсов (до 2GB данных).
Эксплуатация:
Отправить поток сообщений GetSlices. Это вызовет перегрузку CPU, Disk I/O и пропускной способности (если узел начнет отвечать).
5. Rate Limit Bypass: Missing Checks
Файлы: net/protocol.rs, net/rate_limit.rs
Анализ:
Структура PeerRateLimits и проверки в protocol.rs покрывают только сообщения Addr, Inv, GetData.
Остальные сообщения не имеют ограничений:
Slice(4MB payload)Tx(1MB payload)PresenceGetSlices
Эксплуатация:
Атакующий может флудить сообщениями Slice (4MB каждый), что быстро заполнит канал событий (см. Memory Exhaustion) или забьет канал связи, так как проверка process_message происходит после вычитывания всего сообщения в память.