
Fuzzer guiado por cobertura para variáveis UEFI NVRAM usando emulação Qiling e AFL++ para descobrir vulnerabilidades de firmware através de mutação automatizada de entrada e detecção de falhas.
Um fuzzer simples, guiado por cobertura para variáveis NVRAM UEFI.
Baseado em Qiling e AFL++.
Escrito por Itai Liba (@liba2k) e Assaf Carlsbad (@assaf_carlsbad).
Construir imagem:
docker build -t efi_fuzz .
Testar o ambiente:
docker run -v $PWD:/efi_fuzz -it efi_fuzz sh -c "cd efi_fuzz/tests/ && pytest -s -v -W ignore::DeprecationWarning"
Usar o ambiente:
docker run -v $PWD:/efi_fuzz -it efi_fuzz sh -c "cd /efi_fuzz ; bash"
Preparar o ambiente NVRAM emulado (Você precisará fornecer a imagem da ROM):
python3 scripts/prepare_nvram.py rom.bin nvram.pickle
Preparar o corpus inicial para as variáveis NVRAM:
python3 scripts/prepare_afl_corpus.py rom.bin afl_inputs
Realizar uma execução de teste do fuzzer:
python3 efi_fuzz.py <target> <nvram> <varname> <seed>
Se for bem-sucedido, prossiga para o fuzzing completo:
afl-fuzz -i afl_inputs/<varname> -o afl_outputs/ -U -- python3 efi_fuzz.py <target> <nvram> <varname> @@
Se estiver no Windows, instale o WSL. Recomendamos o WSL2 em vez do WSL original, que tende a ser lento às vezes. As instruções completas de instalação para Windows 10 podem ser encontradas aqui: https://docs.microsoft.com/en-us/windows/wsl/install-win10
Dentro da distribuição WSL, instale alguns pacotes necessários que nos permitirão compilar código fonte C:
sudo apt install build-essential automake
Instalar o AFL++ com suporte ao modo Unicorn.
3.1. Clonar o repositório:
git clone https://github.com/AFLplusplus/AFLplusplus
3.2. Compilar os binários principais do AFL++:
make
3.3. Compilar o recurso de suporte ao Unicorn:
cd unicorn_mode
./build_unicorn_support.sh
3.4. Instalar tudo:
make install
Adquirir e descompactar o firmware UEFI que você deseja fuzzear. Para os detalhes técnicos completos sobre como isso é feito na prática, veja aqui ou aqui.
Clonar o fuzzer e instalar as dependências necessárias:
git clone https://github.com/Sentinel-One/efi_fuzz
O Triton é necessário para propagação de taint.
Instruções para instalar o Triton podem ser encontradas aqui:
https://triton.quarkslab.com/documentation/doxygen/#install_sec
Preparar o ambiente NVRAM emulado:
python scripts/prepare_nvram.py rom.bin nvram.pickle
Preparar o corpus inicial para as variáveis NVRAM:
python scripts/prepare_afl_corpus.py rom.bin afl_inputs
Realizar uma execução de teste do fuzzer:
python efi_fuzz.py <target> <nvram> <varname> <seed>
Se for bem-sucedido, prossiga para o fuzzing completo:
afl-fuzz -i afl_inputs/<varname> -o afl_outputs/ -U -- python efi_fuzz.py <target> <nvram> <varname> @@
-e, --end: Especificar um endereço final para a emulação.-t, --timeout: Especificar um novo valor de timeout para a emulação, em ms.-o, --output: Especificar o formato de saída para fins de depuração. Os valores válidos são: trace, disasm, debug e off (padrão é off).-n, --no-sanitize: Desabilitar o sanitizador de memória (padrão é False).-u, --track-uninitialized: Manter o rastreamento de memória não inicializada via Triton e propagação de taint (EXPERIMENTAL!).-x, --extra-modules: Uma lista de módulos extras para carregar para satisfazer as dependências do alvo.Informações adicionais sobre firmware UEFI em geral e o efi_fuzz em particular podem ser encontradas aqui:
pip install -r efi_fuzz/requirements.txt