
Uma ferramenta de fuzzing para binários de código fechado baseada em Unicorn e LibFuzzer
uniFuzzer é uma ferramenta de fuzzing para binários de código fechado baseada em Unicorn e LibFuzzer. Atualmente, suporta fuzzing de arquivos ELF LSB de 32 bits em ARM/MIPS, normalmente encontrados em dispositivos IoT.
.c no diretório callback, que deve conter os seguintes callbacks:void onLibLoad(const char *libName, void *baseAddr, void *ucBaseAddr): É invocado cada vez que uma biblioteca dependente é carregada no Unicorn.int uniFuzzerInit(uc_engine *uc): É invocado logo após todos os binários terem sido carregados no Unicorn. Pilha/heap/registradores podem ser configurados aqui.int uniFuzzerBeforeExec(uc_engine *uc, const uint8_t *data, size_t len): É invocado antes de cada rodada de execução de fuzzing.int uniFuzzerAfterExec(uc_engine *uc): É invocado após cada rodada de execução de fuzzing.make e obtenha a ferramenta de fuzzing chamada uf.uniFuzzer utiliza as seguintes variáveis de ambiente como parâmetros:
UF_TARGET: Caminho do arquivo ELF alvoUF_PRELOAD: Caminho da biblioteca de pré-carregamento. Certifique-se de que a biblioteca tenha a mesma arquitetura que o alvo.UF_LIBPATH: Caminhos onde residem as bibliotecas dependentes. Use : para separar múltiplos caminhos.E o fuzzing pode ser iniciado com o seguinte comando:
UF_TARGET=<target> [UF_PRELOAD=<preload>] UF_LIBPATH=<libPath> ./uf
Aqui está uma demonstração para uso básico. A demonstração contém os seguintes arquivos:
vuln() que é vulnerável a estouro de pilha/heap.printf() vazio e malloc()/free() simplificados.vuln() de demonstração.Primeiro, instale o gcc para mipsel (pacote gcc-mipsel-linux-gnu no Debian) para compilar a demonstração:
# o binário alvo
# '-Xlinker --hash-style=sysv' instrui o gcc a usar 'DT_HASH' em vez de 'DT_GNU_HASH' para busca de símbolos
# já que atualmente o uniFuzzer não suporta 'DT_GNU_HASH'
mipsel-linux-gnu-gcc demo-vuln.c -Xlinker --hash-style=sysv -no-pie -o demo-vuln
# a biblioteca de pré-carregamento
mipsel-linux-gnu-gcc -shared -fPIC -nostdlib -Xlinker --hash-style=sysv demo-libcpreload.c -o demo-libcpreload.so
Ou você pode simplesmente usar os arquivos demo-vuln e demo-libcpreload.so, que já foram compilados com os comandos acima.
Em seguida, execute make para compilar o uniFuzzer. Observe que se você compilou a demonstração MIPS por conta própria, alguns endereços podem ser diferentes do binário pré-compilado e o demo-callback.c deve ser atualizado de acordo.
Finalmente, certifique-se de que a biblioteca libc do MIPS está disponível. No Debian, ela está em /usr/mipsel-linux-gnu/lib/ após instalar o pacote libc6-mipsel-cross, e é isso que UF_LIBPATH deve conter:
UF_TARGET=<caminho para demo-vuln> UF_PRELOAD=<caminho para demo-libcpreload.so> UF_LIBPATH=<caminho da lib para MIPS> ./uf
O Unicorn limpa o cache JIT do QEMU devido a este problema, o que diminui a velocidade do fuzzing, pois o binário alvo teria que ser recompilado via JIT durante cada rodada de execução.
Podemos comentar tb_flush(env); conforme indicado nesse problema para melhorar o desempenho.
GNU_HASHIFUNC