Курс — Хакинг на Rust. #21 Инструменты хакера на Rust. Фаззинг и тестирование на устойчивость. Инструменты: cargo-fuzz, afl.rs
Здравствуйте, дорогие друзья.
Фаззинг — метод тестирования, при котором программа подвергается потоку случайных, непредсказуемых входных данных (фазз-данных). Цель: вызвать краши, утечки памяти или некорректное поведение, чтобы обнаружить уязвимости. В Rust фаззинг особенно эффективен для:
- Обнаружения use-after-free и переполнений буфера в
unsafe
-коде. - Проверки обработки ввода (парсеры, сетевые протоколы).
Cargo-fuzz: фаззинг в экосистеме Rust
cargo-fuzz
— официальный инструмент на основе LLVM LibFuzzer, интегрированный в Cargo.
Установка и настройка
- Добавьте
cargo-fuzz
в зависимости:
1 |
cargo install cargo-fuzz |
2. Инициализируйте проект:
1 |
cargo fuzz init |
- Это создаст директорию
fuzz
с примером таргета.
Пример: фаззинг парсера JSON
Пусть есть функция parse_json(input: &str) -> Result<(), &str>
. Создадим фазз-таргет:
1 2 3 4 5 6 7 |
// fuzz/fuzz_targets/parse_json.rs #![no_main] use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &str| { let _ = my_parser::parse_json(data); }); |
Запуск фаззинга
1 |
cargo fuzz run parse_json |
cargo-fuzz
генерирует входные данные, пока не найдёт краш или не превысит лимиты.
Анализ результатов
При краше создаётся тест-кейс в fuzz/artifacts
. Пример вывода:
1 |
==4242==ERROR: AddressSanitizer: heap-buffer-overflow on address... |
AFL.rs: American Fuzzy Lop для Rust
AFL — легендарный фаззер, использующий генетические алгоритмы для мутации входных данных. В Rust его можно использовать через afl.rs
.
Установка и настройка
- Установите AFL:
1 |
cargo install afl |
2. Настройте Cargo.toml
для инструментария AFL:
1 2 3 4 5 |
[package] build = "build.rs" [dependencies] afl = "0.7" |
Пример: фаззинг обработчика CSV
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// src/main.rs use std::fs::File; use std::io::Read; fn process_csv(data: &[u8]) { // Уязвимый код: некорректная обработка длины строки let mut buffer = [0u8; 8]; unsafe { std::ptr::copy(data.as_ptr(), buffer.as_mut_ptr(), data.len()); } } #[cfg(test)] mod tests { extern crate afl; use super::*; #[test] fn afl_fuzz() { afl::read_stdio_bytes(|data| { process_csv(&data); }); } } |
Запуск AFL
1 2 |
cargo afl build cargo afl fuzz -i in_dir -o out_dir target/debug/my_app |
AFL проанализирует входные данные из in_dir
и сохранит результаты в out_dir
.
Сравнение cargo-fuzz и afl.rs
КРИТЕРИЙ | CARGO-FUZZ | AFL.RS |
Интеграция | Встроен в Cargo | Требует отдельной настройки |
Скорость | Быстрый (LLVM) | Медленнее, но умные мутации |
Кастомизация | Ограниченная | Гибкая (например, persistent mode) |
Поддержка | Официальная | Сообщество |
Лучшие практики
- Минимизация тест-кейсов:
Используйтеcargo fuzz cmin
для уменьшения размера краш-образцов. - Покрытие кода:
Включите сбор метрик покрытия:
1 |
cargo fuzz coverage parse_json |
- Обработка паник:
Добавьтеpanic = "abort"
вCargo.toml
, чтобы фаззер фиксировал паники.
Этический контекст
Фаззинг может быть использован как для защиты, так и для атак. Правила:
- Только свои проекты или с разрешения.
- Ответственное раскрытие: Сообщайте найденные уязвимости разработчикам.
Задание для самостоятельной работы:
- Настройте фаззинг для собственной функции, обрабатывающей бинарные данные.
- Сравните скорость
cargo-fuzz
иafl.rs
на одном и том же коде. - Используйте
afl.rs
в persistent mode для ускорения тестирования.
Итог:
Фаззинг — критически важный этап разработки безопасного ПО. cargo-fuzz
и afl.rs
делают процесс удобным даже для сложных Rust-проектов. Помните: чем больше непредсказуемых данных вы проверите, тем выше шанс найти уязвимость до злоумышленников.

На этом все. Всем хорошего дня!