Skip to content

Commit

Permalink
kern_netfilter targets + fix nginx_docker fuzz script (#50)
Browse files Browse the repository at this point in the history
* - add kern_netfilter targets
- fix nginx_docker fuzz.sh

* minor upd kern_netfilter readme
  • Loading branch information
wakolzin authored Apr 23, 2024
1 parent 3b38470 commit 39312ca
Show file tree
Hide file tree
Showing 3 changed files with 208 additions and 2 deletions.
3 changes: 2 additions & 1 deletion Examples/Crusher/Linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

Expand Down
205 changes: 205 additions & 0 deletions Examples/Crusher/Linux/kern_netfilter/README.md
Original file line number Diff line number Diff line change
@@ -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 <num>` - ядра на fuzz и eat-процессы;
- `-i <path>` - папка с начальными входными данными;
- `-o <path>` - папка с результатами;
- `-I <type>` - тип инструментации;
- `-F` - очищать папку с предыдущими результатами;
- `--affinity` - привязка процессов (fuzz, eat) к определённым ядрам;
- `--max-file-size <megabytes>` - ограничение на входные данные;
- `--wait-next-instance <milliseconds>` - ожидание перед запуском каждого 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}
2 changes: 1 addition & 1 deletion Examples/Crusher/Linux/nginx_docker/fuzz.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 39312ca

Please sign in to comment.