Переведено специально для xss.pro by Stalker
Оригинальная статья
Вступление
В этом посте мы рассмотрим, как мы обнаружили CVE-2019-13504 в exiv2 и CVE-2019-13503 в mongoose, два относительно широко используемых проекта oss.
Exiv2 - это набор «библиотеки метаданных C++ и инструментов…, используемых во многих проектах, включая KDE, Gnome Desktop, а также во многих других приложениях, включая GIMP, Darktable, shotwell, GwenView и Luminance HDR» (цитируется с их сайта). Исправление этой проблемы было произведено довольно быстро и в целом в хорошем состоянии.
Mongoose - это встроенная библиотека веб-сервера, которая, вероятно, используется некоторыми другими проектами с открытым исходным кодом, а также коммерческими проектами. Ошибка никогда не была исправлена (по крайней мере, во время написания), и похоже, что проект oss не очень хорошо поддерживается, хотя он относительно популярен, по крайней мере, по количеству звезд в их github.
Обе ошибки были найдены с помощью фаззинга, и мы пройдем процесс установки правильного фаззера, компиляции, запуска и поиска ошибки, а также покажем, как разные настройки / фаззер будут иметь разные результаты.
AFL против libFuzzer
Есть много хороших фаззеров для приложений. Некоторыми из наиболее заметных из них являются AFL и libFuzzer, которые работают как управляемые фаззеры для приложений C / C++. Мы не будем обсуждать бинарное размытие (как afl-qemu, afl-unicorn) здесь, так как мы больше сосредоточены на обсуждении фаззинга как части цикла разработки, где обычно доступен исходный код.
Оба фаззера очень хороши с точки зрения фаззинг двигателя / эвристики, но имеют некоторые различия.
AFL обычно проще в настройке, и он может работать с вашей «основной» командной строкой из коробки. Это выгодно как для разработчиков, так и для исследователей безопасности, которые проводят множество проектов и пытаются найти уязвимости.
libFuzzer является частью проекта инфраструктуры компилятора LLVM и поставляется со встроенным компилятором clang. Хотя для установки libFuzzer требуется немного больше работы, он идеально подходит для фаззирования определенных вызовов API в библиотеке, а также для лучшей поддержки различных средств защиты. Вы можете увидеть базовый пример на их сайте, а также наш пример для exiv2 и mongoose в этом посте.
Также можно использовать механизм AFL при использовании целевой функции, как в libFuzzer. Мы не будем рассказывать, как это сделать в посте.
Exiv2 - настройка AFL
Мы покажем простой пример того, как настроить AFL для exiv2 (эта часть не найдет никаких уязвимостей, по крайней мере, не быстро, вы можете перейти к следующему разделу, если хотите вызвать ошибку). Следующие инструкции были протестированы на Ubuntu: 18.04 - вы можете использовать docker run -it ubuntu: 18.04 / bin / bash и пройтись по инструкциям.
Это создаст инструментированный двоичный файл AFL exiv2 (с уязвимой версией, так как версия уже исправлена в master). Как только вы запустите afl fuzzer, он не найдет никаких уязвимостей, по крайней мере, недостаточно быстро, либо из-за того, что кто-то уже выполнил эту точную настройку фаззинга, либо из-за того, что на этом пути не было «низко висящих» ошибок.
Мы также скомпилировали цель с помощью AFL_USE_ASAN, но она дала аналогичные результаты (процесс тот же, просто используйте 32-битный двоичный файл или увеличьте предел памяти). Позже мы также покажем, что сбой, обнаруженный libFuzzer, не повлиял на утилиту командной строки.
Exiv2 - настройка libFuzzer
Фаззинга с AFL недостаточно, как мы увидим в этом разделе, особенно для библиотеки. Поскольку библиотека не обязательно используется командной строкой, но используется API, экспортируемыми библиотекой, которые могут иметь немного другой код. Это также, где сила libFuzzer вступает в игру.
Фаззер доступен в PR, который мы предоставили, и скоро будет объединен. В то же время вы можете увидеть реализацию этого здесь.
Ниже приведена инструкция для сборки и запуска цели libFuzzer («target» или «harness» - это реализуемая вами функция, вызываемая фаззером).
Довольно быстро вы увидите переполнение кучи-буфера с размером READ 4 от ASAN
Мы также можем дважды проверить, что этот сбой действительно не влияет на командную строку exiv2 через ./bin/exiv2 ./crash, где мы получаем вывод «не удалось прочитать изображение», а не вывод ASAN из-за незначительной разницы в коде инструмент командной строки и экспортированный API.
Следовательно, это хороший пример того, почему важно фаззирование экспортированных API-функций в библиотеках C /C++. Также с точки зрения лучшей практики важно не только выполнять однократное фаззирование, но и иметь постоянное фаззирование на месте, где новый код «фаззирован» (новый глагол
) каждый раз, когда он вводится в мастер, точно так же, как модульный тест ,
Mongoose
Вы можете проверить наш pull-запрос, который вообще не был адресован, по крайней мере, на момент написания.
Мы не будем рассказывать, как настроить фаззер, так как он похож на exiv2, и вы можете посмотреть инструкции в pull-запросе.
Mongoose - хороший пример, когда сложно настроить фаззинг с помощью AFL, так как нет двоичного кода, как в exiv2 или другом инструменте командной строки. Это хороший пример, когда libfuzzer может вступить в игру и использовать экспортируемые / опасные функции fuzz, которые обычно включают в себя некоторый анализ, например mg_parse_http, в случае mongoose.
Оригинальная статья
Вступление
В этом посте мы рассмотрим, как мы обнаружили CVE-2019-13504 в exiv2 и CVE-2019-13503 в mongoose, два относительно широко используемых проекта oss.
Exiv2 - это набор «библиотеки метаданных C++ и инструментов…, используемых во многих проектах, включая KDE, Gnome Desktop, а также во многих других приложениях, включая GIMP, Darktable, shotwell, GwenView и Luminance HDR» (цитируется с их сайта). Исправление этой проблемы было произведено довольно быстро и в целом в хорошем состоянии.
Mongoose - это встроенная библиотека веб-сервера, которая, вероятно, используется некоторыми другими проектами с открытым исходным кодом, а также коммерческими проектами. Ошибка никогда не была исправлена (по крайней мере, во время написания), и похоже, что проект oss не очень хорошо поддерживается, хотя он относительно популярен, по крайней мере, по количеству звезд в их github.
Обе ошибки были найдены с помощью фаззинга, и мы пройдем процесс установки правильного фаззера, компиляции, запуска и поиска ошибки, а также покажем, как разные настройки / фаззер будут иметь разные результаты.
AFL против libFuzzer
Есть много хороших фаззеров для приложений. Некоторыми из наиболее заметных из них являются AFL и libFuzzer, которые работают как управляемые фаззеры для приложений C / C++. Мы не будем обсуждать бинарное размытие (как afl-qemu, afl-unicorn) здесь, так как мы больше сосредоточены на обсуждении фаззинга как части цикла разработки, где обычно доступен исходный код.
Оба фаззера очень хороши с точки зрения фаззинг двигателя / эвристики, но имеют некоторые различия.
AFL обычно проще в настройке, и он может работать с вашей «основной» командной строкой из коробки. Это выгодно как для разработчиков, так и для исследователей безопасности, которые проводят множество проектов и пытаются найти уязвимости.
libFuzzer является частью проекта инфраструктуры компилятора LLVM и поставляется со встроенным компилятором clang. Хотя для установки libFuzzer требуется немного больше работы, он идеально подходит для фаззирования определенных вызовов API в библиотеке, а также для лучшей поддержки различных средств защиты. Вы можете увидеть базовый пример на их сайте, а также наш пример для exiv2 и mongoose в этом посте.
Также можно использовать механизм AFL при использовании целевой функции, как в libFuzzer. Мы не будем рассказывать, как это сделать в посте.
Exiv2 - настройка AFL
Мы покажем простой пример того, как настроить AFL для exiv2 (эта часть не найдет никаких уязвимостей, по крайней мере, не быстро, вы можете перейти к следующему разделу, если хотите вызвать ошибку). Следующие инструкции были протестированы на Ubuntu: 18.04 - вы можете использовать docker run -it ubuntu: 18.04 / bin / bash и пройтись по инструкциям.
Код:
# install git, cmake, zlib, libexpat
apt update && apt install -y git build-essential cmake zlib1g-dev libexpat1-dev
# install afl
git clone https://github.com/mirrorer/afl
cd afl
make && make install
cd ..
# Download and compile the vulnerable exiv2 version (as it's already fixed in master)
git clone https://github.com/fuzzitdev/exiv2 --branch libfuzzer_integration_vanilla exiv2
cd exiv2
export CC=`which afl-gcc`
export CXX=`which afl-g++`
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
# Run AFL
mkdir in
mkdir out
# just use random png for the seed corpus
wget -O in/1.png https://www.fnordware.com/superpng/pnggrad8rgb.png
afl-fuzz -i in -o out ./bin/exiv2 @@
Это создаст инструментированный двоичный файл AFL exiv2 (с уязвимой версией, так как версия уже исправлена в master). Как только вы запустите afl fuzzer, он не найдет никаких уязвимостей, по крайней мере, недостаточно быстро, либо из-за того, что кто-то уже выполнил эту точную настройку фаззинга, либо из-за того, что на этом пути не было «низко висящих» ошибок.
Мы также скомпилировали цель с помощью AFL_USE_ASAN, но она дала аналогичные результаты (процесс тот же, просто используйте 32-битный двоичный файл или увеличьте предел памяти). Позже мы также покажем, что сбой, обнаруженный libFuzzer, не повлиял на утилиту командной строки.
Exiv2 - настройка libFuzzer
Фаззинга с AFL недостаточно, как мы увидим в этом разделе, особенно для библиотеки. Поскольку библиотека не обязательно используется командной строкой, но используется API, экспортируемыми библиотекой, которые могут иметь немного другой код. Это также, где сила libFuzzer вступает в игру.
Фаззер доступен в PR, который мы предоставили, и скоро будет объединен. В то же время вы можете увидеть реализацию этого здесь.
Ниже приведена инструкция для сборки и запуска цели libFuzzer («target» или «harness» - это реализуемая вами функция, вызываемая фаззером).
Код:
# install git, cmake, zlib, libexpat, clang-8
apt update && apt install -y git build-essential cmake zlib1g-dev libexpat1-dev clang-8
# Download the vulnerable code with the libFuzzer targets
git clone https://github.com/fuzzitdev/exiv2 --branch libfuzzer_integration_vanilla exiv2
cd exiv2
# Compile the libFuzzer targets
mkdir build
cd build
export CXX=clang++-8
Export CC=clang-8
cmake .. -G "Unix Makefiles" "-DEXIV2_BUILD_FUZZ_TESTS=ON" "-DEXIV2_TEAM_USE_SANITIZERS=ON"
make -j4
# Run the libFuzzer Target
./bin/read-metadata -exact_artifact_path=crash
Довольно быстро вы увидите переполнение кучи-буфера с размером READ 4 от ASAN
Мы также можем дважды проверить, что этот сбой действительно не влияет на командную строку exiv2 через ./bin/exiv2 ./crash, где мы получаем вывод «не удалось прочитать изображение», а не вывод ASAN из-за незначительной разницы в коде инструмент командной строки и экспортированный API.
Следовательно, это хороший пример того, почему важно фаззирование экспортированных API-функций в библиотеках C /C++. Также с точки зрения лучшей практики важно не только выполнять однократное фаззирование, но и иметь постоянное фаззирование на месте, где новый код «фаззирован» (новый глагол
Mongoose
Вы можете проверить наш pull-запрос, который вообще не был адресован, по крайней мере, на момент написания.
Мы не будем рассказывать, как настроить фаззер, так как он похож на exiv2, и вы можете посмотреть инструкции в pull-запросе.
Mongoose - хороший пример, когда сложно настроить фаззинг с помощью AFL, так как нет двоичного кода, как в exiv2 или другом инструменте командной строки. Это хороший пример, когда libfuzzer может вступить в игру и использовать экспортируемые / опасные функции fuzz, которые обычно включают в себя некоторый анализ, например mg_parse_http, в случае mongoose.
Последнее редактирование модератором: