From 39312caac7d09bafa81820e514bac23376164fc4 Mon Sep 17 00:00:00 2001 From: wakolzin <63758930+wakolzin@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:25:09 +0300 Subject: [PATCH] kern_netfilter targets + fix nginx_docker fuzz script (#50) * - add kern_netfilter targets - fix nginx_docker fuzz.sh * minor upd kern_netfilter readme --- Examples/Crusher/Linux/README.md | 3 +- .../Crusher/Linux/kern_netfilter/README.md | 205 ++++++++++++++++++ Examples/Crusher/Linux/nginx_docker/fuzz.sh | 2 +- 3 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 Examples/Crusher/Linux/kern_netfilter/README.md diff --git a/Examples/Crusher/Linux/README.md b/Examples/Crusher/Linux/README.md index 053c31d..53b727a 100644 --- a/Examples/Crusher/Linux/README.md +++ b/Examples/Crusher/Linux/README.md @@ -18,7 +18,8 @@ 15) [nginx_docker](nginx_docker) - фаззинг сервера Nginx в Docker-режиме; 16) [OpenSSL_mod_client](OpenSSL_mod_client) - фаззинг OpenSSL-сервера методом модифицированного клиента; 17) [arm_rootfs_gzip](arm_rootfs_gzip) - фаззинг gzip из Ubuntu20 (ARM) с применением Qemu (user-mode); -17) [pytorch](pytorch) - фаззинг python-модуля pytorch. +17) [pytorch](pytorch) - фаззинг python-модуля pytorch; +18) [kern_netfilter](kern_netfilter) - фаззинг компонента ядра с использованием снимков памяти (снапшотов). Далее приведена последовательность действий по фаззингу, мониторингу и воспроизведению аварийных завершений (крешей) для следующих примеров: `python`, `jasper` и `faad`. diff --git a/Examples/Crusher/Linux/kern_netfilter/README.md b/Examples/Crusher/Linux/kern_netfilter/README.md new file mode 100644 index 0000000..a093e77 --- /dev/null +++ b/Examples/Crusher/Linux/kern_netfilter/README.md @@ -0,0 +1,205 @@ + +`netfilter` - компонент ядра, отвечающий за фильтрацию и перенаправление трафика. + +Рассмотрены примеры фаззинга `netfilter` с использованием снимков памяти виртуальной машины в двух режимах: +1. Статическая инструментация; +2. Динамическая инструментация (на основе технологии Intel PT). + +# 1. Введение +## 1.1. Снимки памяти (снапшоты) + +Для ускорения фаззинга используется технология снимков памяти (снапшотов) виртуальной машины. +Она позволяет: +- начинать выполнение программы с определённого состояния (без потерь времени на его достижение); +- завершать выполнение в указанных точках программы. + +Логика управления снапшотами реализована в виде снапшот-api. + +Снапшот-фаззинг можно выполнять в двух режимах: +1. Статическая инструментация (kcov). +При выполнении проинструментированного кода производится запись о соответствующих событиях в устройство `/dev/kcov`, +на основе чего заполняется битовая карта покрытия (стандартный способ получения обратной связи в AFL-совместимых фаззерах). +2. Динамическая инструментация с помощью аппаратных возможностей процессора Intel - Intel PT. + +Реализация снапшот-фаззинга в Crusher включает снапшот-api для управления снапшотами и совместима с Nyx-бэкэндом. + +## 1.2. Управление снапшотами + +Для достижения соответствующего состояния в `netfilter` в данных примерах используется утилита `conntrack`, +запуск которой в ВМ позволяет попасть в интересующий нас код ядра. + +Код ядра дополняется соответствующими вызовами снапшот-api, которые позволяют: +1. Поставить точки начала/конца снапшота; +2. Настроить передачу входных данных; +3. Настроить передачу информации о покрытии - битовой карты. + +# 2. Фаззинг + +Будет рассмотрен фаззинг `netfilter` в 2 вышеупомянутых режимах инструментации. + +Необходимо скачать фаззинг-цели (таргеты): https://dynamic.ispras.ru/ -> Linux -> examples -> kern_netfilter -> {target4.tar.gz, target7.tar.gz} +и распаковать. + +Таргеты: +1. `target4` (kcov): +- ядро с поддержкой kcov; +- пропатченный conntrack; +- снапшот в юзер-моде. + +2. `target7` (intel pt): +- пропатчено ядро: снапшоты + покрытие через intel pt; +- conntrack - оригинальный. + +Необходимо установить определённое ядро и KVM по данной инструкции - https://github.com/nyx-fuzz/KVM-Nyx + +## 2.1. Фаззинг-цель target4 + +### 2.1.1. Описание таргета + +См. target4/ + +**Ядро** + +См. target4/kern/ + +1. Код. +Ядро 4.15.3 + модельные ошибки. +linux-4.15.3_instr_4/ + +2. Сборка. +Скрипт `clean_kern-kcov.sh`. Инструментация встраивается в отдельные части, включая netfilter. +Собирать не требуется, готовое ядро - `linux-clean-bin/vmlinuz-4.15.3` + +**conntrack** + +См. target4/kern/conntrack-tools + +1. Код. +См. git-историю: +```shell +$ git diff f1ca2d9204996382411f4c93d4636a8ca8a46f44..d0e0927dc28d2162b5f5924a98043506bee3d88b +``` + +Патчи: +- поддержка kcov и общение с фаззером - `include/{kcov.h, nyx.h}`; +- снапшоты на уровне юзер-мода - `src/conntrack.c`: ksnap_start, ksnap_end, payload_buffer; +- для этого сделано snap_full api - `include/snap_full.h`. + +2. Сборка (уже выполнена): +```shell +cd conntrack-tools/build +make +``` + +Результат - бинарь `conntrack-tools/build/src/conntrack` + +**Запакованный таргет** +target4/target/ + +Для фаззинга в nyx-режиме таргет требуется специальным образом подготовить (запаковать). +Для этого предусмотрены т.н. пакеры. +Всё уже сделано, кроме указания правильных путей (будет далее): +- бинарь target - это собранный пропатченный conntrack (conntrack-tools/build/src/conntrack); +- fuzz.sh - в нём указана команда запуска `target -L`, которая позволит попасть в нужное состояние ВМ (точка снапшота); +- config.ron - конфиг таргета. + +В config.ron необходимо будет поменять далее путь до конфига `default_config_kernel.ron` (таких в фаззере несколько - для разных nyx-пакеров, нужен из пакера packer_4). + +В `crusher/nyx_mode/packer_4/packer/fuzzer_configs/default_config_kernel.ron` указано ранее собранное ядро. + +### 2.1.2. Фаззинг + +1. Подготовка +Перед запуском: +- поставьте актуальные пути в `crusher/nyx_mode/packer_4/packer/fuzzer_configs/default_config_kernel.ron` в полях qemu_binary, kernel и ramfs; +- поставьте актуальный путь до `default_config_kernel.ron` в `target/config.ron` (обратите внимание, что это путь в пакере packer_4). + +2. Запуск + +```shell +./crusher/bin_x86-64/fuzz_manager --start 20 -i in -o out \ + -I nyx -F --affinity --max-file-size 1 \ + --wait-next-instance 1000 -- ./target/ __DATA__ +``` + +Опции: +- `--start ` - ядра на fuzz и eat-процессы; +- `-i ` - папка с начальными входными данными; +- `-o ` - папка с результатами; +- `-I ` - тип инструментации; +- `-F` - очищать папку с предыдущими результатами; +- `--affinity` - привязка процессов (fuzz, eat) к определённым ядрам; +- `--max-file-size ` - ограничение на входные данные; +- `--wait-next-instance ` - ожидание перед запуском каждого fuzz/eat процесса. + +3. Мониторинг +Через UI: +```shell +./crusher/bin_x86-64/ui -o out +``` + +4. Анализ результатов +Сгенерированные входные данные - out/EAT_OUT/{queue, crashes, hangs} + +## 2.2. Фаззинг-цель target7 + +### 2.2.1. Описание таргета + +См. target7/ + +**Ядро** + +См. target7/kern/ + +1. Код. +Ядро 4.15.3 + патчи для снапшотов + встроенные ошибки. + +linux-4.15.3_instr/ + +См. `net/netfilter/nf_conntrack_netlink.c`: +1) управление снапшотами - ф-ции kern_snap_* +2) встроенный баг: +- в начале файла объявлена глобальная переменная magic; +- в неё записываются мутированные данные (см. код между `kern_snap_start` и `kern_snap_end`); +- если `magic == 4242`, то происходит сбой в ядре. + +2. Сборка (уже выполнена). +```shell +$ ./intelpt_7.sh +``` + +Готовое ядро - `linux-intelpt-bin/vmlinuz-4.15.3`. + +**Запакованный таргет** + +target7/target/ + +Аналогично предыдущему таргету, только `conntrack` не пропатченный, а оригинальный из системы. + +В `config.ron` необходимо будет поменять далее путь до конфига `default_config_kernel.ron` (таких в фаззере несколько - для разных nyx-пакеров, нужен из пакера packer_7). + +В `crusher/nyx_mode/packer_7/packer/fuzzer_configs/default_config_kernel.ron` указано ранее собранное ядро. + +### 2.2.2. Фаззинг + +1. Подготовка +Перед запуском: +- поставьте актуальные пути в `crusher/nyx_mode/packer_7/packer/fuzzer_configs/default_config_kernel.ron` в полях qemu_binary, kernel и ramfs. +- поставьте актуальный путь до `default_config_kernel.ron` в target/config.ron (обратите внимание, что это путь в пакере packer_4). + +2. Запуск + +```shell +./crusher/bin_x86-64/fuzz_manager --start 10 -i in -o out \ + -I nyx -F --affinity --max-file-size 1 \ + --wait-next-instance 1000 -- ./target/ __DATA__ +``` + +3. Мониторинг +Через UI: +```shell +./crusher/bin_x86-64/ui -o out +``` + +4. Анализ результатов +Сгенерированные входные данные - out/EAT_OUT/{queue, crashes, hangs} diff --git a/Examples/Crusher/Linux/nginx_docker/fuzz.sh b/Examples/Crusher/Linux/nginx_docker/fuzz.sh index eae31dc..874b4f8 100755 --- a/Examples/Crusher/Linux/nginx_docker/fuzz.sh +++ b/Examples/Crusher/Linux/nginx_docker/fuzz.sh @@ -4,5 +4,5 @@ if [ -z "$1" ] echo "Usage: fuzz.sh /path/to/crusher" else PATH_TO_CRUSHER=$(realpath -m $1) - $PATH_TO_CRUSHER/bin_x86-64/fuzz_manager --start 4 --eat-cores 2 --dse-cores 0 --pre-run ./docker/license/license.sh --wait-next-instance 2000 --ip 127.0.0.1 --port 8080 -I StaticForkSrv --bitmap-size 65536 -T NetworkTCP --delay 500 -t 1000 -F -i $PWD/in/ -o $PWD/out --docker nginx-demo --clean-binary /root/target/nginx-clean/sbin/nginx -- /root/target/nginx-fuzz/sbin/nginx + $PATH_TO_CRUSHER/bin_x86-64/fuzz_manager --start 4 --eat-cores 2 --dse-cores 0 --pre-run ./docker/license/license.sh --wait-next-instance 2000 --ip 127.0.0.1 --port 8080 -I StaticForkSrv --bitmap-size 65536 -T NetworkTCP --delay 3000 -t 10000 -F -i $PWD/in/ -o $PWD/out --docker nginx-demo --clean-binary /root/target/nginx-clean/sbin/nginx -- /root/target/nginx-fuzz/sbin/nginx fi