
Coverage-gesteuerter Fuzzer für UEFI-NVRAM-Variablen unter Verwendung von Qiling-Emulation und AFL++, um Firmware-Schwachstellen durch automatisierte Eingabemutation und Absturzerkennung zu entdecken.
Ein einfacher, coverage-gesteuerter Fuzzer für UEFI-NVRAM-Variablen.
Basiert auf Qiling und AFL++.
Geschrieben von Itai Liba (@liba2k) und Assaf Carlsbad (@assaf_carlsbad).
Image erstellen:
docker build -t efi_fuzz .
Umgebung testen:
docker run -v $PWD:/efi_fuzz -it efi_fuzz sh -c "cd efi_fuzz/tests/ && pytest -s -v -W ignore::DeprecationWarning"
Umgebung nutzen:
docker run -v $PWD:/efi_fuzz -it efi_fuzz sh -c "cd /efi_fuzz ; bash"
Emulierte NVRAM-Umgebung vorbereiten (Sie müssen das ROM-Image bereitstellen):
python3 scripts/prepare_nvram.py rom.bin nvram.pickle
Initiales Corpus für die NVRAM-Variablen vorbereiten:
python3 scripts/prepare_afl_corpus.py rom.bin afl_inputs
Einen Probelauf des Fuzzers durchführen:
python3 efi_fuzz.py <target> <nvram> <varname> <seed>
Bei Erfolg zum umfassenden Fuzzing übergehen:
afl-fuzz -i afl_inputs/<varname> -o afl_outputs/ -U -- python3 efi_fuzz.py <target> <nvram> <varname> @@
Falls unter Windows ausgeführt, WSL installieren. Wir empfehlen WSL2 gegenüber dem ursprünglichen WSL, der manchmal langsam sein kann. Die vollständigen Installationsanweisungen für Windows 10 finden Sie hier: https://docs.microsoft.com/en-us/windows/wsl/install-win10
Innerhalb der WSL-Distribution einige notwendige Pakete installieren, die es uns ermöglichen, C-Quellcode zu kompilieren:
sudo apt install build-essential automake
AFL++ mit Unicorn-Modus-Unterstützung installieren.
3.1. Repository klonen:
git clone https://github.com/AFLplusplus/AFLplusplus
3.2. Kern-AFL++-Binärdateien erstellen:
make
3.3. Unicorn-Unterstützung erstellen:
cd unicorn_mode
./build_unicorn_support.sh
3.4. Alles installieren:
make install
Besorgen und entpacken Sie die UEFI-Firmware, die Sie fuzzen möchten. Die vollständigen technischen Details zur praktischen Durchführung finden Sie hier oder hier.
Klonen Sie den Fuzzer und installieren Sie erforderliche Abhängigkeiten:
git clone https://github.com/Sentinel-One/efi_fuzz
Triton wird für die Taint-Weitergabe benötigt.
Anweisungen zur Installation von Triton finden Sie hier:
https://triton.quarkslab.com/documentation/doxygen/#install_sec
Emulierte NVRAM-Umgebung vorbereiten:
python scripts/prepare_nvram.py rom.bin nvram.pickle
Initiales Corpus für die NVRAM-Variablen vorbereiten:
python scripts/prepare_afl_corpus.py rom.bin afl_inputs
Einen Probelauf des Fuzzers durchführen:
python efi_fuzz.py <target> <nvram> <varname> <seed>
Bei Erfolg zum umfassenden Fuzzing übergehen:
afl-fuzz -i afl_inputs/<varname> -o afl_outputs/ -U -- python efi_fuzz.py <target> <nvram> <varname> @@
-e, --end: Geben Sie eine Endadresse für die Emulation an.-t, --timeout: Geben Sie einen neuen Timeout-Wert für die Emulation in ms an.-o, --output: Geben Sie das Ausgabeformat zu Debugging-Zwecken an. Gültige Werte sind: trace, disasm, debug und off (Standard: off).-n, --no-sanitize: Deaktivieren Sie den Memory Sanitizer (Standard: False).-u, --track-uninitialized: Verfolgt nicht initialisierten Speicher mittels Triton und Taint-Weitergabe (EXPERIMENTELL!).-x, --extra-modules: Eine Liste zusätzlicher Module, die geladen werden, um die Abhängigkeiten des Ziels zu erfüllen.Weitere Informationen zur UEFI-Firmware im Allgemeinen und zu efi_fuzz im Besonderen finden Sie hier:
pip install -r efi_fuzz/requirements.txt