
Инструмент статической бинарной инструментации для исполняемых файлов Windows x64
peafl64 — это инструмент статической инструментации для x64 PE-файлов в Windows.
Статическая инструментация — это практика редактирования исполняемых файлов и добавления кода в определённые места в них.
Инструментация добавляет код в начало каждого базового блока бинарного файла, записывая поток выполнения в совместимом с AFL виде.
Это позволяет фаззить бинарные файлы в пользовательском режиме (с помощью WinAFL) и в режиме ядра (с помощью kAFL) без доступа к их исходному коду.
Существуют и другие способы фаззинга Windows-бинарных файлов; в этом проекте мы решили сосредоточиться на статической инструментации, потому что это самый быстрый метод.
Этот проект основан на инструменте pe-afl от wmliang, с добавленной поддержкой x64.
Скрипт инструментации требует результат анализа IDA.
Чтобы создать его, запустите предоставленный скрипт ida_dumper.py в IDA.
Скрипт требует IDA 7+ и python3.8+.
usage: pe_afl.py [-h] [-n] [-cb] [-tf] [-te THREAD_ENTRY] [-nt NTOSKRNL] [-e ENTRY] [-l ENLARGE] [-v] [-lf] pefile ida_dump
positional arguments:
pefile Target PE file for instrumentation
ida_dump dump.json from IDA (created by ida_dumper.py)
optional arguments:
-h, --help show this help message and exit
-n, --nop Instrument with NOPs for testing
-cb, --callback Instrument with a callback, which is in the helper driver that's written in C
-tf, --thread-filter Driver instrumentation that filters only on thread ID (must use "-te" with this option)
-te THREAD_ENTRY, --thread-entry THREAD_ENTRY
The address (RVA) of the thread's initialization function
-nt NTOSKRNL, --ntoskrnl NTOSKRNL
ntoskrnl.exe path for offset extraction (non-optional if instrumenting a driver)
-e ENTRY, --entry ENTRY
Inject code on entry point, ie. -e9090
-l ENLARGE, --enlarge ENLARGE
Enlarge factor for sections, default=4
-v, --verbose Print debug log
-lf, --logfile Print log to pe-afl64.log rather than stream
Инструментация бинарного файла в пользовательском режиме с NOP-ами
PS pe-afl-64> python .\pe_afl.py -n C:\Work\cmd.exe C:\Work\cmd.exe.dump.json
[*] User-mode binary is being instrumented
[*] Single-thread instrument is on
[*] Preparing new sections
[*] Added section .text^
[*] Added section .cov
[*] Expanding relative jumps
[*] Expanded 3874 of 14353 branches
[*] Building address map
[*] Updating relative instructions
[*] Updating relocations...
[*] Updating Export table
[*] Updating load config
[*] Updating exception records
[*] Updating the PE headers
[*] Finalizing...
[*] Creating instrumented code
[*] Writing address mapping to C:\Work\cmd.exe.mapping.txt
[*] Updating jump tables
[*] Updated .text
...
[*] Removing temporary PE files
[*] Fixing PE checksum
[*] Instrumented binary saved to: C:\Work\cmd.instrumented.exe
Инструментация бинарного файла в режиме ядра с фильтрацией по ID процесса
python .\pe_afl.py -l 6 -nt "C:\Work\ntoskrnl.exe" "C:\Work\driver.sys" "C:\Work\driver.sys.dump.json"
Инструментация бинарного файла в режиме ядра с фильтрацией по ID потока и подробным выводом
python .\pe_afl.py -v -tf -te 0x40000 -l 6 -nt "C:\Work\ntoskrnl.exe" "C:\Work\ntoskrnl.exe" "C:\Work\ntoskrnl.exe.dump.json"
Сначала нужно проверить, загружается ли ваша машина с помощью BIOS или UEFI.
Для машин Hyper-V: машины Gen 1 основаны на BIOS, а Gen 2 — на UEFI.
Если ваша машина основана на BIOS, то вам нужно пропатчить winload.exe:
ImgpValidateImageHashmov eax, edi на xor eax, eax в последнем блоке кода функцииbcdedit /set path \Windows\system32\winload2.exeЕсли ваша машина загружается с помощью UEFI, используйте утилиту EfiGuard для патча winload.efi.
Шпаргалка по командам при использовании Hyper-V Manager:
FS1:
cd EFI/Boot
Load EfiGuard.Dxe.efi
FS0:
\EFI\Boot\bootx64.efi
Затем инструментируйте выбранный драйвер. Чтобы загрузить инструментированный драйвер на машине с Windows, он должен быть подписан, и самоподписанного сертификата достаточно для удовлетворения требований ОС:
# In elevated powershell terminal
$c = New-SelfSignedCertificate -Type CodeSigningCert -KeyUsage DigitalSignature -Subject 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'
Set-AuthenticodeSignature .\driver.instrumented.sys -Certificate $c -Force
Если инструментированный вами драйвер уже используется системой, используйте эти команды (от имени администратора), чтобы заменить файл драйвера:
set NAME=mydriver.sys
icacls %NAME% /save C:\windows\temp\%NAME%.icacls
takeown /F %NAME%
icacls %NAME% /grant Everyone:F
move %NAME% %NAME%.bak
move instrumented_driver.sys %NAME%
icacls . /restore C:\windows\temp\%NAME%.icacls
Затем выполните:
bcdedit /set recoveryenabled no
bcdedit /set nointegritychecks on
shutdown -t 0 -r
Интеграция с WinAFL осуществляется путём компиляции харнесса с использованием предоставленных заголовочных файлов.
Вместе с заголовочными файлами поставляется example.c — пример программы, показывающий, как их использовать.
Предоставленные заголовочные файлы представляют собой небольшую модификацию заголовков, которые уже поставляются с WinAFL для интеграции с другим инструментом статической инструментации бинарных файлов под названием Syzygy.
Способ нашей интеграции с kAFL довольно прост.
Обычно харнесс kAFL работает на виртуальной машине и общается с фронтендом фаззера с помощью специальных «гипервызовов».
Эти гипервызовы указывают фаззеру выполнять множество действий, среди которых — загрузка данных о покрытии из IntelPT и их разбор как AFL-битовой карты.
Поскольку peafl64 делает трассировку IntelPT устаревшей, мы должны подготовить способ передачи данных о покрытии фаззеру.
Поэтому мы расширили qemu и kvm «гипервызовами», которые позволяют харнессу (в пользовательском режиме), работающему в ВМ, отправлять собранные данные о покрытии с помощью вспомогательного драйвера.
Это касается именно настройки на ESXi, но должно быть актуально и для других платформ виртуализации, таких как AWS.
Настройка довольно проста:
install.sh qemu выполните install.sh qemu_sbiДля фаззинга с помощью kAFL и peafl64 нам нужно настроить фаззинг-машину: