В июне 2023 года Microsoft закрыла CVE-2023-29361 - use-after-free (CWE-416) в драйвере Cloud Files Mini Filter (
cldflt.sys), CVSS 7.0 (HIGH), вектор CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H. Advisory содержал одну строку: «Elevation of Privilege Vulnerability». Ни PoC, ни root cause analysis, ни указания на конкретную функцию. Одна строка - и молчание.Два файла с Winbindex, экспорт через BinExport в Ghidra, сортировка по similarity в BinDiff - через 40 минут изменённые базовые блоки показали, где объект освобождался до повторного использования. Публичные технические разборы (без PoC) появились позже. А diff уже всё рассказал.
Это и есть patch diffing - рабочий инструмент для n-day research, когда vendor выпустил патч, а защитники ещё не понимают, что именно было исправлено. И пока они не понимают - окно открыто.
Место patch diffing в цепочке атаки и анализ 1-day уязвимостей
Patch diffing занимает конкретную позицию в исследовательском workflow и напрямую связан с тактиками MITRE ATT&CK. На стороне атакующего это этап Resource Development: разработка эксплойтов (T1587.004) и получение информации об уязвимостях (T1588.006). Результат patch diffing - понимание root cause, которое конвертируется в эксплойт для Exploitation for Privilege Escalation (T1068), Exploit Public-Facing Application (T1190), Exploitation for Client Execution (T1203) или Exploitation of Remote Services (T1210). Куда именно - зависит от класса уязвимости и attack surface. Подробнее - в нашем статье о cve эксплойт разработка.Цепочка от патча до эксплойта:
- Vendor публикует security update (Patch Tuesday, Android Security Bulletin, USN/DSA)
- Patch diffing: извлечение уязвимого и исправленного бинарника, бинарное сравнение функций, изоляция security-relevant изменений
- Root cause analysis: определение класса уязвимости (OOB write, UAF, integer overflow), input surface, достижимости из user space
- PoC development: минимальный триггер для подтверждения exploitability
- Exploit development или reporting через responsible disclosure
Три рабочих сценария:
- 1-day exploit development. Патч вышел, публичного эксплойта нет. Diff даёт root cause и input surface - основу для PoC. Применимо к Windows Patch Tuesday, Android Security Bulletin, Linux kernel stable updates. [Внешний и внутренний пентест, red team]
- Variant analysis (поиск 0-day). Патч закрывает одну уязвимость, но паттерн ошибки повторяется в соседних функциях. Как показали исследования Mateusz Jurczyk из Google Project Zero, win32k-подсистема Windows - характерный пример: систематический анализ обработчиков приводил к обнаружению целых серий уязвимостей.
- Тренировка reverse engineering. Patch diffing даёт одновременно цель (понять патч) и ограничение области - несколько изменённых функций вместо всего бинарника. Переход от CTF к реальному ПО через patch diffing - один из самых коротких путей.
Инструменты patch diffing: от BinDiff до Diaphora и PatchDiff
Требования к окружению
- ОС: Windows 10/11, GNU/Linux (Ubuntu 22.04+) или macOS - BinDiff и Ghidra работают на всех трёх; IDA Pro (для Diaphora) - аналогично
- RAM: минимум 8 ГБ; для крупных бинарников (ядро Windows, Android system libraries) - 16 ГБ, иначе будете долго смотреть на прогресс-бар
- Дисассемблер: IDA Pro 7.5+ с Python 3 (Diaphora, PatchDiff2) или Ghidra 10.x+ (BinDiff через BinExport)
- BinDiff: v8+, бесплатный, closed-source, Google; требует BinExport (Ghidra Extension или IDA plugin)
- Diaphora: текущая версия с GitHub (joxeankoret/diaphora), open-source, активно поддерживается
- Сеть: offline-работа полностью поддерживается; интернет нужен только для скачивания бинарников (Winbindex, Microsoft Symbol Server)
| Инструмент | Дисассемблер | Тип matching | Преимущества | Ограничения | Когда использовать | Статус |
|---|---|---|---|---|---|---|
| BinDiff | IDA Pro, Ghidra | Structural (CFG + call graph) | Скорость, стабильность на больших бинарях, наглядная визуализация CFG | Closed-source, слабо работает с renamed/обфусцированными функциями | Первый проход, быстрая сортировка по similarity | Активный, Google |
| Diaphora | IDA Pro (основной), Ghidra, Binary Ninja (экспериментально) | Heuristic + fuzzy + graph isomorphism | Open-source, скриптуемость, batch diffing, custom heuristics, экспорт в SQLite | Требует IDA Pro, медленнее BinDiff на крупных файлах | Глубокий анализ, stripped бинари, автоматизация | Активный, GitHub |
| PatchDiff2 | IDA Pro | Signature-based + CFG | Заточен на patch analysis, прост | Nicolas Pouvesle (Tenable), поддержка прекращена, последние версии для устаревших IDA | Legacy-задачи, если нет BinDiff/Diaphora | Заброшен |
| ghidriff | Ghidra | Fuzzy matching + similarity scoring | Бесплатный, CLI для автоматизации, CI-интеграция | Менее зрелый, документация скудная | Batch-обработка, автоматизация в пайплайне | Активный, GitHub |
| QBinDiff | Standalone | NP-hard network alignment, 33 feature vectors | Полная программируемость, тюнинг метрик | Экспериментальный (Quarkslab, 2023), малая user base | Firmware, нишевые архитектуры | Активный |
В работе выбор определяется задачей: BinDiff - первый проход (быстро показать, какие функции изменились), Diaphora - второй проход (копнуть глубже в кандидатов, особенно если BinDiff промахнулся или бинарь stripped). Оба работают в связке, и это не перестраховка - это рабочий протокол.
Уязвимость затрагивает Windows 10 21H2/22H2, Windows 11 21H2/22H2, Windows Server 2022. Локальный доступ, высокая сложность атаки (AC:H), нужны минимальные привилегии (PR:L), взаимодействие пользователя не требуется (UI:N). EPSS 0.0129 (percentile 0.7995) - выше медианы, заметная вероятность эксплуатации. CISA SSVC: Track (мониторить), exploitation - none, technical impact - total.
Получение уязвимого и исправленного бинарника
Для Windows основной источник - Winbindex (winbindex.m417z.com). Сервис отслеживает версии системных файлов и даёт ссылки на скачивание напрямую с серверов Microsoft.Workflow для
cldflt.sys:- Открыть
winbindex.m417z.com/?file=cldflt.sys, отфильтровать по Windows 10 22H2 - Скачать как
cldflt_patched.sys - Скачать как
cldflt_vuln.sys
.deb/.rpm); Android - factory images или OTA с developers.google.com; macOS - IPSW-файлы или extracted dyld shared cache.Бинарное сравнение функций через BinDiff
Workflow Ghidra + BinExport + BinDiff:- Загрузить оба бинарника в Ghidra (отдельные программы в проекте)
- Для Windows-драйверов - загрузить символы:
File->Load PDB File->Advanced->Search All(поиск на серверах Microsoft) - Перебазировать на 0x0:
Window->Memory Map-> иконка Home -> ввести0 - Запустить автоанализ:
Analysis->Auto-Analyzeс дефолтными настройками, дождаться завершения - Экспортировать:
File->Export Program-> форматBinary BinExport (V2) for BinDiff - Повторить шаги 1-5 для второго бинарника
Код:
bindiff --primary cldflt_vuln.BinExport --secondary cldflt_patched.BinExport -o diff_result
bindiff -ui) или анализируется программно через BinDiff API.Интерпретация diff: на что смотреть в графе
Открываем Matched Functions, сортируем по Similarity по возрастанию. Функции с similarity ниже 1.0 - кандидаты. Но не все: часть - обновления библиотек, отладочные изменения, stack canaries. Шум неизбежен, и его надо уметь отсеивать.Фильтры первого прохода:
- Similarity < 0.95 - функция изменилась существенно
- Confidence > 0.7 - BinDiff уверен в сопоставлении
- Basic blocks changed > 0 - есть структурные изменения в CFG
- Добавленные проверки (bounds check, null check, reference counting)
- Удалённые или перемещённые участки кода
- Изменения в порядке вызовов free/allocate - характерная сигнатура UAF-патча
InterlockedIncrement (reference count) перед передачей объекта в другой контекст. В графе это один-два новых базовых блока с условным переходом непосредственно перед вызовом, который использовал уже освобождённый объект. Увидеть это в CFG - дело нескольких минут, если знаешь, что искать.Паттерны анализа патчей безопасности: сигнатуры security fix
Каждый класс уязвимости оставляет характерный отпечаток в diff. Зная эти паттерны, время анализа сокращается с часов до минут.
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Use-after-free (CWE-416). CVE-2023-29361. UAF-патчи содержат одно из трёх изменений: добавление
ref_count++ перед передачей указателя, перемещение вызова free после последнего использования объекта, или null-проверка указателя перед dereference после функции, которая может освободить объект.CVE-2019-8606. Патч добавил improved validation символьных ссылок (по описанию Apple), что в бинарном diff проявляется как новые проверки пути или типа объекта перед использованием. Хотя CVE-2019-8606 классифицирован как CWE-362, конкретный патч - это validation fix, а не добавление lock-примитивов. Такое бывает: формальная классификация и реальный патч расходятся.
Сводная таблица:
| Класс (CWE) | Типичный патч в diff | Сигнал в BinDiff | Пример CVE |
|---|---|---|---|
| OOB write (CWE-787) | Bounds check перед memcpy/write | Новый block с compare + conditional jump | CVE-2023-21273 |
| Integer overflow (CWE-190) | Overflow check перед аллокацией | Block с MAX-constant comparison | CVE-2023-21241 |
| Use-after-free (CWE-416) | Изменён порядок free/use или добавлен refcount | Перестановка блоков, новый call к ref-функции | CVE-2023-29361 |
| Race condition (CWE-362) | Добавлена синхронизация (lock/mutex) или validation | Новые call-инструкции к lock-функциям или проверки валидности | CVE-2019-8606 (validation fix) |
CISA SSVC классифицирует CVE-2023-21273, CVE-2023-21241 и CVE-2023-29361 как Track (мониторить): exploitation - none, automatable - no, technical impact - total. Низкий EPSS (0.0002–0.0129) подтверждает: без patch diffing эти уязвимости остались бы «тёмными» - формально закрытыми, но технически непонятными для защитников. Advisory сказал «fixed», а что именно fixed - разбирайтесь сами.
BinDiff vs Diaphora: бинарный diff в двух парадигмах
Инструменты используют принципиально разные подходы к сопоставлению, и эта разница критична на практике.
BinDiff строит CFG и call graph, использует MD-index и фингерпринты базовых блоков для матчинга. Подход восходит к работе Halvar Flake 2004 года о structural comparison of executable objects - одной из первых формализаций проблемы. BinDiff быстр и стабилен на бинарях с символами.
Проблемы начинаются, когда компилятор переупорядочивает блоки (PGO), функция инлайнится после LTO, или регистровая аллокация меняется (RAX вместо RDX для той же переменной). BinDiff в таких случаях даёт false match или оставляет функцию в unmatched. И ты сидишь, гадаешь - это security fix или компилятор поиграл в тетрис.
Diaphora комбинирует exact match (хеш-сравнение), fuzzy matching (набор нечётких признаков), graph isomorphism и специализированные эвристики для stripped бинарей. Промежуточные данные экспортируются в SQLite - можно писать SQL-запросы поверх результатов, строить кастомные фильтры и автоматизировать batch-обработку.
Ключевое архитектурное отличие - расширяемость. В Diaphora можно добавлять custom heuristics для конкретного таргета, фильтровать экспортируемые функции по паттернам, делать partial diffing (сравнение только конкретных функций) и писать собственные инструменты поверх Diaphora как библиотеки. Для исследователя, который регулярно анализирует патчи одного продукта (ядро Windows, Android system server), это меняет дело: один раз настроенные heuristics ускоряют каждый последующий анализ.
При анализе патчей Android Bluetooth-стека (CVE-2023-21273, CVE-2023-21241) картина характерная: BinDiff корректно сопоставляет функции с символами, но на stripped Bluetooth-стеке промахивается. Diaphora в аналогичных сценариях показывает лучшую точность за счёт fuzzy matching, но работает медленнее. Компромисс, к которому можно привыкнуть.
Рабочий протокол: BinDiff для первого прохода (10-15 минут на экспорт + diff, сортировка по similarity, выделение 5-10 кандидатов). Diaphora - для углублённого анализа конкретных функций, если BinDiff не дал однозначного результата или бинарь stripped.
[Применимо: оба инструмента работают для Windows, GNU/Linux, macOS, Android. BinDiff - через Ghidra (бесплатно) или IDA Pro. Diaphora - основная поддержка IDA Pro, экспериментальная поддержка Ghidra и Binary Ninja в версиях 3.x+]
Ограничения бинарного анализа уязвимостей и фильтрация шума
Security fix - далеко не единственное изменение в обновлённом бинарнике. Источники шума:- Non-security баг-фиксы и фичи. В Windows Patch Tuesday один модуль часто получает несколько патчей одновременно. Для Android Security Bulletin - десятки компонентов обновляются в одном билде. Всё это попадает в diff.
- Изменения компилятора. Обновление тулчейна (MSVC, clang) меняет instruction selection, register allocation, порядок блоков. Тысячи «изменённых» функций, семантически идентичных. Самый раздражающий источник шума.
- Stack canaries и массовый hardening. Добавление
/GSв MSVC или-fstack-protectorв gcc меняет пролог/эпилог каждой функции. - LTO и PGO. Link-Time Optimization и Profile-Guided Optimization радикально перестраивают layout бинарника.
- Начинать с модулей из advisory. Microsoft указывает «Cloud Files Mini Filter Driver» - diff только
cldflt.sys, не всю ОС - Отсекать similarity = 1.0. 100% совпадение - функция не менялась
- Фокус на малом числе изменённых блоков. Security fix - это 1-5 базовых блоков. 50+ блоков - скорее refactoring
- Искать паттерны из таблицы выше: bounds check, null check, overflow check, lock primitives
- Использовать символы. PDB для Windows, DWARF для GNU/Linux. Для Apple Objective-C имена методов сохраняются в бинарнике runtime'ом - это упрощает сопоставление
- Полная перекомпиляция с другой оптимизацией. Переход с
-O0на-O2меняет всё: inlining, loop unrolling, dead code elimination. Security fix неотличим от тысяч compiler-induced изменений. Тут diff бесполезен. - Cross-architecture. Сравнение ARM и x86 версий требует специализированных инструментов (QBinDiff, DeepDiff с embedding-based подходом). BinDiff и Diaphora на это не рассчитаны.
- Обфускация. Control flow flattening и opaque predicates ломают structural matching. Если бинарь прошёл через обфускатор - готовьтесь к ручной работе.
- Распределённый патч. Исправление рассыпано по нескольким call sites после LTO - нет единой «патченной функции». По данным ряда исследований LLM-агентов для patch analysis, значительная часть неудач происходит именно здесь - бинарный диффер не включает security-relevant функцию в набор кандидатов, и модель в принципе не может её увидеть.
.deb - единственный путь к root cause. Исследования LLM-агентов для бинарного анализа показывают, что точность локализации security-relevant функции при работе с бинарными артефактами без advisory остаётся ограниченной - и узкое место зачастую не LLM-модель, а качество бинарного diff на этапе формирования списка кандидатов.Заключение
Многие говорят о patch diffing как о навыке, который «надо бы освоить». Реальный workflow от скачивания бинарника до root cause отработан у единиц. Причина простая: первые две-три попытки выдают тысячи изменённых функций, нет понимания куда смотреть, и человек откладывает тему до следующего Patch Tuesday. Который тоже проходит мимо.А зря. Patch diffing - навык с самой быстрой отдачей во всём vulnerability research. Не fuzzing, где месяцами строишь harness и ждёшь crash. Не аудит исходников, где нужно прочитать миллион строк. Здесь - 30-60 минут на конкретную цель с гарантированным результатом: патч существует, уязвимость в нём точно есть, задача - найти где.
Через год-два LLM-агенты заберут тривиальную часть этой работы - первичный triage и ранжирование функций-кандидатов. Но финальный шаг - прочитать граф, понять семантику изменения, оценить exploitability - останется за аналитиком. Модели видят синтаксис diff, но не понимают, почему bounds check в одном контексте означает remote code execution, а в другом - просто hardening. Тот, кто нарабатывает этот навык руками сейчас, через два года будет не конкурировать с автоматизацией, а управлять ею.
Попробуйте взять любой CVE из июньского Patch Tuesday 2023, стянуть бинарники с Winbindex и прогнать через BinDiff по описанному workflow. Первый раз будет больно. Второй - уже нет. На WAPT эту цепочку проходят в течение двух модулей с лабами.
Последнее редактирование модератором: