
Fuzzer binário, guiado por cobertura, para Windows, macOS, Linux e Android
Copyright 2020 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Jackalope é um fuzzer personalizável, distribuído e guiado por cobertura que é capaz de trabalhar com binários de caixa-preta.
Embora existam muitos bons fuzzers guiados por cobertura que funcionam em alvos onde o código-fonte está disponível, existem relativamente poucos que funcionam em binários de caixa-preta, em particular nos sistemas operacionais Windows e macOS, e os que existem são principalmente baseados em bases de código que não são muito fáceis de personalizar. Os objetivos iniciais do Jackalope são:
O Jackalope pode ser usado de forma autônoma, mas é mais poderoso quando usado como uma biblioteca, onde os usuários podem conectar componentes personalizados que substituiriam o comportamento padrão. Por padrão, o Jackalope vem com:
O Jackalope pode ser executado em paralelo
-nthreads-start_server) e fazendo com que os fuzzers nas máquinas trabalhadoras se conectem a este servidor (flag de linha de comando -server). O servidor então coleta e distribui amostras, crashes e cobertura entre os trabalhadores.O Jackalope atualmente não inclui estratégias avançadas de mutação. Em vez disso, ele vem com um conjunto de mutadores genéricos, que funcionarão para muitos alvos, no entanto, os usuários são encorajados a escrever mutadores e estratégias de mutação personalizados de acordo com os alvos que desejam fuzzar.
Atualmente, o fuzzing de binários de caixa-preta é suportado nos sistemas operacionais Windows, macOS, Linux e Android.
No Linux, o Jackalope também é capaz de executar com Sanitizer Coverage (código-fonte do alvo necessário). Este modo está documentado em um documento separado.
Pré-requisito: Python 3
Abra um terminal e configure seu ambiente de compilação, se necessário. No Windows, em vez de abrir um prompt de comando genérico, você vai querer abrir o prompt de comando do Visual Studio para a plataforma para a qual está compilando, ou executar vcvars64.bat / vcvars32.bat.
Navegue até o diretório que contém o código-fonte.
Execute os seguintes comandos:
cd Jackalope
git clone --recurse-submodules [email protected]:googleprojectzero/TinyInst.git
(alternadamente: git clone --recurse-submodules https://github.com/googleprojectzero/TinyInst.git)
mkdir build
cd build
cmake <generator arguments> ..
cmake --build . --config Release
Os argumentos do gerador dependem do seu ambiente. No macOS você usaria -G Xcode, enquanto por exemplo no Windows com Visual Studio 2019 e para compilação de 64 bits você usaria -G "Visual Studio 16 2019" -A x64. No Linux, nenhum argumento de gerador é necessário. Ao compilar de forma cruzada para Android, argumentos adicionais do cmake são necessários, os mesmos descritos nas instruções de compilação do TinyInst para Android. Se você estiver fuzzando Android em uma VM que suporta memória compartilhada via /dev/shm, -DANDROID_TARGET=VM habilita a entrega de amostras por memória compartilhada.
Para compilar para executar contra binários arm64e no macOS, veja aqui.
Recebendo o erro No CMAKE_C_COMPILER could be found no macOS? Tente atualizar o cmake. Também certifique-se de que o Xcode está instalado e que você o executou pelo menos uma vez (ele instala alguns componentes na primeira execução).
Uso:
./fuzzer <fuzzer arguments> <instrumentation and other components arguments> -- <target command line>
Os seguintes argumentos de linha de comando são suportados:
-in - Diretório de entrada (diretório contendo o conjunto inicial de amostras). Se o diretório de entrada for "-", o fuzzer tenta restaurar a sessão anterior (o mesmo que usar a flag -restore).
-out - Diretório de saída
-t - Timeout da amostra em ms
-t1 - Timeout para inicialização do alvo (por exemplo, antes de atingir o método alvo, se definido). O padrão é o timeout da amostra.
-nthreads - Número de threads do fuzzer. O padrão é 1.
-delivery <file|shmem> - Mecanismo de entrega de amostras a ser usado. Se file, cada amostra é gravada como arquivo e "@@" nos argumentos do alvo é substituído por um caminho para o arquivo. Se shmem, o fuzzer cria memória compartilhada e substitui "@@" nos argumentos do alvo pelo nome da memória compartilhada. É responsabilidade do alvo abrir a memória compartilhada e extrair a amostra neste caso. O padrão é file.
-file_extension - Ao usar a entrega de amostras file, acrescenta a extensão especificada ao nome do arquivo. Útil se o alvo espera que os arquivos de entrada tenham uma certa extensão.
-restore ou -resume - Restaura e retoma uma sessão de fuzzing anterior. Tanto o processo do fuzzer quanto o do servidor suportam a restauração.
-server - Especifica o servidor de cobertura a ser usado.
-start_server - Executa um processo servidor em vez de um processo de fuzzing.
-crash_retry - Número de vezes para tentar reproduzir um crash. O padrão é 10. Crashes que não se reproduzem dentro deste número de tentativas ou que não se reproduzem quando executados sem instrumentação são marcados como instáveis.
-coverage_retry - Número de vezes para tentar reproduzir nova cobertura. Cobertura que não pode ser reproduzida de forma confiável dentro deste número de tentativas é considerada instável. Amostras que contêm apenas cobertura instável não são salvas.
-clean_target_on_coverage - Reinicia o alvo ao reproduzir cobertura. O padrão é true.
-minimize_samples - Tenta minimizar novas amostras antes de salvá-las no corpus. O padrão é true.
-iterations_per_round - Número de vezes para mutar e executar uma amostra do corpus antes de passar para a próxima amostra. O padrão é 1000. Você pode considerar diminuir este valor para alvos muito lentos.
-deterministic_mutations - Usa mutações determinísticas além das não determinísticas. O padrão é true, a menos que a flag -server seja usada.
-deterministic_only - Prioriza mutações determinísticas. Nota: mesmo com esta flag, o fuzzer ainda vai usar mutações não determinísticas, mas apenas depois que todas as mutações determinísticas tiverem sido esgotadas. Pode ser útil ao executar com um -server ter uma única instância cliente realizando mutações determinísticas.