Rust, Хакинг на Rust

Курс — Хакинг на Rust. #31 Продвинутые темы. Интеграция с другими языками: Встраивание Rust в C/C++ проекты

Здравствуйте, дорогие друзья.

Rust и C/C++ часто называют «естественными союзниками». C/C++ доминируют в системном программировании, но их сложность управления памятью и уязвимости вроде переполнения буфера делают их рискованными для критичных к безопасности задач. Rust, с его системой владения и безопасностью на этапе компиляции, позволяет поэтапно модернизировать legacy-проекты, заменяя уязвимые компоненты без переписывания всего кода.

Примеры применения:

  • Ускорение «горячих» участков кода на C/C++ через Rust.
  • Замена уязвимых функций работы с памятью (например, strcpy → безопасный аналог на Rust).
  • Создание оберток для C-библиотек с автоматической проверкой безопасности.

Основы FFI: Foreign Function Interface

Rust предоставляет атрибут #[no_mangle] для предотвращения изменения имен функций компилятором и ключевое слово extern для указания внешнего ABI.

Пример 1: Экспорт функции из Rust в C

Компиляция в статическую библиотеку:

Использование в C++:

Работа с памятью и строками

Передача строк между языками требует осторожности. В C строки — это char*, в Rust — String или &str.

Пример 2: Возврат строки из Rust в C

В C:

Интеграция через bindgen: генерация оберток для C-кода

Утилита bindgen автоматически создает Rust-обертки для C-заголовков.

Пример 3: Использование bindgen для работы с OpenSSL

  1. Добавьте bindgen в Cargo.toml:

2. Создайте build.rs:

3. В wrapper.h:

Теперь в Rust можно вызывать функции OpenSSL:

Обработка ошибок

В C ошибки обычно возвращаются через коды, в Rust — через Result. Для совместимости можно преобразовать Result в целочисленные коды.

Пример 4: Возврат кода ошибки из Rust

В C:

Интеграция в CMake и Makefile

Для сборки проектов на C/C++ с использованием Rust-кода можно вызывать cargo из CMake:

CMakeLists.txt:

Безопасность и анти-паттерны

  • Избегайте unsafe без необходимости. Даже при работе с FFI старайтесь минимизировать его использование.
  • Проверяйте входные данные. Например, перед преобразованием *const u8 в срез, убедитесь, что указатель не нулевой и длина корректна.
  • Используйте ManuallyDrop для управления временем жизни объектов.

Пример из кибербезопасности: оптимизация фаззера

Предположим, у вас есть медленный фаззер на Python. Вы можете переписать его ядро на Rust и вызывать через FFI:

Rust-код (fuzzer_core.rs):

Python-код (с использованием ctypes):

Заключение

Интеграция Rust с C/C++ позволяет совместить высокую производительность и безопасность. Это особенно ценно в кибербезопасности, где ошибки управления памятью приводят к критическим уязвимостям. Начните с замены отдельных компонентов, используйте bindgen для автоматизации и всегда проверяйте входные данные в FFI-функциях.

Хакинг на языке программирования Rust

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

Цикл статей по курсу — «Хакинг на Rust».