
Tool zur statischen Binärinstrumentierung für Windows-x64-Executables
peafl64 ist ein statisches Instrumentierungswerkzeug für x64-PEs in Windows.
Statische Instrumentierung ist die Praxis, ausführbare Dateien zu bearbeiten und an bestimmten Stellen Code hinzuzufügen.
Die Instrumentierung fügt am Anfang jedes Grundblocks in der Binärdatei Code hinzu und protokolliert den Ausführungsfluss auf eine AFL-kompatible Weise.
Sie ermöglicht es uns, Binärdateien im Usermode (mit WinAFL) und im Kernelmode (mit kAFL) zu fuzzen, ohne Zugriff auf deren Quellcode zu haben.
Es gibt andere Möglichkeiten, Windows-Binärdateien zu fuzzen; in diesem Projekt haben wir uns auf statische Instrumentierung konzentriert, weil sie die schnellste Methode ist.
Dieses Projekt baut auf dem pe-afl-Werkzeug von wmliang auf und erweitert es um x64-Unterstützung.
Das Instrumentierungsskript benötigt eine IDA-Analyseausgabe.
Um sie zu erstellen, führen Sie das mitgelieferte Skript ida_dumper.py in IDA aus.
Das Skript erfordert IDA 7+ und Python 3.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
Instrumentieren einer Usermode-Binärdatei mit NOPs
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
Instrumentieren einer Kernelmode-Binärdatei mit Prozess-ID-Filterung
python .\pe_afl.py -l 6 -nt "C:\Work\ntoskrnl.exe" "C:\Work\driver.sys" "C:\Work\driver.sys.dump.json"
Instrumentieren einer Kernelmode-Binärdatei mit Thread-ID-Filterung und ausführlicher Ausgabe
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"
Zuerst müssen Sie prüfen, ob Ihr Rechner per BIOS oder UEFI bootet.
Bei Hyper-V-Maschinen: Gen-1-Maschinen basieren auf BIOS, Gen-2-Maschinen auf UEFI.
Wenn Ihre Maschine auf BIOS basiert, müssen Sie winload.exe patchen:
ImgpValidateImageHash darinmov eax, edi durch xor eax, eaxbcdedit /set path \Windows\system32\winload2.exe ausWenn Ihre Maschine per UEFI bootet, verwenden Sie das Dienstprogramm EfiGuard, um winload.efi zu patchen.
Befehls-Spickzettel bei Verwendung des Hyper-V-Managers:
FS1:
cd EFI/Boot
Load EfiGuard.Dxe.efi
FS0:
\EFI\Boot\bootx64.efi
Instrumentieren Sie dann den Treiber Ihrer Wahl. Damit ein instrumentierter Treiber auf einem Windows-Rechner geladen werden kann, muss er signiert sein; ein selbstsigniertes Zertifikat reicht aus, um die Anforderungen des Betriebssystems zu erfüllen:
# 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
Wenn der instrumentierte Treiber bereits vom System verwendet wird, verwenden Sie diese Befehle (als Administrator), um die Treiberdatei zu ersetzen:
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
Führen Sie dann aus:
bcdedit /set recoveryenabled no
bcdedit /set nointegritychecks on
shutdown -t 0 -r
Die Integration mit WinAFL erfolgt durch Kompilieren eines Harness mit den mitgelieferten Headern.
Neben den Headern gibt es example.c, ein Beispielprogramm, das deren Verwendung zeigt.
Die mitgelieferten Header sind eine leichte Abwandlung der bereits von WinAFL bereitgestellten Header, um die Integration mit einem anderen statischen Binärinstrumentierungswerkzeug namens Syzygy zu ermöglichen.
Die Art und Weise, wie wir mit kAFL integrieren, ist ziemlich einfach.
Normalerweise läuft ein kAFL-Harness auf einer virtuellen Maschine und kommuniziert über spezielle „Hypercalls“ mit dem Frontend des Fuzzers.
Diese Hypercalls weisen den Fuzzer an, viele Dinge zu tun, unter anderem Coverage-Daten von IntelPT zu laden und als AFL-Bitmap zu parsen.
Da peafl64 das IntelPT-Tracing überflüssig macht, müssen wir eine Möglichkeit vorbereiten, die Coverage-Daten an den Fuzzer zu übertragen.
Daher haben wir qemu und kvm um „Hypercalls“ erweitert, die es dem (Usermode-)Harness, der in einer VM läuft, ermöglichen, die mit dem Hilfstreiber gesammelten Coverage-Daten zu senden.
Dies betrifft speziell die Einrichtung auf ESXi, sollte aber auch für andere Virtualisierungsplattformen wie AWS relevant sein.
Die Einrichtung ist ziemlich einfach:
install.sh qemu den Befehl install.sh qemu_sbi aus