PetrSec Notes
94 subscribers
8 photos
9 files
12 links
Привет!

Меня зовут Пётр, я Application Security Engineer в Айдеко - занимаюсь фаззингом, статическим анализом, уязвимостями.
Тут пишу о всём, что мне интересно.

Мой GitHub - https://github.com/petrvaganoff
Личка - @petrsec
Download Telegram
FUZZING TOOLS 🙂

Давно не писал в канал, за это время у меня накопилось много всего интересного - потихоньку начинаю выкладывать 🙂

В октябре проходил обучение по программе №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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🤡2❤‍🔥1🔥1
Undefined Behavior Sanitizer (UBSan) ☣️

Захотел разобраться в этой теме, потому что часто видел не ясно откуда взятый 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
🔥3👍1
Basic Exploitation - Linux with Mitigations Disabled🦞

Weeks 1-5 (Basic Exploitation - Linux with Mitigations Disabled) of Exploit Development by AnotherOne@Pwn3rzs

Нашел довольно ценные заметки одного из участников канала Pwn3rzs, в канале люди бесплатно делятся материалами и знаниями об ИБ, в том числе есть множество заметок в Markdown формате, информация для меня довольно ценная, решил поделиться.

В сообщении разрешено распростарять эту информацию, значит со временем буду дополнять)

‼️Информация представлена исключительно в образовательных целях!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2
Первая CVE в ядре (write-up) ✔️

В октябре 2024 года мы с коллегой занимались фаззингом ядра Linux 6.11 в рамках выполнения работ для технологического центра. Хотя и основную работу сделал не я, в это время я в основном обучался этой теме, это было очень интересно, поэтому даже спустя время решил написать об этом чтобы оставить воспоминания :)

Как известно, крупные отечественные IT компании, использующие open source компоненты в составе своих продуктов, должны вносить определенный вклад по анализу и исправлению уязвимостей в них.

Мне впервые довелось участвовать в этом мероприятии. Задача была собрать ядро Linux с санитайзером, запустить фаззинг через Syzkaller и каждую нелелю в течение месяца отправлять отчеты в техцентр о найденных крашах, приращении покрытия и обновлении корпуса.

Одно ядро мы собрали с KASAN, другое с KMSAN. Поставили ядра на фаззинг и пустя некоторое время были найдены интересные краши в KMSAN сборке, в то время как в KASAN сборке мы так ничего стоящего не смогли найти - наверное потому что это самый популярный санитайзер)

1️⃣ BUG: KMSAN: uninit-value in selinux_inet_conn_request
Первый краш в KMSAN сборке мы нашли когда запустили debian сборку с ним в qemu/KVM. При подключении по ssh командой ssh root@127.0.0.1 -p 10021 -i ./bullseye.id_rsa возникает kernel panic. То есть чтение неинициализированного участка памяти в подсистеме SELinux. Проблему пофиксили бэкпортом патча из апстрима.

2️⃣BUG: KMSAN: uninit-value in tcp_v4_timewait_ack
Второй краш нашли когда попытались выполнить команду sudo apt install gdb 🙃 То же чтение неинициализированной переменной в сетевой подсистеме протокола TCP/IPv4. Так же бэкпортировали патч в апстриме.

Хотя эти краши и не были найдены методом фаззинга - в техцентре их нам засчитали.

3️⃣ BUG: KMSAN: kernel-infoleak in _copy_to_iter
Другой краш был уже интереснее - утечка неинициализированной памяти ядра через подсистему Netlink XFRM. Его как раз мы и нашли Syzkaller-ом. Несколько дней ушло на отладку и написание патчта. Затем еще пару недель переписок по почте, подготовки очередных версий патча, отправка патчей во все стабильные lvc-ветки техцентра, в upstream и stable. Благо, большую помощь с этим оказывал нам Фёдор Пчелкин.

В итоге, мейнтейнеры подсистемы XFRM приняли в upstream очередную версию патча, затем приняли бэкпорт и в stable-ветку ядра. А через некоторое время я увидел, что Linux kernel CVE assignment team присвоила этому исправлению CVE-2024-50110 с критичностью CVSS 3.1 5.5 - Medium. Как оказалось, любое security исправление в ядре всегда рассматривается серьезно и даже без PoC подобные исправления, как правило, получают CVE.

Это был классный опыт, сейчас я периодически занимаюсь фаззингом и кажется эта деятельность всё больше затягивает)

#kernel #cve #syzkaller #fuzzing
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Deref of Null в интерпретаторе CPython 3.11+ 💥

Примерно полтора месяца назад я нашёл интересный баг в модуле sqlite3 стандартной библиотеки CPython. После сборки под статическим анализатором Svace и запуска анализа, Svacer подсветил маркер DEREF_OF_NULL.RET.LIB (CWE-476) в Modules/_sqlite/connection.c - возможное разыменование нулевого указателя cls. NULL может вернуть функция sqlite3_aggregate_context() несколькими строками выше. Причем после неё и так уже стоит
assert(cls != NULL);

Но, как известно assert() работает только в отладочных сборках, но не в релизе. Значит в релизе оно вполне может выстрелить, потому что по коду других причин почему это не может случиться я не нашел)

Далее я попытался понять каким образом могу вызвать выполнение этой строки, причем, чтобы пришел именно NULL после sqlite3_aggregate_context(). И, через некоторое время у меня был готов минимальный репродюсер:
import sqlite3

class A:
def value(self):
return 1

con = sqlite3.connect(":memory:")
con.create_window_function("f", 1, A)

con.execute("CREATE TABLE t(x)")
con.execute("INSERT INTO t VALUES (1)")

con.execute("""
SELECT f(x)
OVER (ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
FROM t
""").fetchall()

Этот код, запущенный через REPL, роняет интерпретатор с SIGSEGV, у меня падает вот так:
zsh: segmentation fault (core dumped)  python3


Оценить критичность находки в тот момент было для меня затруднительно, но было понятно одно - данный баг может привести к DoS только в случае когда:
1. В скрипте регистрируется custom window function при работе с SQLite.
2. Скрипт позволяет внешнему пользователю управлять содержимым SQL запроса. То есть этот баг может использоваться только в цепочке эксплойтов. К примеру SQL-injection + этот DoS.

Поскольку, я не до конца понимал насколько вообще распространён код подобного вида в продакшене, на всякий случай решил этот баг отправить через приватный Security Advisories на GitHub. В результате переписки с мэйнтейнерами выяснилось что это обычный баг, он недостижиим извне - поэтому следующим шагом я создал публичный issue - в нем подробнее описаны технические детали. Даже хотел в ближайшее время заняться и исправить этот баг, но меня немного опередили)) Нашелся доброволец, который вроде как починил это через Claude Code😀, фикс пока на стадии ревью и вроде выглядит +- норм.

В результате всего мне удалось много узнать о том, как вообще выстроен процесс репортинга уязвимостей и багов в CPython.

А ещё, мне кажется, находить подобные баги можно так же методом фаззинга самого интерпретатора CPython через кастомные мутаторы AFL++ на основе формальной грамматики python3, как нибудь попробую эту тему изучить.

#bug #python #svace #opensource
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7