Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
AFL — american fuzzy lop - un fuzzer orientato alla sicurezza | Kitploit
Strumenti/GitHubGitHub/google/afl
Analisi delle VulnerabilitàFuzzingPenetration TestingAnalisi di BinariArchived
GitHubgoogle/afl

AFL

american fuzzy lop - un fuzzer orientato alla sicurezza

Vedi Repository
4.2k6715 anni faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Sito web

american fuzzy lop

Build Status

Sviluppato originariamente da Michal Zalewski [email protected].

Vedi QuickStartGuide.txt se non hai tempo di leggere questo file.

1) Sfide del fuzzing guidato

Il fuzzing è una delle strategie più potenti e collaudate per identificare problemi di sicurezza in software reali; è responsabile della stragrande maggioranza dei bug di esecuzione remota di codice e di escalation dei privilegi trovati finora in software critici per la sicurezza.

Purtroppo, il fuzzing è anche relativamente superficiale; mutazioni casuali e cieche rendono molto improbabile raggiungere determinati percorsi del codice nel software testato, lasciando alcune vulnerabilità del tutto fuori dalla portata di questa tecnica.

Ci sono stati numerosi tentativi di risolvere questo problema. Uno dei primi approcci — di cui è stato pioniere Tavis Ormandy — è la distillazione del corpus. Il metodo si basa su segnali di copertura per selezionare un sottoinsieme di seed interessanti da un corpus massiccio e di alta qualità di file candidati, e poi sottoporli a fuzzing con mezzi tradizionali. L'approccio funziona eccezionalmente bene, ma richiede che un tale corpus sia prontamente disponibile. Inoltre, le misurazioni della copertura a blocchi forniscono solo una comprensione molto semplicistica dello stato del programma e sono meno utili per guidare lo sforzo di fuzzing nel lungo periodo.

Altre ricerche più sofisticate si sono concentrate su tecniche come l'analisi del flusso del programma ("esecuzione concolica"), l'esecuzione simbolica o l'analisi statica. Tutti questi metodi sono estremamente promettenti in contesti sperimentali, ma tendono a soffrire di problemi di affidabilità e prestazioni nell'uso pratico — e attualmente non offrono un'alternativa valida alle tecniche di fuzzing "cieco".

2) L'approccio di afl-fuzz

American Fuzzy Lop è un fuzzer brute-force accoppiato a un algoritmo genetico estremamente semplice ma solidissimo, guidato dalla strumentazione. Utilizza una forma modificata di copertura degli archi per cogliere senza sforzo sottili cambiamenti su scala locale nel flusso di controllo del programma.

Semplificando un po', l'algoritmo complessivo può essere riassunto come:

  1. Caricare i casi di test iniziali forniti dall'utente nella coda,

  2. Prendere il file successivo dalla coda,

  3. Tentare di ridurre il caso di test alla dimensione più piccola che non alteri il comportamento misurato del programma,

  4. Mutare ripetutamente il file usando una varietà equilibrata e ben studiata di strategie di fuzzing tradizionali,

  5. Se una qualsiasi delle mutazioni generate ha prodotto una nuova transizione di stato registrata dalla strumentazione, aggiungere l'output mutato come nuova voce nella coda.

  6. Tornare al punto 2.

I casi di test scoperti vengono inoltre periodicamente eliminati per rimuovere quelli resi obsoleti da nuove scoperte a copertura più elevata; e vengono sottoposti a diversi altri passaggi di minimizzazione dello sforzo guidati dalla strumentazione.

Come risultato collaterale del processo di fuzzing, lo strumento crea un corpus piccolo e autosufficiente di casi di test interessanti. Questi sono estremamente utili per fare da seme ad altri regimi di test che richiedono molto lavoro o molte risorse — ad esempio, per lo stress-test di browser, applicazioni da ufficio, suite grafiche o strumenti closed-source.

Il fuzzer è stato testato a fondo per offrire prestazioni immediate di gran lunga superiori al fuzzing cieco o agli strumenti basati solo sulla copertura.

3) Strumentazione dei programmi per l'uso con AFL

Quando il codice sorgente è disponibile, la strumentazione può essere iniettata da uno strumento complementare che funziona come sostituto diretto di gcc o clang in qualsiasi processo di build standard per codice di terze parti.

La strumentazione ha un impatto prestazionale abbastanza modesto; in combinazione con altre ottimizzazioni implementate da afl-fuzz, la maggior parte dei programmi può essere sottoposta a fuzzing con la stessa velocità o addirittura più velocemente di quanto sia possibile con gli strumenti tradizionali.

Il modo corretto per ricompilare il programma target può variare a seconda delle specifiche del processo di build, ma un approccio quasi universale sarebbe:```shell $ CC=/path/to/afl/afl-gcc ./configure $ make clean all

root@kitploit:~
Per i programmi C++, vorrai anche impostare `CXX=/path/to/afl/afl-g++`.

I wrapper clang (afl-clang e afl-clang++) possono essere usati allo stesso modo;
gli utenti di clang possono anche scegliere di sfruttare una modalità di strumentazione ad alte prestazioni,
come descritto in llvm_mode/README.llvm.

Quando si testano librerie, è necessario trovare o scrivere un semplice programma che legga
dati da stdin o da un file e li passi alla libreria testata. In tal
caso, è essenziale collegare questo eseguibile a una versione statica della
libreria strumentata, o assicurarsi che il file .so corretto venga caricato in
runtime (di solito impostando `LD_LIBRARY_PATH`). L'opzione più semplice è una build
statica, di solito possibile tramite:```shell
$ CC=/path/to/afl/afl-gcc ./configure --disable-shared

Impostando AFL_HARDEN=1 quando si chiama 'make', il wrapper CC abiliterà automaticamente le opzioni di hardening del codice che rendono più facile rilevare semplici bug di memoria. Libdislocator, una libreria ausiliaria inclusa con AFL (vedi libdislocator/README.dislocator) può aiutare a scoprire anche problemi di corruzione dell'heap.

PS. Agli utenti ASAN si consiglia di leggere il file notes_for_asan.txt per importanti avvertenze.

4) Instrumentazione di app solo binarie

Quando il codice sorgente NON è disponibile, il fuzzer offre supporto sperimentale per una strumentazione rapida e on-the-fly di binari black-box. Ciò è realizzato con una versione di QEMU eseguita nella meno nota modalità "user space emulation".

QEMU è un progetto separato da AFL, ma puoi comodamente compilare la funzionalità eseguendo:```shell $ cd qemu_mode $ ./build_qemu_support.sh

root@kitploit:~
Per ulteriori istruzioni e avvertenze, consultare qemu_mode/README.qemu.

La modalità è circa 2-5 volte più lenta rispetto all'instrumentazione a tempo di compilazione, è meno adatta alla parallelizzazione e può presentare alcune altre stranezze.

## 5) Scelta dei casi di test iniziali

Per funzionare correttamente, il fuzzer richiede uno o più file di partenza che contengano un buon esempio dei dati di input normalmente attesi dall'applicazione presa di mira. Ci sono due regole di base:

  - Mantieni i file piccoli. Sotto 1 kB è l'ideale, anche se non strettamente necessario.
    Per una discussione sul perché la dimensione conta, vedi [perf_tips.txt](https://github.com/google/afl/blob/HEAD/docs/perf_tips.txt).

  - Usa più casi di test solo se sono funzionalmente diversi tra loro.
    Non ha senso usare cinquanta diverse foto di vacanze per fare fuzzing su una libreria di immagini.

Puoi trovare molti buoni esempi di file di partenza nella sottodirectory testcases/ fornita con questo strumento.

PS. Se è disponibile un ampio corpus di dati per lo screening, potresti voler usare l'utilità afl-cmin per identificare un sottoinsieme di file funzionalmente distinti che esercitano diversi percorsi di codice nel binario target.

## 6) Fuzzing dei binari

Il processo di fuzzing stesso è eseguito dall'utilità afl-fuzz. Questo programma richiede una directory di sola lettura con i casi di test iniziali, un posto separato per memorizzare i suoi risultati, oltre a un percorso del binario da testare.

Per i binari target che accettano input direttamente da stdin, la sintassi usuale è:```shell
$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program [...params...]

Per i programmi che accettano input da un file, usa '@@' per indicare il punto nella riga di comando del target in cui deve essere inserito il nome del file di input. Il fuzzer lo sostituirà per te:```shell $ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@

root@kitploit:~
Puoi anche usare l'opzione -f per avere i dati mutati scritti in un file
specifico. Questo è utile se il programma si aspetta una particolare estensione di file o simili.

I binari non instrumentati possono essere sottoposti a fuzzing in modalità QEMU (aggiungi -Q nella riga di comando
o in una modalità tradizionale, da fuzzer cieco (specifica -n).

Puoi usare -t e -m per sovrascrivere il timeout e il limite di memoria predefiniti per il
processo eseguito; rari esempi di target che potrebbero aver bisogno di queste impostazioni
includono compilatori e decoder video.

Suggerimenti per ottimizzare le prestazioni del fuzzing sono discussi in [perf_tips.txt](https://github.com/google/afl/blob/HEAD/docs/perf_tips.txt).

Nota che afl-fuzz inizia eseguendo una serie di passaggi di fuzzing deterministico,
che possono richiedere diversi giorni, ma tendono a produrre casi di test puliti. Se vuoi
risultati rapidi e sporchi subito - simili a zzuf e altri fuzzer tradizionali -
aggiungi l'opzione -d alla riga di comando.

## 7) Interpretazione dell'output

Consulta il file [status_screen.txt](https://github.com/google/afl/blob/HEAD/docs/status_screen.txt) per informazioni su
come interpretare le statistiche visualizzate e monitorare la salute del processo.
Assicurati di consultare questo file soprattutto se alcuni elementi dell'interfaccia sono evidenziati in
rosso.

Il processo di fuzzing continuerà finché non premi Ctrl-C. Come minimo, devi
permettere al fuzzer di completare un ciclo di coda, che può richiedere da un
paio d'ore a una settimana circa.

All'interno della directory di output vengono create tre sottodirectory, aggiornate
in tempo reale:

  - queue/   - casi di test per ogni percorso di esecuzione distinto, più tutti i
               file iniziali forniti dall'utente. Questo è il corpus sintetizzato
               menzionato nella sezione 2.
               Prima di usare questo corpus per altri scopi, puoi ridurlo
               a una dimensione minore usando lo strumento afl-cmin. Lo strumento troverà
               un sottoinsieme più piccolo di file che offre una copertura degli edge equivalente.

  - crashes/ - casi di test unici che causano la ricezione di un segnale fatale
               da parte del programma testato (ad es. SIGSEGV, SIGILL, SIGABRT). Le voci sono
               raggruppate in base al segnale ricevuto.

  - hangs/   - casi di test unici che causano il timeout del programma testato. Il
               limite di tempo predefinito prima che qualcosa venga classificato come hang è
               il maggiore tra 1 secondo e il valore del parametro -t.
               Il valore può essere regolato con precisione impostando AFL_HANG_TMOUT, ma questo
               è raramente necessario.

I crash e gli hang sono considerati “unici” se i percorsi di esecuzione associati
coinvolgono transizioni di stato non viste in guasti registrati in precedenza. Se un
singolo bug può essere raggiunto in più modi, ci sarà una certa inflazione del conteggio
all'inizio del processo, ma dovrebbe ridursi rapidamente.

I nomi dei file per crash e hang sono correlati alle voci della coda padre non difettose.
Questo dovrebbe aiutare con il debug.

Quando non riesci a riprodurre un crash trovato da afl-fuzz, la causa più probabile è
che non stai impostando lo stesso limite di memoria usato dallo strumento. Prova:```shell
$ LIMIT_MB=50
$ ( ulimit -Sv $[LIMIT_MB << 10]; /path/to/tested_binary ... )

Modifica LIMIT_MB per corrispondere al parametro -m passato ad afl-fuzz. Su OpenBSD, cambia anche -Sv in -Sd.

Qualsiasi directory di output esistente può essere utilizzata anche per riprendere lavori interrotti; prova:```shell $ ./afl-fuzz -i- -o existing_output_dir [...etc...]

root@kitploit:~
Se hai gnuplot installato, puoi anche generare alcuni grafici accattivanti per qualsiasi attività di fuzzing attiva usando afl-plot. Per un esempio di come appare, consulta [http://lcamtuf.coredump.cx/afl/plot/](http://lcamtuf.coredump.cx/afl/plot/).

## 8) Fuzzing parallelizzato

Ogni istanza di afl-fuzz occupa all'incirca un core. Ciò significa che su sistemi multi-core la parallelizzazione è necessaria per utilizzare appieno l'hardware. Per suggerimenti su come eseguire il fuzzing di un target comune su più core o su più macchine in rete, fare riferimento a [parallel_fuzzing.txt](https://github.com/google/afl/blob/HEAD/docs/parallel_fuzzing.txt).

La modalità di fuzzing parallelo offre anche un modo semplice per interfacciare AFL con altri fuzzer, con motori di esecuzione simbolica o concolica e così via; ancora una volta, vedere l'ultima sezione di [parallel_fuzzing.txt](https://github.com/google/afl/blob/HEAD/docs/parallel_fuzzing.txt) per i suggerimenti.

## 9) Dizionari del fuzzer

Di default, il motore di mutazione di afl-fuzz è ottimizzato per formati di dati compatti - ad esempio immagini, multimedia, dati compressi, sintassi di espressioni regolari o script di shell. È un po' meno adatto a linguaggi con una verbosità particolarmente prolissa e ridondante - in particolare HTML, SQL o JavaScript.

Per evitare la seccatura di costruire strumenti consapevoli della sintassi, afl-fuzz offre un modo per alimentare il processo di fuzzing con un dizionario opzionale di parole chiave del linguaggio, header magici o altri token speciali associati al tipo di dati preso di mira - e usarlo per ricostruire al volo la grammatica sottostante:

  [http://lcamtuf.blogspot.com/2015/01/afl-fuzz-making-up-grammar-with.html](http://lcamtuf.blogspot.com/2015/01/afl-fuzz-making-up-grammar-with.html)

Per usare questa funzionalità, devi innanzitutto creare un dizionario in uno dei due formati discussi in dictionaries/README.dictionaries; poi indicare al fuzzer di usarlo tramite l'opzione -x nella riga di comando.

(In quella sottodirectory sono già forniti anche diversi dizionari comuni.)

Non c'è modo di fornire descrizioni più strutturate della sintassi sottostante, ma il fuzzer probabilmente riuscirà a dedurne una parte basandosi solo sul feedback dell'instrumentazione. Questo funziona davvero nella pratica, ad esempio:

  [http://lcamtuf.blogspot.com/2015/04/finding-bugs-in-sqlite-easy-way.html](http://lcamtuf.blogspot.com/2015/04/finding-bugs-in-sqlite-easy-way.html)

PS. Anche quando non viene fornito un dizionario esplicito, afl-fuzz proverà a estrarre i token di sintassi esistenti nel corpus di input osservando molto attentamente l'instrumentazione durante i flip deterministici dei byte. Questo funziona per alcuni tipi di parser e grammatiche, ma non è neanche lontanamente buono come la modalità -x.

Se un dizionario è davvero difficile da ottenere, un'altra opzione è lasciare girare AFL per un po' e poi usare la libreria di cattura dei token che viene fornita come utilità complementare ad AFL. A tal fine, vedere libtokencap/README.tokencap.

## 10) Triage dei crash

Il raggruppamento dei crash basato sulla copertura di solito produce un set di dati ridotto che può essere rapidamente analizzato manualmente o con uno script GDB o Valgrind molto semplice. Ogni crash è inoltre riconducibile al suo test case genitore non crashante nella coda, semplificando la diagnosi dei difetti.

Detto questo, è importante riconoscere che alcuni crash di fuzzing possono essere difficili da valutare rapidamente per quanto riguarda la sfruttabilità senza molto lavoro di debugging e analisi del codice. Per assistere in questo compito, afl-fuzz supporta una modalità molto particolare di "esplorazione dei crash" attivata con il flag -C.

In questa modalità, il fuzzer prende in input uno o più test case che causano crash e usa le sue strategie di fuzzing guidate dal feedback per enumerare molto rapidamente tutti i percorsi di codice raggiungibili nel programma mantenendolo nello stato di crash.

Le mutazioni che non provocano un crash vengono respinte; allo stesso modo vengono respinte le modifiche che non influiscono sul percorso di esecuzione.

L'output è un piccolo corpus di file che può essere esaminato molto rapidamente per vedere quale grado di controllo ha l'attaccante sull'indirizzo che causa il fault, o se è possibile superare una lettura fuori dai limiti iniziale - e vedere cosa c'è sotto.

Oh, un'ultima cosa: per la minimizzazione dei test case, prova afl-tmin. Lo strumento può essere utilizzato in modo molto semplice:```shell
$ ./afl-tmin -i test_case -o minimized_result -- /path/to/program [...]

Lo strumento funziona sia con casi di test che causano crash sia con quelli che non li causano. Nella modalità crash, accetta volentieri binari instrumentati e non instrumentati. Nella modalità non-crash, il minimizer si basa sulla strumentazione standard di AFL per rendere il file più semplice senza alterare il percorso di esecuzione.

Il minimizer accetta la sintassi -m, -t, -f e @@ in modo compatibile con afl-fuzz.

Un'altra recente aggiunta ad AFL è lo strumento afl-analyze. Prende un file di input, tenta di invertire byte in sequenza e osserva il comportamento del programma testato. Poi codifica a colori l'input in base a quali sezioni appaiono critiche e quali no; pur non essendo infallibile, può spesso offrire rapidi spunti sui formati di file complessi. Ulteriori informazioni sul suo funzionamento si trovano vicino alla fine di technical_details.txt.

11) Andare oltre i crash

Il fuzzing è una tecnica meravigliosa e sottoutilizzata per scoprire anche errori di progettazione e implementazione che non causano crash. Non pochi bug interessanti sono stati trovati modificando i programmi target per chiamare abort() quando, ad esempio:

  • Due librerie bignum producono output diversi quando ricevono lo stesso input generato dal fuzzer,

  • Una libreria grafica produce output diversi quando le viene chiesto di decodificare la stessa immagine di input più volte di seguito,

  • Una libreria di serializzazione / deserializzazione non riesce a produrre output stabili quando serializza e deserializza in modo iterativo dati forniti dal fuzzer,

  • Una libreria di compressione produce un output incoerente rispetto al file di input quando le viene chiesto di comprimere e poi decomprimere un particolare blob.

Implementare questi o simili controlli di sanità richiede di solito pochissimo tempo; se sei il manutentore di un determinato pacchetto, puoi rendere questo codice condizionale con #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION (una flag condivisa anche con libfuzzer) o #ifdef __AFL_COMPILER (quest'ultima è solo per AFL).

12) Rischi di buon senso

Tieni presente che, come per molte altre attività computazionalmente intensive, il fuzzing può mettere sotto stress l'hardware e il sistema operativo. In particolare:

  • La tua CPU diventerà calda e avrà bisogno di un raffreddamento adeguato. Nella maggior parte dei casi, se il raffreddamento è insufficiente o smette di funzionare correttamente, la velocità della CPU verrà automaticamente limitata. Detto questo, soprattutto quando si esegue il fuzzing su hardware meno adatto (laptop, smartphone, ecc.), non è del tutto impossibile che qualcosa salti in aria.

  • I programmi testati potrebbero finire per allocare in modo erratico gigabyte di memoria o riempire lo spazio su disco con file spazzatura. AFL cerca di imporre limiti di memoria di base, ma non può prevenire ogni singolo incidente possibile. In conclusione, non dovresti fare fuzzing su sistemi in cui la prospettiva di perdita di dati non è un rischio accettabile.

  • Il fuzzing comporta miliardi di letture e scritture sul filesystem. Sui sistemi moderni, di solito queste operazioni vengono pesantemente memorizzate nella cache, con conseguente I/O "fisico" piuttosto modesto, ma ci sono molti fattori che possono modificare questa equazione. È tua responsabilità monitorare potenziali problemi; con un I/O molto intenso, la durata di molti HDD e SSD può ridursi.

    Un buon modo per monitorare l'I/O del disco su Linux è il comando 'iostat':```shell $ iostat -d 3 -x -k [...optional disk ID...]

root@kitploit:~
## 13) Limitazioni note e aree di miglioramento

Ecco alcune delle avvertenze più importanti per AFL:

  - AFL rileva i guasti controllando se il primo processo generato muore a causa di
    un segnale (SIGSEGV, SIGABRT, ecc.). I programmi che installano handler personalizzati per
    questi segnali potrebbero dover commentare il codice pertinente. Allo stesso
    modo, i guasti nei processi figli generati dal target sottoposto a fuzzing possono sfuggire
    al rilevamento, a meno che non si aggiunga manualmente del codice per intercettarli.

  - Come per qualsiasi altro strumento di brute force, il fuzzer offre una copertura limitata se
    crittografia, checksum, firme crittografiche o compressione vengono utilizzati per
    avvolgere completamente il formato dati effettivo da testare.

    Per aggirare il problema, puoi commentare i controlli pertinenti (vedi
    experimental/libpng_no_checksum/ per ispirazione); se non è possibile,
    puoi anche scrivere un postprocessore, come spiegato in
    experimental/post_library/.

  - Ci sono alcuni compromessi sfortunati con ASAN e i binari a 64 bit. Questo
    non è dovuto a un difetto specifico di afl-fuzz; vedi [notes_for_asan.txt](https://github.com/google/afl/blob/HEAD/docs/notes_for_asan.txt)
    per suggerimenti.

  - Non esiste un supporto diretto per il fuzzing di servizi di rete, daemon in
    background o app interattive che richiedono l'interazione con l'UI per funzionare. Potresti
    dover apportare semplici modifiche al codice per farli comportare in modo più
    tradizionale. Preeny può offrire un'opzione relativamente semplice, anche: 
    https://github.com/zardus/preeny

    Alcuni suggerimenti utili per modificare i servizi basati su rete si trovano anche su:
    https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop

  - AFL non genera dati di copertura leggibili dall'uomo. Se vuoi monitorare
    la copertura, usa afl-cov di Michael Rash: https://github.com/mrash/afl-cov

  - Ogni tanto, macchine senzienti si ribellano ai loro creatori. Se questo
    ti accade, consulta http://lcamtuf.coredump.cx/prep/.

Oltre a questo, vedi INSTALL per suggerimenti specifici per piattaforma.

## 14) Ringraziamenti speciali

Molti dei miglioramenti a afl-fuzz non sarebbero possibili senza feedback,
segnalazioni di bug o patch da parte di:```
  Jann Horn                             Hanno Boeck
  Felix Groebert                        Jakub Wilk
  Richard W. M. Jones                   Alexander Cherepanov
  Tom Ritter                            Hovik Manucharyan
  Sebastian Roschke                     Eberhard Mattes
  Padraig Brady                         Ben Laurie
  @dronesec                             Luca Barbato
  Tobias Ospelt                         Thomas Jarosch
  Martin Carpenter                      Mudge Zatko
  Joe Zbiciak                           Ryan Govostes
  Michael Rash                          William Robinet
  Jonathan Gray                         Filipe Cabecinhas
  Nico Weber                            Jodie Cunningham
  Andrew Griffiths                      Parker Thompson
  Jonathan Neuschfer                    Tyler Nighswander
  Ben Nagy                              Samir Aguiar
  Aidan Thornton                        Aleksandar Nikolich
  Sam Hakim                             Laszlo Szekeres
  David A. Wheeler                      Turo Lamminen
  Andreas Stieger                       Richard Godbee
  Louis Dassy                           teor2345
  Alex Moneger                          Dmitry Vyukov
  Keegan McAllister                     Kostya Serebryany
  Richo Healey                          Martijn Bogaard
  rc0r                                  Jonathan Foote
  Christian Holler                      Dominique Pelle
  Jacek Wielemborek                     Leo Barnes
  Jeremy Barnes                         Jeff Trull
  Guillaume Endignoux                   ilovezfs
  Daniel Godas-Lopez                    Franjo Ivancic
  Austin Seipp                          Daniel Komaromy
  Daniel Binderman                      Jonathan Metzman
  Vegard Nossum                         Jan Kneschke
  Kurt Roeckx                           Marcel Bohme
  Van-Thuan Pham                        Abhik Roychoudhury
  Joshua J. Drake                       Toby Hutton
  Rene Freingruber                      Sergey Davidoff
  Sami Liedes                           Craig Young
  Andrzej Jackowski                     Daniel Hodson

Grazie!

15) Contatti

Domande? Preoccupazioni? Segnalazioni di bug? Per favore, usa GitHub.

C'è anche una mailing list per il progetto; per iscriverti, invia una mail a [email protected]. Oppure, se preferisci consultare prima gli archivi, prova: https://groups.google.com/group/afl-users.

Scarica lo strumento