.
Există o serie de fuzzeri în sălbăticie, inclusiv Peach și syzkaller. Deci, de ce AFL?
Cazul de utilizare. Acesta este cel mai important punct de luat în considerare. Cazul meu de utilizare a fost să fac fuzz la o aplicație care primește date de intrare dintr-un fișier. Este important de reținut că AFL nu are capacitatea de a face fuzz prin rețele.
Este simplu de instalat.
Interfața UI a AFL conține o tonă de informații, inclusiv statistici în timp real ale procesului de fuzzing.
Configurarea AFL
Configurarea AFL este ușoară și am făcut-o mai ușoară pentru dumneavoastră prin scrierea unui script shell simplu (dar rudimentar) care îl va instala pentru dumneavoastră! Rulați scriptul cu privilegiile dvs. de utilizator și acesta va instala toate dependențele, AFL și instrumentele aferente. Scriptul shell poate fi găsit aici: https://github.com/nikhilh-20/enpm691_project/blob/master/install_afl.sh
Alegeți aplicația de fuzzat
În această postare, ne vom ocupa doar de fuzzarea acelor aplicații pentru care avem codul sursă. Acest lucru se datorează faptului că AFL instrumentează codul sursă pentru a monitoriza execuția, erorile și alte lucruri legate de performanță. De asemenea, este posibil să fuzzăm direct un executabil, dar acest lucru este experimental și nu face parte din scopul acestei postări (sfat: necesită QEMU).
Alegeți orice sistem open source de pe GitHub pentru fuzzing. Cu cât alegerea dvs. este mai cunoscută, cu atât va avea probabil un număr mai mic de vulnerabilități. Și alții caută bug-uri! O metodă simplă pe care o folosesc pentru a găsi cod vulnerabil este să folosesc GitHub Search. Iată ce fac:
Căutați o funcție vulnerabilă, să zicem strcpy.
Rezultatele vor fi de ordinul milioanelor. Mergeți la categoria commits a rezultatelor. Aici veți găsi acele depozite în care strcpy a fost folosit (sau poate eliminat). Aceste depozite sunt un bun punct de plecare pentru a începe fuzzing.
Instrumenting the Application
Din motive de confidențialitate, nu pot dezvălui depozitul pe care îl folosesc.
Clonează depozitul git.
nikhilh@ubuntu:~$ git clone https://github.com/vuln; cd vuln
Stabilește o variabilă de mediu, AFL_HARDEN=1. Aceasta activează anumite opțiuni de întărire a codului în AFL în timpul compilării, ceea ce facilitează detectarea bug-urilor de corupție a memoriei.
nikhilh@ubuntu:~/vuln$ export AFL_HARDEN=1
Setați anumiți indicatori ai compilatorului, astfel încât aplicația să fie compilată într-un mod care să ne faciliteze găsirea (și exploatarea) vulnerabilităților. Ideal ar fi să folosim variabilele de mediu pentru a seta ceea ce avem nevoie, dar există destul de multă personalizare. așa că vom edita direct fișierul Makefile.
Asigurați-vă că compilatorul folosit este afl-gcc sau afl-clang în loc de gcc și respectiv clang. Acest lucru este ceea ce permite AFL să instrumenteze codul sursă.
Adaugați stegulețe de compilator:
-fno-stack-protector dezactivează stack protector, ceea ce ne va permite să exploatăm buffer overflows.
-m32 este necesar doar dacă folosiți o mașină pe 32 de biți, altfel nu.
După ce ați terminat cu aceste modificări, este timpul să compilați aplicația. Rulați make. Când o faceți, TREBUIE să vedeți declarații ca acestea în jurnal:
Instrumented 123 locations (32-bit, hardened-mode, ratio 100%).
Dacă nu vedeți astfel de declarații, înseamnă că AFL nu a activat codul aplicației pentru fuzzing. Cu alte cuvinte, nu a instrumentat cu succes codul sursă.
Eșantioane de testare
AFL este un tip evolutiv de fuzzer. Aceasta înseamnă că, la fel ca și fuzzerele bazate pe generație, are nevoie de date de testare inițiale pentru a înțelege ce fel de date așteaptă aplicația țintă. Atunci când se vizează sisteme open source, acest lucru este ușor de găsit. Trebuie doar să vă uitați în directorul lor de test și veți găsi toate datele de test de care aveți nevoie.
nikhilh@ubuntu:~/vuln$ mkdir afl_in afl_out
nikhilh@ubuntu:~/vuln$ cp test/* afl_in/
Fuzzing Begins
Acum că avem mostrele noastre de test, suntem gata să facem fuzz!
Oh, așteptați… trebuie să schimbăm și locul unde merg notificările de accident ale aplicației. By default, when an application crashes, the core dump (basically, the contents of RAM are stored in a file to help in debugging) notification is sent to the system’s core handler. We don’t want this. Why? By the time this notification reaches AFL, it’ll be classified as a timeout rather than a crash.
nikhilh@ubuntu:~/vuln$ sudo su
password for nikhilh:
root@ubuntu:/home/nikhilh/vuln# echo core > /proc/sys/kernel/core_pattern
root@ubuntu:/home/nikhilh/vuln# exit
NOW, we are ready to fuzz!
nikhilh@ubuntu:~/vuln$ afl-fuzz -i afl_in -o afl_out -S slaveX — ./vuln @@
Command line flags used:
-i — This marks the test input directory. Aici am stocat datele inițiale de testare.
-o- Acesta este directorul în care AFL scrie informații utile cu privire la accidentări, blocaje, etc.
-S – Acesta este modul Slave. Practic, AFL va modifica la întâmplare datele de intrare, cauzând fuzzing nedeterminist.
Opțiunea -M este modul Master, care este fuzzing determinist, ceea ce înseamnă, în esență, că fiecare bit de intrare este modificat într-un fel. (Acest lucru este lent! … Evident.)
@@ – Aceasta este poziția în care se va afla fișierul de test de intrare. AFL înlocuiește acest lucru pentru dvs. în mod automat. Dacă executabilul dvs. primește intrare de la STDIN, atunci acest lucru nu este necesar.
Fuzzing Results
Aceasta va dura ceva timp pentru a se afișa. De multe ori, oamenii fac fuzz pentru mai mult de 24 de ore (și s-ar putea să se termine cu nimic). În cazul meu, cred că aplicația a fost un pic prea vulnerabilă, așa că am avut 516 crash-uri unice în decurs de o oră. Totuși, asta nu înseamnă că există 516 vulnerabilități!
Puteți ieși din sesiunea de fuzzing cu un Ctrl-C.
Analysis Phase
Now that we have results, we need to analyze them to see which ones are exploitable. To this end, we will use one of AFL’s utilities called afl-collect. This will have been installed through the installation script as well.
nikhilh@ubuntu:~/afl-utils$ afl-collect -d crashes.db -e gdb_script -r -rr ~/vuln/afl_out/slaveX ./output_dir — ~/vuln/vuln
To understand what each command line flag does, refer to its help section.
nikhilh@ubuntu:~/afl-utils$ afl-collect — help
If you see lines such as these in the output, celebrate! You’ve found something interesting to try and exploit.
*** GDB+EXPLOITABLE SCRIPT OUTPUT ***
…
…
slaveX:id:000000,sig:11,src:000000,op:havoc,rep:2……………:EXPLOITABLE
…
slaveX:id:000046,sig:11,src:000004,op:havoc,rep:4……………:EXPLOITABLE
…
AFL vă va arăta ce intrare a cauzat blocarea aplicației. În acest caz, fișierul: id:000046,sig:11,src:000004,op:havoc,rep:4 a cauzat un StackBufferOverflow în aplicație. Astfel de fișiere pot fi găsite în ../afl_out-slaveX/crashes/
Done!
Asta este tot pentru un început rapid în fuzzing! Procesul este foarte simplu și foarte convenabil, deoarece totul este automatizat. Următorul pas ar fi să analizăm de ce intrarea a cauzat un Buffer Overflow și să căutăm o modalitate de a-l exploata. Nu uitați că nu toate vulnerabilitățile pot duce la o exploatare.
.