Протестировано с crusher 2.4.0
Докерфайлы созданы так, чтобы пробрасывать в контейнер id и name пользователя и группы, выполняющих сборку кода, подлежащего в дальнейшем фаззинг-тестированию. Аналогичные пользователи создаются внутри контейнера для упрощения взаимодействия с хостом - в частности устанавливаются одинаковые права на каталог, пробрасываемый внутрь контейнера. По умолчанию в контейнере создается пользователь crusher:crusher (1000:1000)
- стандартный пользователь на моей фаззинг-ферме.
Докерфайлы расчитаны на работу с использованием доступного по сети центра лицензирования Crusher (красный хасп) *Пользователь, от которого выполняются команды должен иметь права root или быть добавлен в группу docker, подробнее https://docs.docker.com/engine/install/linux-postinstall/
Dockerfile.DRIO.txt
- сборка и фаззинг в режиме динамического инструментирования
Dockerfile.STATIC.txt
- сборка и фаззинг в режиме статического инструментирования
Dockerfile.STATIC_COV.txt
- сбор покрытия для сборки, полученной в режиме статического инструментирования
Dockerfile.EAT.txt
- контейнер для запуска процесса-анализатора EAT (Extra Analysis Tool) Crusher
- Сохранить дистрибутив Crusher в текущую директорию с именем crusher.tar.gz
- Создать каталог in в текущей директории и скопировать в него входные данные
docker build --build-arg cuid=$(id -u) --build-arg cgid=$(id -g) --build-arg cuidname=$(id -un) --build-arg cgidname=$(id -gn) -t crusher_drio -f Dockerfile.DRIO.txt . *Точка в конце команды означает текущий каталог
Команда сборки образа для фаззинга в режиме статического инструментирования. Сборка с санитайзерами UBSAN и компиляторными оптимизациями LAF.
docker build --build-arg cuid=$(id -u) --build-arg cgid=$(id -g) --build-arg cuidname=$(id -un) --build-arg cgidname=$(id -gn) -t crusher_static -f Dockerfile.STATIC.txt .
docker build --build-arg cuid=$(id -u) --build-arg cgid=$(id -g) --build-arg cuidname=$(id -un) --build-arg cgidname=$(id -gn) -t crusher_static_cov -f Dockerfile.STATIC_COV.txt .
docker build --build-arg cuid=$(id -u) --build-arg cgid=$(id -g) --build-arg cuidname=$(id -un) --build-arg cgidname=$(id -gn) -t crusher_eat -f Dockerfile.EAT.txt .
rm -rf /var/work/experiments/cluster/out
Это необходимый пункт, т.к. иначе каждый процесс fuzz_manager, видя уже имеющуюся директорию с результатами, будет требовать от пользователя подтвердить её удаление, что мешает автоматизированному запуску.
Команда запуска фаззинг-контейнера в режим контроля STDOUT для контроля в консоли того, что происходит в контейнере
docker run --network host --name=fuzz -v /var/work/experiments/cluster/out:/home/$(id -un)/out -e "FUZZ_INSTANCE=fuzz" --privileged crusher_drio
docker run --network host --name=fuzz -v /var/work/experiments/cluster/out:/home/$(id -un)/out -e "FUZZ_INSTANCE=fuzz" --privileged crusher_static
for i in $(seq 1 5); do docker run --network host --name=fuzz$i -v /var/work/experiments/cluster/out:/home/$(id -un)/out -e "FUZZ_INSTANCE=fuzz$i" -d --privileged crusher_drio; done
for i in $(seq 1 5); do docker run --network host --name=fuzz$i -v /var/work/experiments/cluster/out:/home/$(id -un)/out -e "FUZZ_INSTANCE=fuzz$i" -d --privileged crusher_static; done
screen -dmS EAT docker run --network host --rm --name=eat -v /var/work/experiments/cluster/out:/home/$(id -un)/out --privileged crusher_eat
Уничтожение в цикле N (N=5) контейнеров (заодно чистится выходной каталог - !в реальной работе так делать не нужно!)
for i in $(seq 1 5); do docker kill fuzz$i ; docker rm fuzz$i ; done ; rm -rf out
docker kill eat && docker rm eat
В специальном контейнере выполняется сборка цели с инструментацией под сбор покрытия, прогоняются сэмплы из каталога в котором сохраняется queue выбранного фаззера, формируется html-отчет, формируется текстовый отчет (текущий, при наличии предыдущего он сохраняется для выполнения сравнения через diff)
docker run --name=cov -v /var/work/experiments/cluster/out/fuzz1-MASTER_0/queue:/home/$(id -un)/in_stat -v /var/work/experiments/cluster/out_stat:/home/$(id -un)/out_stat -d --privileged crusher_static_cov && docker wait cov && docker rm cov
diff --suppress-common-lines -y out_stat/coverage.txt out_stat/coverage_prev.txt
В результате выполнения команды можно быстро посмотреть в каких модулях достигнут прирост покрытия с момента прошлого подсчета покрытия