__attribute__ в языках С и С++Недавно изучил интересную возможность языка С - атрибуты функций и переменных. К примеру, с помощью атрибутов можно написать код, который выполнится до и после функции
main (#include <stdio.h>
__attribute__ ((constructor)) void before() {
printf("%s\n", "before");
}
__attribute__ ((destructor)) void after() {
printf("%s\n", "after");
}
int main()
{
printf("%s\n", "inside main");
return 0;
}
После запуска этого кода stdout будет таким:
before
inside main
after
__attribute__ были введены в GCC начиная с версии 2.0 , выпущенной в 1992 году как часть расширений, позже вошли в стандарт. Они предоставляют разработчикам гибкость при работе с компилятором, особенно в контексте низкоуровневого программирования, оптимизации и взаимодействия с аппаратным обеспечением.Атрибуты позволяют:
- Указывать особенности функций, например, что функция является "чистой" (
pure) или "константной" (const), чтобы компилятор мог применять оптимизации.- Контролировать выравнивание данных в памяти
int x __attribute__ ((aligned (16))) = 0;- Управлять порядком инициализации глобальных переменных.
- Запрещать вызов attributeнкций
__attribute__((deprecated))- Объявляattributeволы
__attribute__((weak)), которые могут быть переопределены сильными.// Эта функция никогда не возвращает управление
void __attribute__((noreturn)) exit_function() {
while (1);
}
Начиная с C++11 атрибуты так же поддерживаются в плюсах, как часть официального стандарта, до этого при использовании атрибутов компилятор
g++ вызывал gcc чтобы скомпилировать объектные файлы с атрибутами.С момента введения атрибутов в стандарте языка C++, появился новый синтаксис, атрибуты стали записываться через
[[attribute]]. Поэтому сейчас существует разница в синтаксисе:// В стиле GCC
void __attribute__((noreturn)) terminate();
// В стиле C++
[[noreturn]] void terminate();
#cpp
👍2🔥1
Давно уже искал официальную информацию в документах ФСТЭК о критериях успешного фаззинга и тут подсказали)
Кто не знает - ФСТЭК как раз играет роль регулятора, который вводит концепции, документы и регламенты для разработки безопасного ПО.
Для того чтобы получить сертификат ФСТЭК, вендор ПО должен организовать у себя некий процесс безопасной разработки и предоставить испытательной лаборатории пруфы того что ПО соответствует всем этим документам. В том числе нужно провести фаззинг и статический анализ кода.
Сохраню на всякий случай, думаю будет полезно
Кто не знает - ФСТЭК как раз играет роль регулятора, который вводит концепции, документы и регламенты для разработки безопасного ПО.
Для того чтобы получить сертификат ФСТЭК, вендор ПО должен организовать у себя некий процесс безопасной разработки и предоставить испытательной лаборатории пруфы того что ПО соответствует всем этим документам. В том числе нужно провести фаззинг и статический анализ кода.
Сохраню на всякий случай, думаю будет полезно
❤🔥1
Forwarded from Информ::Доверенная Разработка
Методическая рекомендация № 2025-04-001 (графические материалы)
🔥2❤🔥1
Впервые участвовал в Tinkoff-CTF на этих выходных 💳
Скажу одно - было интересно и сложно одновременно 😁
- Лига безопасности
- Заняли 329/977 место
- 3 человека в команде
- Решено 3/30 задачи 🙈
- Так и не решил задачу про aiogram бота
- Приобретено МНОГО новых скиллов)
Самое интересное задание было на отладку удалённо компилируемого сишного кода, жду разбора заданий!
t-ctf.ru/share/S6NeXwdx
Скажу одно - было интересно и сложно одновременно 😁
- Лига безопасности
- Заняли 329/977 место
- 3 человека в команде
- Решено 3/30 задачи 🙈
- Так и не решил задачу про aiogram бота
- Приобретено МНОГО новых скиллов)
Самое интересное задание было на отладку удалённо компилируемого сишного кода, жду разбора заданий!
t-ctf.ru/share/S6NeXwdx
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤🔥1🔥1
Когда я только начинал заниматься фаззингом в 2024 году, даже не представлял насколько это глубокая тема.
Ядро Linux как раз является отличной целью для фаззинга, отличается от обычных бинарей лишь тем, что код ядра выполняется в привилегированном режиме, а входные данные - системные вызовы, запускаемые в различном порядке и с различными комбинациями аргументов.
Ниже опишу свой опыт сборки ядра 6.16 из ветки linux-next с санитайзером KASAN и запуском фаззера Syzkaller.
Кому интересно - добро пожаловать под кат
Решил выбрать самое свежее ядро что есть на данный момент - это "экспериментальная" dev-ветка linux-next, она используется как интеграционная для обкатки самых новых драйверов пред вливанием в mainline ветку, часто содержит регрессии производительности и баги. Её и будем фаззить!
- Подготовка к запуску сборки:
git clone https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
cd linux-next
sudo dnf builddep -y kernel
- Включаем нужные подсистемы и функции ядра и собираем:
# полная очистка
make mrproper
# генерация стандартного конфига
make ARCH=x86_64 defconfig
# <-- config from https://portal.linuxtesting.ru/LVCFuzzingKernelOptions.html#main
# включаем namespaces
noscripts/config -e CONFIG_NAMESPACES \
-e CONFIG_UTS_NS \
-e CONFIG_IPC_NS \
-e CONFIG_PID_NS \
-e CONFIG_NET_NS \
-e CONFIG_USER_NS \
-e CONFIG_CGROUP_PIDS \
-e CONFIG_MEMCG
# Поддержка USB
noscripts/config -e CONFIG_USB \
-e CONFIG_USB_GADGET \
-e CONFIG_USB_LIBCOMPOSITE
# Поддержка Bluetooth
noscripts/config -e CONFIG_BT \
-e CONFIG_BT_BREDR
# Поддержка IEEE 802.15.4
noscripts/config -e CONFIG_IEEE802154 \
-e CONFIG_IEEE802154_6LOWPAN \
-e CONFIG_MAC802154 \
-e CONFIG_MAC802154_HWSIM
# Чтобы отобразить покрытие кода в веб-интерфейсе:
noscripts/config -e CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
# применяем конфиг
make olddefconfig
# собираем сжатый образ ядра
make -j"$(nproc)" bzImage
⚠️ - не забыть подставить конфиг из Техцентра!
В результате сборки должен будет появиться сжатый образ ядра Linux, доступный по пути -
linux-next/arch/x86_64/boot/bzImageФаззер тоже берем самый новый) Клонируем репозиторий, собираем бинари, готовим свежайший образ
git clone https://github.com/google/syzkaller.git
cd syzkaller
make -j"$(nproc)" all
./create-image.sh --distribution trixie
mkdir workdir && cd workdir
wget https://portal.linuxtesting.ru/pub/syzkaller/corpus-2025-01-24.db.gpg --no-check-certificate
gpg --output corpus.db --decrypt corpus-2025-01-24.db.gpg
⚠️ - пароль от зашифрованного архива с корпусом для фаззинга от Техцентра дается по запросу. Но можно фаззить и без него, в этом случае syzkaller будет создавать этот корпус с нуля.
Далее создаем конфиг файл manager.cfg в корне syzkaller, указываем абсолютные пути:
{
"target": "linux/amd64",
"http": "localhost:22200",
"workdir": "syzkaller/workdir",
"kernel_obj": "linux-next",
"image": "syzkaller/trixie.img",
"sshkey": "syzkaller/trixie.id_rsa",
"syzkaller": "syzkaller",
"procs": 2,
"type": "qemu",
"sandbox": "none",
"reproduce": true,
"vm": {
"count": 4,
"cpu": 2,
"mem": 4096,
"kernel": "linux-next/arch/x86_64/boot/bzImage",
"cmdline": "panic_on_warn=1 oops=panic slub_debug=FZP console=ttyS0 earlyprintk=serial mitigations=off vsyscall=native rcupdate.rcu_expedited=1"
},
"disable_syscalls": ["keyctl", "add_key", "request_key"]
}То есть в процессе фаззинга будет запускаться 4 виртуальных машины, с 2 CPU/4Гб RAM, стартовать Debian 13 с ядром Linux 6.16 (KASAN). Внутри syzkaller будет гонять 2 процесса фаззинга, в которых будут постоянные запуски системных вызовов, в надежде уронить ядро.
#fuzz #syzkaller #linux
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2❤🔥1👍1
В предыдущей части собрали ядро Linux и подготовили Syzkaller, теперь остается запустить фаззинг командой:
cd syzkaller
bin/syz-manager -config manager.cfg
Через некоторое время Syzkaller загрузит в память корпус, создаст виртуальные машины и поднимет веб-сервер по адресу
http://localhost:22200 для контроля состояния фаззинга.Минут через 5 выдаст такой результат выполнения команды:
2025/08/17 21:25:52 serving rpc on tcp://42507
2025/08/17 21:25:52 serving http on http://localhost:22200
2025/08/17 21:26:36 machine check:
disabled the following syscalls:
...
BinFmtMisc : enabled
Comparisons : enabled
Coverage : enabled
DelayKcovMmap : enabled
DevlinkPCI : PCI device 0000:00:10.0 is not available
ExtraCoverage : enabled
Fault : enabled
KCSAN : write(/sys/kernel/debug/kcsan, on) failed
KcovResetIoctl : kernel does not support ioctl(KCOV_RESET_TRACE)
LRWPANEmulation : netlink: adding device lowpan0 type lowpan link wpan0
Leak : enabled
NetDevices : enabled
NetInjection : enabled
NicVF : PCI device 0000:00:11.0 is not available
SandboxAndroid : setfilecon: setxattr failed.
SandboxNamespace : enabled
SandboxNone : enabled
SandboxSetuid : enabled
Swap : enabled
USBEmulation : enabled
VhciInjection : enabled
WifiEmulation : enabled
syscalls : 2408/8048
Заходим на веб-морду, там можно собирать и оценивать покрытие кода, видеть найденные краши, всю статистику и метрики фаззинга.
Через 1-2 часа Syzkaller уже пишет в лог первые найденные краши:
2025/08/17 21:57:33 VM 2: crash: KASAN: slab-use-after-free Write in __xfrm_state_delete
2025/08/17 22:11:53 VM 2: crash: possible deadlock in input_inject_event
2025/08/17 22:12:56 VM 3: crash: INFO: task hung in __iterate_supers
Кликнув на краш, можно посмотреть полный backtrace падения с указанием конкретных строк функций
После нахождения краша, если syzkaller считает его детерминированным и в принципе воспроизводимым, он ставит его в очередь на поиск репродюсера. Далее, если есть свободные 4 виртуальных машины, то он задействует их для поиска репродюсера. Он может найти репродюсер либо написанный на языке syzlang, либо на языке Си, а может не найти его вовсе, бывает по разному, этот процесс пока не идеален.
⚠️ - занятые под репродюсинг крашей виртуальные машины, могут почти полностью парализовать фаззинг, потому как syzkaller оперирует только выделенным ему количеством виртуальных машин в конфиге.
К сожалению, пока не могу добиться от syzkaller поведения, когда сразу после нахождения краша, он запускал бы процесс поиска подходящего репродюсера для этого краша, хотя в конфиге стоит
"reproduce": true. Если кто-то уже решал такую проблему - прошу подсказать в комментариях).Для ручного поиска репродюсера на данный момент пользуюсь утилитой syz-repro из состава syzkaller, запускаю поиск репродюсера, указывая конфиг фаззера и лог краша:
cd syzkaller
bin/syz-repro -config manager.cfg workdir/crashes/6bfbc3ea5a876102628620dec078f4992586f034/log0
При этом так же запускается пул из 4-х виртуальных машин и в них уже целенаправленно выполняются программы, которые могут приводить к этому крашу. В случае успеха, сохраняет Си-репродюcер и пишет в лог:
C file saved to repro.c.#fuzz #syzkaller #linux
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥1🔥1
Forwarded from Whitehat Lab
Нашел очередную, но достойную интерактивную платформу для тренировки работы в командной строке
Здесь и здесь более продвинутый уровень, либо оболочка bash ограничена
Знаете ли вы как можно вывести список всех файлов в директории не использую ls, а сделать это использую только echo ? 😳😁
#linux #cmd #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥1
Напомню, что на предыдущих шагах удалось запустить Syzkaller и он уже нашел несколько интересных крашей:
KASAN: slab-use-after-free Read in xfrm_alloc_spi
general protection fault in xfrm_alloc_spi
possible deadlock in input_inject_event
WARNING in __rate_control_send_low
Для 1-го краша из списка выше мне удалось через syz-repro получить репродюссер. Идем дальше!
У нас уже есть код репродюсера на СИ, который приводит к этом крашу. Давайте проверим работает ли он. Для этого запустим виртуальную машину QEMU с нашим ядром и окружением Trixie, сделаем это через скрипт для удобства:
#!/bin/bash
bzImage='linux-next/arch/x86/boot/bzImage'
qemuImage='syzkaller/trixie.img'
qemu-system-x86_64 \
-m 2G \
-smp 2 \
-kernel $bzImage \
-append 'console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0 nokaslr' \
-drive file=$qemuImage,format=raw \
-net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \
-net nic,model=e1000 \
-enable-kvm \
-nographic \
-pidfile vm.pid
Это запускает виртуальную машину с 2 vCPU/2 ГБ RAM с нашим ядром
bzImage и диском с дистрибутивом Debian 13 - trixie с выводом логов загрузки ядра и отключенным KASLR.root без пароля.grep kasan /proc/kallsyms | wc -l
scp:scp -P 10021 -i trixie.id_rsa workdir/crashes/6bfbc3ea5a876102628620dec078f4992586f034/repro.c root@127.0.0.1:/root
gcc repro.c -o repro
./repro
В случае использования pthread нужно добавить опцию `-pthread`
После этого происходит kernel panic
⚠️ - важно проверить чтобы краш в точности совпадал с тем, что нашел syzkaller.
СИ-код, генерируемый syz-repro, часто избыточен, содержит комментарии и многочисленные лишние действия. И я обычно, либо вручную, либо с помощью ИИ провожу минимизацию, часто уже в процессе минимизации и упрощения кода, становится понятна природа бага.
Процесс примерно такой:
- убираем лишние строки, либо переписываем что-то;
- проверяем в QEMU воспроизводится ли баг всё еще? Если нет, откатываем, значит задели то что влияет на воспроизводимость;
- повторяем действия выше
Пример боевого мини репро, одного из реальных падений стабильной ветки ядра:
#include <fcntl.h>
#include <linux/cdrom.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#define SIZE 14
void main()
{
unsigned char buf[SIZE];
memset(buf, 0x42, SIZE);
static struct cdrom_generic_command cgc;
static const unsigned char cdb[12] = { 0x6f, 0x79, 0xa6, 0x9f, 0xa8, 0xa3, 0x5f, 0x4b, 0x77, 0xef, 0xec, 0x7d };
memcpy(cgc.cmd, cdb, sizeof(cdb));
cgc.buffer = buf;
cgc.buflen = SIZE;
cgc.data_direction = CGC_DATA_WRITE;
int fd = open("/dev/cdrom", O_RDONLY | O_NONBLOCK);
ioctl(fd, CDROM_SEND_PACKET, &cgc);
}
Приведу несколько полезных рекомендаций, которые помогают в этом процессе:
- символизировать бэктрейс падения - https://google.github.io/kernel-sanitizers/SYMBOLIZER.html
(
cat backtrace.txt | python3 symbolizer.py --linux=$PWD/linux-6.16);-
printk для отладки ядра;- собрать репро с
-ggdb -O0;- удаленная отладка gdb, для этого добавить
-s -S в опции запуска QEMU;- найти похожие краши в сети;
- использовать
git blame и прочее;В итоге получилась достаточно объемная серия постов по фаззингу ядра
Linux. Осталось только осветить тему подготовки, оформления и отправки патча в upstream ядра, но это думаю будет отдельным постом в будущем, на примере фикса реального бага ядра, найденного через Syzkaller.#fuzz #syzkaller #linux
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥2🔥1
FUZZING TOOLS 🛠
Давно не писал в канал, за это время у меня накопилось много всего интересного - потихоньку начинаю выкладывать 🙂
В октябре проходил обучение по программе №37 от ИСП РАН -
Рассказывали в теории о том как появился и развивался динамический анализ, видах и способах инструментации, о санитайзерах, видах мутаций AFL++, картах покрытия и способах сборки покрытия, LLVM-тулчейн, компиляторах AFL++, persistent mode, учет состояний при фаззинге, pre и post-обработка, минимизации корпусов afl-cmin/afl-tmin - вкратце как всё это устроено под капотом.
Были и практики на фаззинг - в виде лабораторных работ, в итоге удалось поработать с различными тулзами, ниже привожу полный список, который решил выделить для себя:
• универсальные фаззеры - AFL++, libfuzzer
• сетевой фаззер - boofuzz
• генерационные фаззеры сложных структур - peach-fuzzer, Sulley
• гибридные фаззеры (Open Source) - fuzollic, SymCC, QSym, SymQEMU
• комплекс гибридного фаззинга:
◦ Sydr (concrete + symbolic execution)
◦ Sydr-fuzz (для интеграции Sydr и libFuzzer/AFL++)
• фаззер - Crusher (+ интеграция с Sydr)
• фаззеры ядра ОС и драйверов - Syzkaller, Trinity
• фаззинг сложных систем с сохранением состояний Nyx-fuzz
• дедупликация и триаж крашей - Casr
• плагин IDA PRO для визуализации покрытия кода - Lighthouse
• платформа управления уязвимостями (агрегирует баги) - DefectDojo
Из интересного что хочу доизучить - направленный фаззинг с IJON-аннотациями - сейчас как раз его завезли в свежий релиз AFL++. Есть хорошая статья на эту тему, кстати тоже от слушателя курса прошлых лет.
Casr и DefectDojo - вообще давно искал, просто не знал о подобных инструментах.
Увы, в open-source всё еще нет качественного движка символьного выполнения, подобного Sydr - считаю что symbolic это просто имба для фаззинга, существенно помогает быстрее находить новые пути и глубоко в них заходить засчет инверсии условных переходов.
В планах изучить подробнее эти интересные темы, использовать в своих кейсах, ну и написать об этом в канал.
#fuzz #fuzzing #testing #DAST #dast #afl #vulnerability
Давно не писал в канал, за это время у меня накопилось много всего интересного - потихоньку начинаю выкладывать 🙂
В октябре проходил обучение по программе №37 от ИСП РАН -
"Техническая защита информации. Основы инструментальной и технологической поддержки проведения фаззинг-тестирования программного обеспечения". Обучение проходило в Москве в очном формате с 9:00 до 18:00 в течение 5-ти дней, в конце зачет из 2-х практических заданий на фаззинг. Занятия проводили сотрудники ИСП РАН и разработчики DAST инструментов.Рассказывали в теории о том как появился и развивался динамический анализ, видах и способах инструментации, о санитайзерах, видах мутаций AFL++, картах покрытия и способах сборки покрытия, LLVM-тулчейн, компиляторах AFL++, persistent mode, учет состояний при фаззинге, pre и post-обработка, минимизации корпусов afl-cmin/afl-tmin - вкратце как всё это устроено под капотом.
Были и практики на фаззинг - в виде лабораторных работ, в итоге удалось поработать с различными тулзами, ниже привожу полный список, который решил выделить для себя:
• универсальные фаззеры - AFL++, libfuzzer
• сетевой фаззер - boofuzz
• генерационные фаззеры сложных структур - peach-fuzzer, Sulley
• гибридные фаззеры (Open Source) - fuzollic, SymCC, QSym, SymQEMU
• комплекс гибридного фаззинга:
◦ Sydr (concrete + symbolic execution)
◦ Sydr-fuzz (для интеграции Sydr и libFuzzer/AFL++)
• фаззер - Crusher (+ интеграция с Sydr)
• фаззеры ядра ОС и драйверов - Syzkaller, Trinity
• фаззинг сложных систем с сохранением состояний Nyx-fuzz
• дедупликация и триаж крашей - Casr
• плагин IDA PRO для визуализации покрытия кода - Lighthouse
• платформа управления уязвимостями (агрегирует баги) - DefectDojo
Из интересного что хочу доизучить - направленный фаззинг с IJON-аннотациями - сейчас как раз его завезли в свежий релиз AFL++. Есть хорошая статья на эту тему, кстати тоже от слушателя курса прошлых лет.
Casr и DefectDojo - вообще давно искал, просто не знал о подобных инструментах.
Увы, в open-source всё еще нет качественного движка символьного выполнения, подобного Sydr - считаю что symbolic это просто имба для фаззинга, существенно помогает быстрее находить новые пути и глубоко в них заходить засчет инверсии условных переходов.
В планах изучить подробнее эти интересные темы, использовать в своих кейсах, ну и написать об этом в канал.
#fuzz #fuzzing #testing #DAST #dast #afl #vulnerability
👍3❤🔥1🤡1
Undefined Behavior Sanitizer (UBSan) ☣️
Захотел разобраться в этой теме, потому что часто видел не ясно откуда взятый SIGILL в итоговых отчетах об ошибках после фаззинга. И самое интересное, если начать разбираться с SIGILL под отладчиком, приходим на строку, в которой и произошла ошибка, как выясняется в итоге 😄.
Что мы знаем об UBSan? Он детектирует неопределенное поведение - отсутствие ограничений на поведение программы со стороны стандарта языка С/C++. Включается опцией
Напишем простой пример программы с целочисленным переполнением:
Соберём ее c UBSan и запустим:
Программа не падает, сообщение о сработке санитайзера идет на stderr, а программа завершается с кодом 0. Так ведёт себя UBSan по дефолту, если не задать дополнительных опций.
Разбор опций
Часто при фаззинге нам нужно чтобы при срабатывании санитайзера фаззер считал это крашем, поэтому существуют различные опции, которые в этом помогают и задают дополнительное поведение, приведу ниже некоторые из них.
Это так называемый режим ловушки (trap-mode), при котором компилятор для отображения подробностей ошибки не добавляет в код тяжелую инструментацию из
Для сравнения вес бинарей при сборке с разными опциями:
Что же происходит при сборке под фаззинг AFL++, если мы собираем с UBSan?
⚡️Когда мы ставим переменную AFL_USE_UBSAN=1 под капотом ставятся флаги компиляции:
Этот режим позволяет с максимальной скоростью фаззить и находить краши, вызваные UB и не тратить ресурсы на подробное отображение причины и типа краша.
💡А если ставим переменные AFL_USE_UBSAN=1 и AFL_UBSAN_VERBOSE=1, то под капотом ставятся флаги:
Этот флаг AFL++ разумно использогвать после фаззинга при разборе результатов, потому что он сильно садит скорость фаззинга и добавляет веса бинарям за счет тяжелой инструментации из
Надеюсь получилось внести бОльшую ясность в эту тему, в первую очередь для себя)
#fuzz #fuzzing #testing #DAST #dast #afl #vulnerability #cpp
Захотел разобраться в этой теме, потому что часто видел не ясно откуда взятый SIGILL в итоговых отчетах об ошибках после фаззинга. И самое интересное, если начать разбираться с SIGILL под отладчиком, приходим на строку, в которой и произошла ошибка, как выясняется в итоге 😄.
Что мы знаем об UBSan? Он детектирует неопределенное поведение - отсутствие ограничений на поведение программы со стороны стандарта языка С/C++. Включается опцией
-fsanitize=undefined и находит целый класс ошибок. Сам санитайзер разработан Google в процессе работы над проектом LLVM/Clang в 2012 году, а сейчас поддерживается сообществом LLVM и GCC.Напишем простой пример программы с целочисленным переполнением:
int main() {
int k = 0x7fffffff;
k += argc;
return 0;
}Соберём ее c UBSan и запустим:
clang++ -fsanitize=undefined -o out test.cc && ./out
test.cc:3:5: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior test.cc:3:5
echo $?
0
Программа не падает, сообщение о сработке санитайзера идет на stderr, а программа завершается с кодом 0. Так ведёт себя UBSan по дефолту, если не задать дополнительных опций.
Разбор опций
-fsanitize=undefined - добавляет UBSan-инструментацию, по дефолту выводит подробное сообщение о срабатывании в stderr и пытается продолжить выполнение. Если далее ошибок не случилось, возвращает в итоге 0. За вывод подробного отчета об ошибке отвечает runtime библиотека libubsan (в инструкциях будут __ubsan_handle_*). При этом, сама UBSan-инструментация (проверки на UB) при этом не трубуют внешних либ.Часто при фаззинге нам нужно чтобы при срабатывании санитайзера фаззер считал это крашем, поэтому существуют различные опции, которые в этом помогают и задают дополнительное поведение, приведу ниже некоторые из них.
-fsanitize-recover=undefined - при обнаружения UB программа выводит сообщение в stderr, но не завершается аварийно (это дефолтное поведение при сборке с флагом -fsanitize=undefined).-fno-sanitize-recover=undefined - при обнаружения UB программа выводит сообщение в stderr и завершает выполнение с кодом 1.-fsanitize-trap=undefined - при обнаружения UB программа завершается с SIGILL (код 132) и выводит сообщение:Illegal instruction (core dumped) ./a.out
Это так называемый режим ловушки (trap-mode), при котором компилятор для отображения подробностей ошибки не добавляет в код тяжелую инструментацию из
libubsan, а вставляет только инструкции детектирования UB, и при их срабатывании ставит недопустимую аппарутную инструкцию (для x86/x86_64 это ud2 - Undefined Instruction), на ней бинарь обычно и падает с SIGILL или SIGTRAP. В этом случае значительно уменьшается размер бинаря, так как libubsan не линкуется.-fsanitize-minimal-runtime - компромиссный режим вывода информации об ошибке, только тип ошибки и адрес инструкции:./ubsan_min
ubsan: add-overflow by 0x0000000000400f6c
Для сравнения вес бинарей при сборке с разными опциями:
409K - undefined
20K - undefined-minimal-runtime
13K - undefined-trap
Что же происходит при сборке под фаззинг AFL++, если мы собираем с UBSan?
⚡️Когда мы ставим переменную AFL_USE_UBSAN=1 под капотом ставятся флаги компиляции:
-fsanitize=undefined (активирует санитайзер UBSan);-fsanitize-trap=undefined (заставляет программу генерировать SIGILL при срабатывании UBSan);Этот режим позволяет с максимальной скоростью фаззить и находить краши, вызваные UB и не тратить ресурсы на подробное отображение причины и типа краша.
💡А если ставим переменные AFL_USE_UBSAN=1 и AFL_UBSAN_VERBOSE=1, то под капотом ставятся флаги:
-fsanitize=undefined;-fno-sanitize-recover=undefined (подробный вывод в stderr и завершение с кодом 1);Этот флаг AFL++ разумно использогвать после фаззинга при разборе результатов, потому что он сильно садит скорость фаззинга и добавляет веса бинарям за счет тяжелой инструментации из
libubsan.Надеюсь получилось внести бОльшую ясность в эту тему, в первую очередь для себя)
#fuzz #fuzzing #testing #DAST #dast #afl #vulnerability #cpp
🔥2