• [ Регистрация ]Открытая и бесплатная
  • Tg admin@ALPHV_Admin (обязательно подтверждение в ЛС форума)

Статья Фаззим JS-движки при помощи Fuzzilli

stihl

Moderator
Регистрация
09.02.2012
Сообщения
1,178
Розыгрыши
0
Реакции
510
Deposit
0.228 BTC
stihl не предоставил(а) никакой дополнительной информации.
Сегодня в меню макароны! Точнее, наглядная демонстрация того, как использовать фаззер Fuzzilli, чтобы искать уязвимости в движках JavaScript. Теории будет всего чуть‑чуть, сосредоточимся на практике. Быстренько соберем необходимый инструментарий, а затем приступим к поиску багов при помощи фаззинга.
Раньше фаззить движки JavaScript (те самые, что позволяют делать в браузере падающий снег или разрабатывать бэкенды на Node.js) было сложно. Мутации JS-кода приводили к синтаксическим ошибкам, что серьезно замедляло работу. Семплы отбрасывались движком, и приходилось генерировать новые и новые. На помощь пришли фаззеры на основе грамматики, но их применение тоже не назовешь легким.

В 2019 году исследователь безопасности Для просмотра ссылки Войди или Зарегистрируйся публично открыл свою разработку — фаззер Fuzzilli. Идея была в том, чтобы вместо JavaScript генерировать подобие байт‑кода, которое будет проще подвергать мутациям. Собственно, хоть в названии и обыгран сорт пасты, происходит оно от FuzzIL — Fuzzing Intermediate Language, промежуточный язык для фаззинга.


Для просмотра ссылки Войди или Зарегистрируйся

Стенд​

Для стенда нам понадобится виртуальная машина на Linux. Можно скачать готовую виртуалку с сайта Для просмотра ссылки Войди или Зарегистрируйся, выбрав дистрибутив по вкусу. Я в статье буду использовать Ubuntu 22.

Чем больше ты выделишь виртуалке ресурсов, тем лучше. Фаззер показывает покрытие кода, и в зависимости от мощности машины на весь движок может уйти от одного дня до нескольких недель.

Из инструментов понадобится Git, язык программирования Swift (не путать с певицей), а также весь тулчейн, нужный для сборки JS-движка. Но об этом поговорим чуть позже.

Пока же запускай виртуалку и вводи свой пароль.

Password=osboxes.org
echo $Password | sudo -S apt update
sudo apt upgrade -y
Update и upgrade

JavaScript-движки​

Основные части движка JavaScript — это парсер, интерпретатор и компилятор.

JS-пайплайн
Все начинается с парсинга исходного кода на JavaScript. Строится абстрактное синтаксическое дерево (AST). На его основе создается байт‑код. Затем интерпретатор выполняет байт‑код.

Во время выполнения записывается разная информация — profiling data. В дальнейшем она используется при компиляции байт‑кода в машинный. Этим занимается компилятор.

Машинный код генерируется в тех случаях, когда какой‑то участок часто используется. Например, функция выполняется в цикле. Тогда выгоднее потратить время на его компиляцию и в дальнейшем выиграть во времени выполнения (ведь интерпретация идет медленнее).

Обычно применяется несколько компиляторов, и выбор происходит в зависимости от уровня оптимизации кода.

www​

Подробнее о работе движков JS — в презентации «JavaScript engines: The Good Parts» (Для просмотра ссылки Войди или Зарегистрируйся).

Подготовка фаззера​

Fuzzilli поставляется в виде исходного кода, написанного на языке Swift.

Для скачивания исходников понадобится Git, для сборки Fuzzilli — пакеты GCC, Binutils и, конечно, исходники фаззера. Ставим зависимости и клонируем репозиторий Fuzzilli.

Код:
Password=osboxes.org
echo $Password | sudo -S apt update
sudo apt install git binutils gcc -y
git clone https://github.com/googleprojectzero/fuzzilli
Клонируем репозиторий

Теперь переходим на сайт Swift в раздел Для просмотра ссылки Войди или Зарегистрируйся и ищем релиз для своего дистрибутива. Для Ubuntu 22 качаем релиз Для просмотра ссылки Войди или Зарегистрируйся.

Swift

Распаковываем архив и копируем папку usr, чтобы установить Swift. После этого убеждаемся, что все корректно настроено.

Вот мини‑скрипт для ленивых. Если читаешь эту статью спустя много лет, поменяй переменные SwiftUrl на соответствующий URL со страницы Swift.

Код:
# Установка Swift
Password=osboxes.org
SwiftUrl=https://download.swift.org/swift-5.8.1-release/ubuntu2204/swift-5.8.1-RELEASE/swift-5.8.1-RELEASE-ubuntu22.04.tar.gz
SwiftTar=$(echo $SwiftUrl | sed 's:.*/::')
SwiftFolder=${SwiftTar%.tar.gz}
# Переходим домой
cd $HOME
# Качаем архив
wget $SwiftUrl
# Извлекаем
tar -xzf $SwiftTar
# Устанавливаем
echo $Password | sudo -S cp -r $SwiftFolder/usr /
# Удаляем архив
rm $SwiftTar
# Удаляем папку
rm -rf $SwiftFolder
# Тестовый запуск
swift --version

Установка Swift

Теперь мы готовы к сборке фаззера. Переходим в папку Fuzzilli и запускаем сборку.

cd fuzzilli && swift build -c release
Собираем Fuzzilli
Фаззер готов. Можно почитать раздел помощи, если есть желание.

swift run -c release FuzzilliCli --help
Переходим к подготовке JS-движков. На главной странице репозитория инструкция гласит: «Скачайте исходный код движка. Скомпилируйте его, как описано в инструкции к нему в папке Targets». Для каждого движка там есть отдельная папка, в которой указано, как собрать движок для фаззинга.


Сборка и фаззинг V8​


Теория​

Начнем с движка браузера Google Chrome, он называется V8. Это движок JavaScript и WebAssembly, разработанный в Google, распространяется с открытым исходным кодом, написан на C++. Используется в Chrome, Node.js и множестве дериватив Chrome.

Разработали этот движок в датском городе Орхус, а ведущего разработчика зовут Ларс Бак. Бак занимался разработкой языка Self, а также HotSpot — виртуальной машины Java. Поэтому многое из наработок Self перекочевало в V8. Например, та же JIT-компиляция или «карты» объектов (maps).

www​

Подробнее — в научной работе, которая легла в основу Self: «An Efficient Implementation of SELF, a Dynamically-Typed Object-Oriented Language Based on Prototypes» (Для просмотра ссылки Войди или Зарегистрируйся).
Движок состоит из интерпретатора Ignition, неоптимизирующего компилятора Sparkplug и оптимизирующего компилятора TurboFan.

Пайплайн V8

Сборка​

В папке Для просмотра ссылки Войди или Зарегистрируйся нам предлагают следовать Для просмотра ссылки Войди или Зарегистрируйся с сайта. Но я не буду утомлять ими, а скомпилирую все в один мини‑скрипт.

Код:
# Подготовка и сборка V8
Password=osboxes.org
echo $Password | sudo -S apt update
# Переходим домой
cd $HOME
# Качаем репозиторий depot_tools
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
# Добавляем в PATH
echo "PATH=$HOME/depot_tools:$PATH" >> ~/.bashrc
source ~/.bashrc
# Качаем исходники
gclient
fetch v8
cd v8/
gclient sync
# Ставим зависимости (update — так как скрипт попросит ввести пароль)
echo $Password | sudo -S apt update
./build/install-build-deps.sh
# Билдим при помощи скрипта из папки фаззера
$HOME/fuzzilli/Targets/V8/fuzzbuild.sh

Сборка V8

Скрипт переходит в домашний каталог пользователя, затем ставит depot_tools (для скачивания и сборки V8), качает и компилирует исходный код движка V8. Сборка займет какое‑то время, зависит от ресурсов машины. Можешь пока сделать небольшую разминку.

Для просмотра ссылки Войди или Зарегистрируйся

Фаззинг​

Приступаем наконец к самому фаззингу. Для этого нужно выполнить следующую команду:

Код:
# Запускаем Fuzzilli
# Отключаем дампы
echo $Password | sudo -S sysctl -w 'kernel.core_pattern=|/bin/false'
# Переходим в папку Fuzzilli
cd $HOME/fuzzilli
# Запускаем
swift run -c release FuzzilliCli --profile=v8 --resume --storagePath=$HOME/fuzzilli-storage-v8 $HOME/v8/out/fuzzbuild/d8

Начинаем фаззить V8

Основные настройки — это профиль движка (--profile=v8), возврат к предыдущей сессии фаззинга (--resume) и хранилище, куда фаззер будет сохранять свои данные (--storagePath). Там будут храниться найденные краши, корпус семплов и прочая информация.

Периодически он будет выводить статистику фаззинга. В основном интересны количество найденных крашей (Crashes Found) и процент покрытия кода (Coverage).

Статус фаззинга

Сборка и фаззинг SpiderMonkey​


Теория​

Переходим к JavaScript-двиглу Firefox.

SpiderMonkey — это потомок первого в мире движка JavaScript. Его релиз состоялся аж в 1995 году! Изначально он разработан Бренданом Айком в компании Netscape. Первые версии были написаны на C, но в дальнейшем код переписали на C++.

Вот структура SpiderMonkey. Парсер производит байт‑код. Интерпретатор JavaScript этот байт‑код выполняет. Baseline-интерпретатор занимается созданием Для просмотра ссылки Войди или Зарегистрируйся. Baseline-компилятор создает неоптимизированный машинный код. WarpMonkey — оптимизированный машинный код.

Пайплайн SpiderMonkey

Сборка​

В Для просмотра ссылки Войди или Зарегистрируйся пишут, что нужно просто клонировать репозиторий Gecko и запустить fuzzbuild.

Но на самом деле надо применить патчи из папки Patches. И только после этого билдить. К тому же запускать fuzzbuild нужно не из js/src, а из рута gecko-dev.

Для просмотра ссылки Войди или Зарегистрируйся
Что ж, приступаем. Нам понадобится curl и компилятор Rust для сборки движка.

Код:
# Подготовка и сборка SpiderMonkey
Password=osboxes.org
cd $HOME
# Ставим curl
echo $Password | sudo -S apt install curl -y
# Ставим Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o install.sh
sh ./install.sh -y
source "$HOME/.cargo/env"
# Клонируем
git clone https://github.com/mozilla/gecko-dev.git
# Заходим
cd gecko-dev/js/src
# Патчим
git apply $HOME/fuzzilli/Targets/Spidermonkey/Patches/*
cd $HOME/gecko-dev
# Собираем
$HOME/fuzzilli/Targets/Spidermonkey/fuzzbuild.sh

Rust установлен Билдим

Фаззинг​

После того как движок собран, можем запустить фаззинг из папки fuzzilli. Команды запуска и параметры фаззера те же, кроме профиля и исполняемого файла.

Код:
# Запуск Fuzzilli
# Отключаем дампы
echo $Password | sudo -S sysctl -w 'kernel.core_pattern=|/bin/false'
# Переходим в папку Fuzzilli
cd $HOME/fuzzilli
# Запускаем
swift run -c release FuzzilliCli --profile=spidermonkey --resume --storagePath=$HOME/fuzzilli-storage-sm $HOME/gecko-dev/obj-fuzzbuild/dist/bin/js

Фаззим SpiderMonkey

Сборка и фаззинг JavaScriptCore​

Ну и наконец, JavaScriptCore — JavaScript-движок браузера Safari.


Теория​

Вообще, можно сказать, что это потомок JavaScript-движка KJS из браузера Konqueror, входящего в KDE. Проект WebKit стартовал в 2001 году как форк от KHTML и KJS.

Пайплайн у него самый сложный, четырехуровневый.
  • LLint или Low Level Interpreter — это просто интерпретатор байт‑кода, сгенерированного из исходного кода JavaScript.
  • Далее идет немного оптимизирующий компилятор Baseline. Оба они собирают информацию, необходимую для дальнейших оптимизаций машинного кода.
  • Следующий компонент — DFG JIT (Data Flow Graph Just In Time). Он отвечает за повышение оптимизации машинного кода.
  • Ну и FTL JIT (Faster Than Light), генерирует наиболее оптимизированный машинный код.
Пайплайн KJS

Сборка​

Смотрим, что пишут в Для просмотра ссылки Войди или Зарегистрируйся по поводу JavaScriptCore.

Для просмотра ссылки Войди или Зарегистрируйся
Нужно клонировать код из репозитория WebKit, накатить патчи и запустить fuzzbuild.sh. Для сборки потребуется установить Clang и зависимости. В папке Tools есть готовые скрипты для этого. Качаем, ставим все необходимое, патчим, билдим. Как обычно, вот скрипт:

Код:
# Подготовка и сборка JavaScriptCore
Password=osboxes.org
cd $HOME
# Качаем исходный код
git clone https://github.com/WebKit/WebKit.git
# Ставим зависимости
cd WebKit
echo $Password | sudo -S apt update
sudo apt install clang -y
Tools/gtk/install-dependencies
# Патчим
git apply ../fuzzilli/Targets/JavaScriptCore/Patches/*
# Билдим
$HOME/fuzzilli/Targets/JavaScriptCore/fuzzbuild.sh

Сборка JSC

Фаззинг​

Когда сборка движка будет закончена, можем запускать фаззинг. Поехали!

Код:
# Запуск Fuzzilli
# Отключаем дампы
echo $Password | sudo -S sysctl -w 'kernel.core_pattern=|/bin/false'
# Переходим в папку Fuzzilli
cd $HOME/fuzzilli
# Запускаем
swift run -c release FuzzilliCli --profile=jsc --resume --storagePath=$HOME/fuzzilli-storage-jsc $HOME/WebKit/FuzzBuild/Debug/bin/jsc

Фаззинг JavaScriptCore
Все работает. Осталось дождаться интересных крашей!


Выводы​

Я постарался рассказать всю необходимую теорию о фаззинге, а также мы подготовили платформу для фаззинга трех основных движков JavaScript. Однако Fuzzilli умеет работать и с другими движками (достаточно заглянуть в папку Для просмотра ссылки Войди или Зарегистрируйся):

  • JerryScript;
  • QuickJS;
  • Qt QJSEngine;
  • XS;
  • duktape.
Их можешь попробовать пофаззить самостоятельно.
 
Activity
So far there's no one here