
Este fuzzer experimental foi concebido para ser usado em fuzzing in-memory de APIs.
v1.4 Copyright (C) 2020 Andrea Fioraldi [email protected]
Lançado sob a Licença Apache v2.0
Este fuzzer experimental é destinado a ser usado para fuzzing de API em memória.
O design é fortemente inspirado e baseado em AFL/AFL++.
No momento, o mutador é bastante simples, apenas os estágios havoc e splice do AFL.
Testei apenas os exemplos em tests/, este é um projeto em andamento (WIP), mas sabe-se que funciona pelo menos no GNU/Linux x86_64 e Android x86_64.
Você precisa do Frida >= 12.8.1 para executar isso (pip3 install -U frida) e do frida-tools para compilar o harness.
A biblioteca fuzz deve ser importada para um harness personalizado e então compilada com frida-compile para gerar o agente que o frida-fuzzer irá injetar no aplicativo alvo.
A maior parte da lógica do fuzzer está no agente.
Um harness tem o seguinte formato:
var fuzz = require("./fuzz");
var TARGET_MODULE = "test_linux64";
var TARGET_FUNCTION = DebugSymbol.fromName("target_func").address;;
var RET_TYPE = "void";
var ARGS_TYPES = ['pointer', 'int'];
var func_handle = new NativeFunction(TARGET_FUNCTION, RET_TYPE, ARGS_TYPES, { traps: 'all' });
fuzz.target_module = TARGET_MODULE;
var payload_mem = Memory.alloc(fuzz.config.MAX_FILE);
fuzz.fuzzer_test_one_input = function (/* Uint8Array */ payload) {
Memory.writeByteArray(payload_mem, payload, payload.length);
func_handle(payload_mem, payload.length);
}
fuzz.fuzzer_test_one_input é obrigatório. Se você não especificar fuzz.target_module, todo o código executado será instrumentado.
Você também pode definir fuzz.manual_loop_start = true para informar ao fuzzer que você chamará fuzz.fuzzing_loop() em um callback e, portanto, ele não deve chamá-lo para você (por exemplo, para iniciar o fuzzing quando um botão for clicado no aplicativo Android).
O callback fuzz.init_callback pode ser definido para executar código quando o fuzzer estiver pronto para começar. Veja tests/test_java.js para um exemplo.
fuzz.dictionary é um dicionário clássico de fuzzer, um array no qual você pode adicionar itens (os tipos aceitos são Array, ArrayBuffer, Uint8Array, String) que são usados como valores adicionais no mutador. Veja tests/test_libxml2.js para um exemplo.
frida-fuzzer aceita os seguintes argumentos:
Se você não especificar a pasta de saída, uma pasta temporária é criada em /tmp.
Se você não especificar a pasta com a semente inicial, uma semente não informada 0000 é usada como semente inicial.
Se você está fuzzing um aplicativo local, talvez queira executar system-config antes do frida-fuzzer para ajustar os parâmetros do seu sistema e acelerar as coisas.
Executando ./frida-fuzzer -spawn ./tests/test_linux64 você verá algo como a seguinte tela de status no seu terminal:

Você também pode facilmente adicionar um estágio personalizado em fuzz/fuzzer.js e adicioná-lo à lista de estágios em fuzz/index.js.
Para personalizar o fuzzer, edite fuzz/config.js.
As variáveis que você pode querer alterar são MAP_SIZE (se o código que você está fuzzing for pequeno, você pode reduzi-lo e ganhar um pouco de velocidade), MAX_FILE (o tamanho máximo da entrada gerada) e QUEUE_CACHE_MAX_SIZE (aumente o tamanho do cache da fila para mais velocidade, especialmente no Android).
Vamos fuzz a biblioteca compartilhada nativa no aplicativo Android de exemplo em tests.
Certifique-se de ter root no seu dispositivo virtual:
host$ adb root
Baixe o frida-server Android x86_64 da página de lançamentos do repositório e copie-o no dispositivo para /data/local/tmp (use adb push).
Inicie um shell e execute o frida-server:
device# cd /data/local/tmp
device# ./frida-server
Agora instale o aplicativo de teste tests/app-debug.apk usando arrastar e soltar na janela do emulador.
Em seguida, abra o aplicativo.
Compile o script do agente com frida-compile:
host$ frida-compile -x tests/test_ndk_x64.js -o fuzzer-agent.js
Abra o aplicativo no emulador.
Fuzz a função test_func da biblioteca libnative-lib.so fornecida com o aplicativo de teste com o comando:
host$ ./frida-fuzzer -U -o output_folder/ com.example.ndktest1
Casos de teste interessantes e crashes são salvos na output_folder.
Aproveite.

Ei, comunidade OSS, há muitos TODOs se alguém quiser contribuir.
Se você tiver dúvidas sobre um desses recursos, sinta-se à vontade para me enviar DM no Twitter.
Para propostas de recursos, existe a seção de Issues.
| -i PASTA | Pasta com sementes iniciais |
| -o PASTA | Pasta de saída com sementes intermediárias e crashes |
| -U | Conectar ao USB |
| -spawn | Spawn e anexar em vez de apenas anexar |
| -script SCRIPT | Nome do arquivo de script (padrão é fuzzer-agent.js) |