- PVSM.RU - https://www.pvsm.ru -

На Хабре уже пару раз появлялись статьи, поднимающие тему American Fuzzy Lop (AFL) (1 [1],2 [2]). Но в данной статье речь пойдет не о классическом AFL, а о вспомогательных утилитах для него и его модификациях, которые, на наш взгляд, могут значительно улучшить качество фаззинга. Если вам интересно узнать, как можно прокачать AFL и искать быстрее и больше уязвимостей, то добро пожаловать под кат!
AFL — Coverage-guided fuzzer или Feedback-based fuzzer. Подробнее о данных концепциях можно узнать из такого классного пейпера, как «Fuzzing: Art, Science, and Engineering» [3]. Если обобщить информацию об AFL, то можно сказать следующее:
Графически это можно представить следующим образом:

Если вы не в курсе что такое AFL, то для старта рекомендуем:
На момент написания статьи последней версией AFL была версия 2.52b [4]. Фаззер активно развивается, и со временем некоторые сторонние разработки включаются в основную ветку AFL и становятся сами по себе неактуальными. В настоящее время можно выделить несколько полезных вспомогательных инструментов — они перечислены в следующем разделе.
При этом некоторые пользователи AFL отмечают [11], что автор фазера Michal Zalewski походу забил на поддержку своего детища, так как последние изменения датируются 5 ноября 2017 года. Это предположительно связывают с его уходом из Google и новыми проектами. В связи с этим люди стали самостоятельно собирать и делать патчи [12] последней текущей версии 2.52b.

Есть так же разные варианты и производные от AFL которые позволяют фаззить Python, Go, Rust, OCaml, GCJ Java, kernel syscalls, или даже целые VM.
В данном разделе мы подобрали различные скрипты и инструменты для работы с AFL и разделили их на несколько категорий:
Обработка крешей
Работа с покрытием кода
Несколько скриптов для минимизации test cases
Для распределенного запуска
Также совсем недавно по данной теме вышла очень хорошая статья “Scaling AFL to a 256 thread machine” [44], описывающая запуск AFL на 256 потоков.
Развертывание, управление, мониторинг, отчетность
AFL очень сильно повлиял на сообщество, занимающееся поиском уязвимостей, на само направление фаззинга. И не удивительно, что со временем на базе его идеи стали появляться различные модификации, вдохновленные оригинальным AFL. В этом разделе мы их и рассмотрим. У каждой из этих модификаций есть как свои преимущества, так и свои недостатки по сравнению с оригинальной версией AFL разных ситуациях.
Сразу скажем, что если есть проблемы с установкой или не хочется тратить время — почти любую модификацию можно найти на hub.docker.com [51]
Зачем?
Встроенные режимы работы AFL
Перед тем как перейти к рассмотрению различных модификаций и форков AFL необходимо рассказать о двух важных режимах, которые когда-то также были модификациями, а со временем стали встроенными режимами. Это Syzygy режим и режим Qemu.
Syzygy [52] mode — является режимом работы в инструменте instrument.exe
instrument.exe --mode=afl --input-image=test.exe --output-image=test.instr.exe
Для данного режима необходимо: Statically rewrite PE32 binaries with AFL, необходимы символы, Requires additional dev to make WinAFL kernel aware.
Qemu mode — О том, как это работает под QEMU, можно посмотреть тут “Internals of AFL fuzzer — QEMU Instrumentation” [53]. Поддержка работы с бинарями с помощью QEMU появилось в upstream AFL с версии Version 1.31b. Режим afl qemu mode работает с помощью добавленной функциональности инструментации бинарного кода в движок бинарной трансляции qemu tcg (tiny code generator). Для этого в afl есть скрипт сборки qemu, который выкачивает исходники определенной (2.10.0) версии qemu, накладывает на них несколько небольших патчей и собирает для заданной архитектуры. После этого сдается файл afl-qemu-trace, который является на самом деле файлом юзермодной (эмуляция только исполняемых файлов ELF) эмуляции qemu-. Благодаря этому можно использовать фаззинг с обратной связью на elf-бинарях, причем для кучи разных архитектур, поддерживаемых qemu. К тому же вы получаете все классные инструменты afl, начиная с удобного экрана с информацией о текущей сессии и заканчивая продвинутыми штуками, типа afl-analyze. Но надо помнить, что вы также получаете и ограничения qemu. Также, например, если файл собран toolchain, использующим аппаратные фичи SoC, на котором запускается бинарь и который не поддерживается qemu, фаззинг оборвется, как только встретится специфическая инструкция, или, например, будет использован специфический MMIO.
Есть еще и вот такой [54]интересный форк qemu mode, где скорость увеличили в 3x-4x раза за счет инструментации TCG кода и кэширования.
Форки
Появление форков AFL в первую очередь связано с изменениями, улучшениями самих алгоритмов работы классического AFL.
Стоит сказать, что есть большое количество академических работ, связанных с реализацией новых подходов, техник по фаззингу, где берется и модифицируется AFL. Кроме whitepaper больше ничего не доступно, поэтому такие реализации мы даже не стали упоминать. Если вам интересно, то их несложно нагуглить. Например, из последнего это CollAFL: Path Sensitive Fuzzing [65], EnFuzz [66], Smart Greybox Fuzzing [67], ML [68] для afl.
Модификации на базе Qemu
Модификация на базе KLEE
kleefl [73] — для генерации тест кейсов средствами символьного исполнения (очень медленный на больших программах).
Модификации на базе Unicorn
afl-unicorn [74] — позволяет фаззить куски кода, эмулируя его на Unicorn Engine [75]. Данную вариацию AFL мы также успешно использовали в нашей практике, а именно на участках кода одной RTOS, которая выполнялась на SOC’е, и использовать QEMU mode было невозможно. Данную модификацию целесообразно использовать в том случае, когда исходников нет (нельзя собрать stand-alone бинарь для анализа парсера) и программа не принимает входные данные в прямом виде (например, зашифрованы или представляют собой семплы сигнала как в одном CGC бинаре), тогда можно её пореверсить и найти предполагаемые места-функции, где эти данные обрабатываются в удобном для фаззера формате и которые можно пофаззить. Это самая общая модификация AFL. В том смысле, что она позволяет фаззить буквально все. То есть не зависит от архитектуры, наличия исходников, формата входных данных и формата самого бинаря (самый яркий пример как раз bare-metal — просто куски кода из памяти контроллера). Исследователь предварительно исследует этот самый бинарь и пишет фаззер, который эмулирует состояние на входе у процедуры парсера, например. Видно, что в отличие от AFL нужно предварительно проделать какое-то исследование бинаря. Для bare-metal прошивок, типа Wi-Fi или baseband есть просто ряд недостатков, которые нужно иметь ввиду:
Пример работы с данной модификацией “afl-unicorn: Fuzzing Arbitrary Binary Code” [76] и
“afl-unicorn: Part 2 — Fuzzing the ‘Unfuzzable’” [77].
Перед тем как мы перейдем к модификациям на основе фреймворков динамической бинарной инструментации (DBI), сразу напомним, что наибольшую скорость из этих фреймворков показывает DynamoRIO, потом DynInst и в конце уже PIN.
Модификации на базе PIN
Как вы видите, разных модификаций много, но толку от них в реальной жизни на практике не много.
Модификации на базе Dyninst
afl-dyninst [83] — American Fuzzy Lop + Dyninst == AFL blackbox фаззинг. Фишка данной версии заключается в том, что первоначально исследуемая программа (без исходного кода) статически инструментируется (static binary instrumentation, static binary rewriting) с помощью DynInst, а затем фаззится классическим AFL, который думает, что программа собрана с помощью afl-gcc/afl-g++/afl-as ;) В итоге это дает нам возможность работы без исходного кода и с очень хорошей производительностью — It used to be at 0.25x speed compared to a native compile. При этом есть значительное преимущество перед QEMU, которое заключается в возможности инструментировать динамически слинкованные библиотеки. В то время, как QEMU способен только инструментировать основной исполняемый файл статически слинкованный с библиотеками. К сожалению, сейчас это актуально только для операционной системы Linux. Для поддержки Windows необходимы изменения в самом DynInst и там над этим идет работа [84].
Можно также обратить внимание еще на такой форк [85] где его неплохо прокачали по различным возможностям (поддержка AARCH64 и PPC архитектур) и скорости ;)
Модификации на базе DynamoRIO
Продвинутый/искушенный читатель может отметить, что есть модификации со всеми популярными фреймворками инструментации, за исключением Frida [92] — действительно так оно и есть. Единственное упоминание об использование Frida с AFL нам встречалось только в работе «Chizpurfle: A Gray-Box Android Fuzzer for Vendor Service Customizations» [93]. Версия AFL с Frida была действительно полезна в виду того, что Frida хорошо поддерживает ряд RISC архитектур.
Многие исследователи также с нетерпением ждут релиза DBI фреймворка Scorpio от создателя Capstone, Unicorne, Keystone. На основе данного фреймворка сами авторы уже сделали фаззер (Darko) и, по их словам, успешно его используют для фаззинга embedded устройств. Подробнее с этим можно ознакомиться в работе «Digging Deep: Finding 0days in Embedded Systems with Code Coverage Guided Fuzzing» [94].
Модификации, базирующиеся на аппаратных возможностях процессора
Когда речь заходит о модификациях AFL с поддержкой аппаратных возможностей процессора, то это в первую очередь говорит о возможности фаззить kernel код, и во вторую очередь — о более высокой скорости фаззинга для приложений без исходного кода.
И, конечно, в первую очередь мы говорим о такой аппаратной возможности процессора, как Intel PT [95] (Processor Tracing). Которая доступна начиная с 6 поколения процессоров (это примерно с 2015). Естественно, для того, чтобы воспользоваться следующими фаззерами, вам понадобится железо с соответствующей поддержкой Intel PT.
Как вы могли заметить, данная тема активно развивается. При этом тут есть большое пространство для творчества, чтобы создать новую, интересную и полезную модификацию AFL.
Спасибо за внимание и удачного фаззинга!
Соавтор: Никита Кныжов
P.S. Спасибо всей команде исследовательского центра за помощь в подготовке данного материала, без их опыта и помощи подготовить такое было бы невозможно.
Автор: d1g1
Источник [99]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/informatsionnaya-bezopasnost/307050
Ссылки в тексте:
[1] 1: https://habrahabr.ru/post/259671/
[2] 2: https://habrahabr.ru/post/332076/
[3] «Fuzzing: Art, Science, and Engineering»: https://arxiv.org/pdf/1812.00140.pdf
[4] Официальная страница проекта: http://lcamtuf.coredump.cx/afl/
[5] afl-training: https://github.com/ThalesIgnite/afl-training
[6] afl-demo: https://gitlab.com/wolframroesler/afl-demo
[7] afl-cve: https://github.com/mrash/afl-cve
[8] тут: https://tunnelshade.in/blog/2018/01/afl-internals-compile-time-instrumentation/
[9] тут: https://copyninja.info/blog/afl-and-network-programs.html
[10] Rode0day: https://rode0day.mit.edu/4
[11] отмечают: https://groups.google.com/forum/#!topic/afl-users/6NTPAkK7JEk
[12] патчи: https://github.com/vanhauser-thc/afl-patches
[13] python-afl: https://github.com/jwilk/python-afl
[14] afl.rs: https://github.com/rust-fuzz/afl.rs
[15] afl-fuzz-js: https://github.com/connor4312/js-fuzz
[16] java-afl: https://github.com/Barro/java-afl
[17] kelinci: https://github.com/isstac/kelinci
[18] статьей: https://www.modzero.ch/modlog/archives/2018/09/20/java_bugs_with_and_without_fuzzing/index.html
[19] javan-warty-pig: https://github.com/cretz/javan-warty-pig
[20] afl-swift: https://github.com/Proteas/afl-swift
[21] ocamlopt-afl: https://github.com/kayceesrk/ocamlopt-afl
[22] sharpfuzz : https://github.com/Metalnem/sharpfuzz
[23] afl-utils: https://gitlab.com/rc0r/afl-utils
[24] afl-crash-analyzer: https://github.com/floyd-fuh/afl-crash-analyzer
[25] fuzzer-utils: https://github.com/ThePatrickStar/fuzzer-utils
[26] atriage: https://github.com/Ayrx/atriage
[27] afl-kit: https://github.com/kcwu/afl-kit
[28] AFLize: https://github.com/d33tah/aflize
[29] afl-fid: https://github.com/FoRTE-Research/afl-fid
[30] afl-cov: https://github.com/mrash/afl-cov
[31] count-afl-calls: https://github.com/Barro/count-afl-calls
[32] afl-sancov: https://github.com/bshastry/afl-sancov
[33] covnavi: https://github.com/Cisco-Talos/covnavi
[34] LAF LLVM Passes: https://gitlab.com/laf-intel/laf-llvm-pass/tree/master
[35] afl-pytmin: https://github.com/ilsani/afl-pytmin
[36] afl-ddmin-mod: https://github.com/MarkusTeufelberger/afl-ddmin-mod
[37] halfempty : https://github.com/googleprojectzero/halfempty
[38] disfuzz-afl: https://github.com/MartijnB/disfuzz-afl
[39] AFLDFF: https://github.com/quantumvm/AFLDFF
[40] afl-launch: https://github.com/bnagy/afl-launch
[41] afl-mothership: https://github.com/afl-mothership/afl-mothership
[42] afl-in-the-cloud: https://github.com/abhisek/afl-in-the-cloud
[43] VU_BSc_project: https://github.com/clvang000/VU_BSc_project
[44] “Scaling AFL to a 256 thread machine”: https://gamozolabs.github.io/fuzzing/2018/09/16/scaling_afl.html
[45] afl-other-arch: https://github.com/shellphish/afl-other-arch
[46] afl-trivia: https://github.com/bnagy/afl-trivia
[47] afl-monitor: https://github.com/reflare/afl-monitor
[48] afl-manager: https://github.com/zx1340/afl-manager
[49] afl-tools: https://hub.docker.com/r/moflow/afl-tools/
[50] afl-remote: https://github.com/block8437/afl-remote
[51] hub.docker.com: https://hub.docker.com
[52] Syzygy: https://doar-e.github.io/blog/2017/08/05/binary-rewriting-with-syzygy/
[53] “Internals of AFL fuzzer — QEMU Instrumentation”: https://tunnelshade.in/blog/2018/02/afl-internals-qemu-instrumentation/
[54] такой : https://abiondo.me/2018/09/21/improving-afl-qemu-mode/
[55] afl-cygwin: https://github.com/arizvisa/afl-cygwin
[56] AFLFast: https://github.com/mboehme/aflfast
[57] FairFuzz: https://github.com/carolemieux/afl-rb
[58] AFLGo: https://github.com/aflgo/aflgo
[59] PerfFuzz: https://github.com/carolemieux/perffuzz
[60] Pythia: https://github.com/mboehme/pythia
[61] Angora: https://github.com/AngoraFuzzer/Angora
[62] Neuzz: https://github.com/Dongdongshe/neuzz
[63] UnTracer-AFL: https://github.com/FoRTE-Research/UnTracer-AFL
[64] Qsym: https://github.com/sslab-gatech/qsym/
[65] CollAFL: Path Sensitive Fuzzing: http://chao.100871.net/papers/oakland18.pdf
[66] EnFuzz: https://arxiv.org/pdf/1807.00182.pdf
[67] Smart Greybox Fuzzing: https://arxiv.org/pdf/1811.09447.pdf
[68] ML: https://arxiv.org/pdf/1811.08973.pdf
[69] TriforceAFL: https://github.com/nccgroup/TriforceAFL
[70] системы: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2016/june/project-triforce-run-afl-on-everything/
[71] TriforceLinuxSyscallFuzzer: https://github.com/nccgroup/TriforceLinuxSyscallFuzzer
[72] afl-qai: https://github.com/kanglictf/afl-qai
[73] kleefl: https://github.com/julieeen/kleefl
[74] afl-unicorn: https://github.com/Battelle/afl-unicorn
[75] Unicorn Engine: https://www.unicorn-engine.org/
[76] “afl-unicorn: Fuzzing Arbitrary Binary Code”: https://hackernoon.com/afl-unicorn-fuzzing-arbitrary-binary-code-563ca28936bf
[77] “afl-unicorn: Part 2 — Fuzzing the ‘Unfuzzable’”: https://hackernoon.com/afl-unicorn-part-2-fuzzing-the-unfuzzable-bea8de3540a5
[78] aflpin: https://github.com/mothran/aflpin
[79] afl_pin_mode: https://github.com/spinpx/afl_pin_mode
[80] afl-pin: https://github.com/vanhauser-thc/afl-pin
[81] NaFl: https://github.com/carlosgprado/NaFl
[82] PinAFL: https://github.com/houcy/PinAFL
[83] afl-dyninst: https://github.com/talos-vulndev/afl-dyninst
[84] работа: https://github.com/dyninst/dyninst/issues/120
[85] форк: https://github.com/vanhauser-thc/afl-dyninst
[86] drAFL: https://github.com/mxmssh/drAFL
[87] afl-dr: https://github.com/atrosinenko/afl-dr
[88] afl-dynamorio: https://github.com/vanhauser-thc/afl-dynamorio
[89] WinAFL: https://github.com/ivanfratric/winafl
[90] статья: https://research.checkpoint.com/50-adobe-cves-in-50-days/
[91] тут: https://github.com/googleprojectzero/winafl/blob/master/readme_pt.md
[92] Frida: https://www.frida.re/
[93] «Chizpurfle: A Gray-Box Android Fuzzer for Vendor Service Customizations»: http://wpage.unina.it/roberto.natella/papers/natella_androidfuzzing_issre2017.pdf
[94] «Digging Deep: Finding 0days in Embedded Systems with Code Coverage Guided Fuzzing»: https://conference.hitb.org/hitbsecconf2018pek/materials/D2T1%20-%20Finding%200days%20in%20Embedded%20Systems%20with%20Code%20Coverage%20Guided%20Fuzzing%20-%20Dr%20Quynh%20and%20Kai%20Jern%20Lau.pdf
[95] Intel PT: https://software.intel.com/en-us/node/721535
[96] WinAFL-IntelPT: https://github.com/intelpt/winafl-intelpt
[97] kAFL: https://github.com/RUB-SysSec/kAFL
[98] «kAFL: Hardware-Assisted Feedback Fuzzing for OS Kernels»: https://www.usenix.org/system/files/conference/usenixsecurity17/sec17-schumilo.pdf
[99] Источник: https://habr.com/ru/post/435644/?utm_source=habrahabr&utm_medium=rss&utm_campaign=435644
Нажмите здесь для печати.