
Automatize tarefas repetitivas para fuzzing
Reescrevendo completamente agora. O foco será em aplicativos Linux interativos que apenas recebem entrada do stdin para começar. Tentando usar a funcionalidade Driller e Fuzzer da Shellphish.
autoPwn em seu estado atual fará isso de forma limitada. Basta executar autoPwn ./binary e depois selecionar a opção Iniciar.
Devido a todos os problemas de dependência aqui, a maneira mais fácil de colocar o autoPwn em funcionamento é usar a construção Docker. Nota: você pode remover a declaração --security-opt e --cap-add, mas alguns aspectos de fuzzing podem não funcionar.
$ sudo docker pull bannsec/autoPwn
$ sudo docker run -it -v $PWD:/mount --security-opt="apparmor=unconfined" --cap-add=SYS_PTRACE -e DISPLAY=$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix/ bannsec/autopwn
Na construção Docker, tudo deve estar pronto para uso. Você pode simplesmente iniciar a ferramenta com:
$ autoPwn ./file
autoPwn tenta facilitar a compilação de código fonte para fuzzing de um projeto. Para ajudar com isso, foi criado o autoPwnCompile. Basta apontá-lo para seu código fonte, fornecer opções e ele produzirá um executável pronto para ser fuzzeado.
usage: autoPwnCompile [-h] [--file FILE] [--ASAN | --MSAN] [--UBSAN]
[--fuzzer FUZZER]
Compile source to binaries for use in autoPwn.
optional arguments:
-h, --help show this help message and exit
--file FILE Single file to compile.
--ASAN Enable ASAN (default off)
--MSAN Enable MSAN (default off)
--UBSAN Enable UBSAN (default off)
--fuzzer FUZZER (optional) What fuzzer to compile for. Options are:
['AFL']. Default is AFL.
O abaixo é da versão ANTIGA do autoPwn..
autoPwn é um nome pomposo para um script simples. Ao trabalhar com fuzzing e afl-fuzz, percebi que fazia as mesmas tarefas repetidamente. Com isso em mente, quis criar um script que realizasse o seguinte:
Até agora, o script é capaz de fazer os primeiros 5. A parte 6 é especulativa e está em desenvolvimento no momento. Ela aproveitaria o motor de execução simbólica angr para criar caminhos iniciais possíveis. Nesse ponto, o script poderia teoricamente automatizar completamente tarefas de fuzzing simples.
Vamos dar uma olhada em um desafio recente da TUCTF chamado "WoO2". Embora não encontre necessariamente o exploit necessário, ele mostra como autoPwn pode ser usado para simplificar a descoberta de caminhos.
Aqui está uma execução básica do programa:
$ ./e67eb287f23011a40ef5bd5c2ad2f48ca97834cf
Welcome! I don't think we're in Kansas anymore.
We're about to head off on an adventure!
Select some animals you want to bring along.
Menu Options:
1: Bring a lion
2: Bring a tiger
3: Bring a bear
4: Delete Animal
5: Exit
Enter your choice:
1
Choose the type of lion you want:
1: Congo Lion
2: Barbary Lion
1
Enter name of lion:
Test
Menu Options:
1: Bring a lion
2: Bring a tiger
3: Bring a bear
4: Delete Animal
5: Exit
Enter your choice:
5
Vamos criar um caso de teste de entrada simples:
$ cat in/1
1
1
Test
5
Agora podemos iniciar facilmente o fuzzer:
$ autoPwn
Setting up fuzz configuration
Target Binary (full or relative path): e67eb287f23011a40ef5bd5c2ad2f48ca97834cf
Command line args:
Number of cores (default: 8):
Test Case Dir (default: 'in/'):
Test Case Dir (default: 'out/'):
Max memory (default: 200): 4096
Starting fuzz
autoPwn> s
status check tool for afl-fuzz by <[email protected]>
Individual fuzzers
==================
>>> SESSION007 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION000 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION002 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION006 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION004 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION001 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION005 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION003 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
Summary stats
=============
Fuzzers alive : 8
Total run time : 0 days, 0 hours
Total execs : 0 million
Cumulative speed : 8 execs/sec
Pending paths : 8 faves, 8 total
Pending per fuzzer : 1 faves, 1 total (on average)
Crashes found : 0 locally unique
autoPwn> h
autoPwn
s == fuzzer (s)tatus
e == collect (e)xploits
a == collect (a)ll paths
m == (m)inimize corpus
q == (q)uit
Então, o que aconteceu aqui foi que o script criou alguns valores padrão (incluindo determinar o número de núcleos disponíveis). Alteramos um valor padrão devido à necessidade de memória extra para executar isso no QEMU. autoPwn criou um arquivo de configuração que então passou para o afl-utils (https://github.com/rc0r/afl-utils). No arquivo de configuração, ele também configurou afinidades de CPU, para que o fuzzing fosse otimizado por padrão.
Neste ponto, seu computador está trabalhando pesado no fuzzing. No entanto, um aspecto chave do fuzzing é minimizar o corpus. Com isso em mente, autoPwn está observando a instância do afl-fuzz para monitorar quando uma série de mutações é concluída. Quando isso acontece, ele interrompe o fuzzing (não é o ideal, mas funciona por agora), minimiza o corpus, e então reinicia o fuzzing. Ele faz isso sem qualquer intervenção humana, para que você possa configurar e esquecer.
Em algum momento, você pode querer dar uma olhada nos caminhos que o afl encontrou. Ao executar o comando 'a', o autoPwn copiará todos os caminhos conhecidos, minimizará o corpus e depois minimizará os próprios casos e os fornecerá em um diretório de saída.