v1.4 Copyright (C) 2020 Andrea Fioraldi [email protected]
Lançado sob a licença Apache v2.0
Este fuzzer experimental deve ser usado para difusão na memória da API.
O design é altamente inspirado e baseado em AFL/AFL++.
ATM o mutador é bastante simples, apenas os estágios de destruição e emenda do AFL.
Testei apenas os exemplos em testes/, este é um projeto WIP, mas é conhecido por funcionar pelo menos em 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 chicote.
A biblioteca fuzz
deve ser importada para um chicote personalizado e então compilada com frida-compile
para gerar o agente que frida-fuzzer
injetará no aplicativo de destino.
A maior parte da lógica do fuzzer está no agente.
Um arnês 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 = ['ponteiro', ' 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 , carga útil, carga útil.length); func_handle(payload_mem, carga útil.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 retorno de chamada e, portanto, ele não deve chamá-lo para você (por exemplo, para iniciar a difusão quando um botão for clicado no aplicativo Android).
O retorno de chamada fuzz.init_callback
pode ser configurado para executar o código quando o fuzzer estiver pronto para começar. Veja tests/test_java.js
para ver um exemplo.
fuzz.dictionary
é um dicionário fuzzer clássico, 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 modificador. Veja tests/test_libxml2.js
para ver um exemplo.
frida-fuzzer
aceita os seguintes argumentos:
-i PASTA | Pasta com sementes iniciais |
-o PASTA | Pasta de saída com sementes e travamentos intermediários |
-Você | Conecte-se ao USB |
-spawn | Gerar e anexar em vez de simplesmente anexar |
-script SCRIPT | Nome do arquivo do script (o padrão é fuzzer-agent.js) |
Se você não especificar a pasta de saída, uma pasta temporária será criada em /tmp. Se você não especificar a pasta com o seed inicial, um seed não informado 0000
será usado como seed inicial.
Se você estiver modificando um aplicativo local, você pode executar system-config
antes 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 em seu terminal:
Você também pode adicionar facilmente 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á difundindo 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 (aumentar o tamanho do cache da fila para mais velocidade, especialmente no Android).
Vamos analisar 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 Android x86_64 frida-server na página de lançamento do repositório e copie-o no dispositivo em /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
enviada com o aplicativo de teste com o comando:
host$ ./frida-fuzzer -U -o output_folder/ com.example.ndktest1
Casos de teste e travamentos interessantes são salvos em output_folder.
Aproveitar.
Olá comunidade OSS, há muitos TODOs se alguém quiser contribuir.
Fuzzing de código Java (aguardar métodos expostos adicionais em frida-java-bridge, deve ser fácil, quase pronto)
estágio de emenda (mescla dois casos de teste na fila e causa estragos nele)
apoiar dicionários (e assim modificar também o caos)
seleção de sementes
instrumentação embutida para arm64
pontuação de desempenho (explorar cronograma da AFL)
modificador estrutural (mutação de bytes com base em uma gramática escrita em JSON)
CompareCoverage (perfil de subinstrução para contornar obstáculos confusos)
reescrever frida-fuzzer em C com frida-core para poder rodar tudo no dispositivo móvel
Se você tiver dúvidas sobre algum desses recursos, sinta-se à vontade para me enviar um DM no Twitter.
Para propostas de recursos, existe a seção Problemas.