Skip to content

Commit

Permalink
Пример фаззинга pytorch (python-модуль) (#49)
Browse files Browse the repository at this point in the history
* pytorch target

* update pytorch target

* update pytorch target

* update pytorch target
  • Loading branch information
wakolzin authored Jan 12, 2024
1 parent ee16173 commit 3b38470
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 1 deletion.
3 changes: 2 additions & 1 deletion Examples/Crusher/Linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
14) [c#](csharp) - фаззинг dll библиотек, написанных на C#, через файл и stdin;
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) [arm_rootfs_gzip](arm_rootfs_gzip) - фаззинг gzip из Ubuntu20 (ARM) с применением Qemu (user-mode);
17) [pytorch](pytorch) - фаззинг python-модуля pytorch.

Далее приведена последовательность действий по фаззингу, мониторингу и воспроизведению аварийных завершений (крешей) для следующих примеров: `python`, `jasper` и `faad`.

Expand Down
54 changes: 54 additions & 0 deletions Examples/Crusher/Linux/pytorch/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
FROM ubuntu:20.04

RUN apt update \
&& apt upgrade -y \
&& apt install -y wget build-essential checkinstall zlib1g-dev zip \
gcc g++ gcc-multilib g++-multilib make sudo git wget libreadline-dev \
zlib1g-dev bison flex libfl-dev acl python3 gnupg2 aha llvm-12 clang-12 libssl-dev lcov

RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-12 0 \
&& update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-12 0 \
&& update-alternatives --install /usr/bin/llvm-profdata llvm-profdata /usr/bin/llvm-profdata-12 0 \
&& update-alternatives --install /usr/bin/llvm-cov llvm-cov /usr/bin/llvm-cov-12 0 \
&& update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-12 0

RUN apt update && apt install -y libbfd-dev libunwind-dev libffi-dev
RUN cd /tmp && wget http://archive.ubuntu.com/ubuntu/pool/main/libf/libffi/libffi6_3.2.1-8_amd64.deb && dpkg -i libffi6_3.2.1-8_amd64.deb && rm -rf libffi6_3.2.1-8_amd64.deb

WORKDIR /deps

# LZ4-devel
RUN apt-get install -y liblz4-dev

# Set Timezone or get hang during the docker build...
ENV TZ=Europe/Moscow
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# Packages for neural networks
RUN apt install -y python3-pip
RUN pip3 install tensorflow && \
pip3 install numpy && \
pip3 install imageio

ENV BASH_ENV=/venv3.8/bin/activate

WORKDIR /

RUN apt update \
&& apt install -y libglib2.0-0

# Libcurl
RUN apt-get update \
&& apt-get install -y libcurl4-openssl-dev

#install setuptools
RUN pip3 install setuptools

# Extra deps
RUN apt install -y nano

# Fuzz-target
RUN mkdir /root/fuzz
WORKDIR /root/fuzz
COPY torch_load_fuzz.py torch_load_fuzz.py
COPY in/ in/
73 changes: 73 additions & 0 deletions Examples/Crusher/Linux/pytorch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
## 1. Фаззинг-цель

Фаззинг Python-библиотеки `torch`.
В качестве целевого выбран метод `load()`, который загружает сериализованную PyTorch-модель.
Фаззинг-цель - [torch_load_fuzz.py](torch_load_fuzz.py).

Вызов `atheris.instrument_imports()` обеспечивает инструментацию модуля `torch`, а декоратор `atheris.instrument_func` - ф-ции `TestOneInput`.

Подробнее про фаззинг приложений на языке Python - см. раздел "Инструментация Python" в документации к Crusher.

## 2. Подготовка к фаззингу

### 2.1. Сборка докер-образа.

Фаззинг будет проводиться в докер-контейнере на основе образа, собранного следующей командой:
```shell
$ docker build -f Dockerfile -t pytorch-fuzz .
```

В докер устанавливаются зависимости, а также копируются необходимые для фаззинга файлы, включая фаззинг-цель и корпус начальных входных данных, который состоит из файла `model` - сериализованная PyTorch-модель, созданная на основе данного примера - https://pytorch.org/tutorials/beginner/saving_loading_models.html

### 2.2. Подготовка докер-контейнера:

1. Создание контейнера:
```shell
$ docker run --name pytorch-fuzz --rm --privileged \
--network host -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 \
-v /path/to/crusher/:/opt/crusher \
-ti pytorch-fuzz:latest /bin/bash
```

Обратите внимание, что в контейнер монтируется директория с фаззером в качестве докер-вольюма (`-v`).


2. Необходимо дополнительно установить atheris (с применением соответствующих патчей) в python3 фаззера и зависимости фаззинг-цели:
```shell
$ /opt/crusher/tools/install_atheris.sh
$ /opt/crusher/bin_x86-64/python-3.9_x86_64/bin/pip3 install numpy torch
```

## 3. Фаззинг

1. Запуск фаззинга.

```shell
$ /opt/crusher/bin_x86-64/fuzz_manager --start 4 --eat-cores 2 \
--dse-cores 0 -I pyinst -i in/ -o out -t 120000 \
-- ./torch_load_fuzz.py @@
```

Опции фаззера:

* `--start <num>` - число fuzz-процессов (экземпляры фаззинга);
* `--eat-cores <num>` - число eat-процессов (процессы доп. анализа);
* `--dse-cores <num>` - число dse-процессов (динамическое символьное выполнение), в данном режиме не поддерживается;
* `-I <type>` - тип инструментации;
* `-i <path>` - путь до директории с начальными образцами входных данных;
* `-o <path>` - путь к выходной директории с результатами фаззинга;
* `-t <milliseconds>` - таймаут на запуск приложения (в миллисекундах).

В данном примере указан довольно большой таймаут, т.к. инструментация фаззинг-цели выполняется долго, но только 1 раз - в начале фаззинга.

2. Мониторинг.

Запустите в другом терминале `UI` фаззера:
```shell
$ docker exec -ti pytorch-fuzz /bin/bash
$ /opt/crusher/bin_x86-64/ui -o out
```

Как только будут найдены необработанные исключения, значение поля `unique_crashes` (в окне `UI` - наверху справа) станет ненулевым.

Прервать фаззинг (в первом терминале, `Ctrl + С`).
Binary file added Examples/Crusher/Linux/pytorch/in/model
Binary file not shown.
20 changes: 20 additions & 0 deletions Examples/Crusher/Linux/pytorch/torch_load_fuzz.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import os
import sys
import atheris

with atheris.instrument_imports():
import torch

import torch

@atheris.instrument_func
def TestOneInput():
try:
model = torch.load(sys.argv[-1])

except SyntaxError as e:
pass


if __name__ == '__main__':
atheris.Run(TestOneInput)

0 comments on commit 3b38470

Please sign in to comment.