
american fuzzy lop - एक सुरक्षा-उन्मुख फ़ज़र
मूल रूप से माइकल ज़ेलेव्स्की [email protected] द्वारा विकसित।
यदि आपके पास इस फ़ाइल को पढ़ने का समय नहीं है, तो QuickStartGuide.txt देखें।
फ़ज़िंग वास्तविक दुनिया के सॉफ़्टवेयर में सुरक्षा समस्याओं की पहचान करने के लिए सबसे शक्तिशाली और सिद्ध रणनीतियों में से एक है; यह सुरक्षा-महत्वपूर्ण सॉफ़्टवेयर में आज तक पाए गए रिमोट कोड निष्पादन और विशेषाधिकार वृद्धि बगों के विशाल बहुमत के लिए ज़िम्मेदार है।
दुर्भाग्य से, फ़ज़िंग अपेक्षाकृत उथली भी है; अंधा, यादृच्छिक उत्परिवर्तन परीक्षण किए गए कोड में कुछ कोड पथों तक पहुँचना बहुत असंभव बना देते हैं, जिससे कुछ कमजोरियाँ इस तकनीक की पहुँच से बाहर रह जाती हैं।
इस समस्या को हल करने के कई प्रयास हुए हैं। प्रारंभिक दृष्टिकोणों में से एक - जिसकी शुरुआत टैविस ऑरमैंडी ने की - कॉर्पस आसवन (corpus distillation) है। यह विधि उम्मीदवार फ़ाइलों के एक विशाल, उच्च-गुणवत्ता वाले कॉर्पस से दिलचस्प सीड्स का एक उपसमुच्चय चुनने के लिए कवरेज सिग्नल पर निर्भर करती है, और फिर उन्हें पारंपरिक तरीकों से फ़ज़ करती है। यह दृष्टिकोण असाधारण रूप से अच्छा काम करता है, लेकिन इसके लिए ऐसे कॉर्पस का आसानी से उपलब्ध होना आवश्यक है। इसके अलावा, ब्लॉक कवरेज माप प्रोग्राम की स्थिति की केवल एक बहुत ही सरल समझ प्रदान करते हैं, और लंबी अवधि में फ़ज़िंग प्रयास का मार्गदर्शन करने के लिए कम उपयोगी होते हैं।
अन्य, अधिक परिष्कृत शोध ने प्रोग्राम फ़्लो विश्लेषण ("concolic execution"), प्रतीकात्मक निष्पादन, या स्थैतिक विश्लेषण जैसी तकनीकों पर ध्यान केंद्रित किया है। ये सभी विधियाँ प्रयोगात्मक सेटिंग्स में अत्यंत आशाजनक हैं, लेकिन व्यावहारिक उपयोगों में विश्वसनीयता और प्रदर्शन समस्याओं से ग्रस्त होती हैं - और वर्तमान में "डम्ब" फ़ज़िंग तकनीकों के लिए एक व्यवहार्य विकल्प प्रदान नहीं करती हैं।
अमेरिकन फ़ज़ी लोप एक ब्रूट-फोर्स फ़ज़र है जो एक अत्यंत सरल लेकिन ठोस इंस्ट्रुमेंटेशन-निर्देशित आनुवंशिक एल्गोरिदम से युक्त है। यह प्रोग्राम नियंत्रण प्रवाह में सूक्ष्म, स्थानीय-स्तरीय परिवर्तनों को सहजता से पकड़ने के लिए एज कवरेज के एक संशोधित रूप का उपयोग करता है।
थोड़ा सरल करते हुए, समग्र एल्गोरिदम को इस प्रकार संक्षेपित किया जा सकता है:
उपयोगकर्ता-आपूर्ति किए गए प्रारंभिक परीक्षण मामलों को कतार में लोड करें,
कतार से अगली इनपुट फ़ाइल लें,
परीक्षण मामले को सबसे छोटे आकार में छाँटने का प्रयास करें जो प्रोग्राम के मापा व्यवहार को नहीं बदलता,
पारंपरिक फ़ज़िंग रणनीतियों की एक संतुलित और अच्छी तरह से शोधित विविधता का उपयोग करके फ़ाइल को बार-बार उत्परिवर्तित करें,
यदि उत्पन्न उत्परिवर्तनों में से कोई भी इंस्ट्रुमेंटेशन द्वारा दर्ज एक नया स्टेट ट्रांज़िशन में परिणत हुआ, तो उत्परिवर्तित आउटपुट को कतार में एक नई प्रविष्टि के रूप में जोड़ें।
चरण 2 पर जाएँ।
खोजे गए परीक्षण मामलों को भी समय-समय पर हटाया जाता है ताकि उन्हें समाप्त किया जा सके जो नए, उच्च-कवरेज खोजों द्वारा अप्रचलित हो गए हैं; और कई अन्य इंस्ट्रुमेंटेशन-संचालित प्रयास न्यूनीकरण चरणों से गुजरते हैं।
फ़ज़िंग प्रक्रिया के एक पार्श्व परिणाम के रूप में, उपकरण दिलचस्प परीक्षण मामलों का एक छोटा, स्व-निहित कॉर्पस बनाता है। ये अन्य, श्रम- या संसाधन-गहन परीक्षण व्यवस्थाओं को सीड करने के लिए अत्यंत उपयोगी हैं - उदाहरण के लिए, ब्राउज़र, ऑफिस एप्लिकेशन, ग्राफिक्स सुइट्स या क्लोज्ड-सोर्स टूल्स के स्ट्रेस-टेस्टिंग के लिए।
फ़ज़र का पूरी तरह से परीक्षण किया गया है ताकि यह ब्लाइंड फ़ज़िंग या केवल-कवरेज टूल्स से कहीं बेहतर आउट-ऑफ-द-बॉक्स प्रदर्शन प्रदान करे।
जब स्रोत कोड उपलब्ध होता है, तो इंस्ट्रुमेंटेशन को एक साथी उपकरण द्वारा इंजेक्ट किया जा सकता है जो तृतीय-पक्ष कोड के लिए किसी भी मानक बिल्ड प्रक्रिया में gcc या clang के ड्रॉप-इन प्रतिस्थापन के रूप में कार्य करता है।
इंस्ट्रुमेंटेशन का प्रदर्शन पर काफी मामूली प्रभाव पड़ता है; afl-fuzz द्वारा लागू अन्य अनुकूलनों के साथ, अधिकांश प्रोग्रामों को पारंपरिक टूल्स से संभव होने वाली गति से उतनी ही तेज़ी से या उससे भी तेज़ी से फ़ज़ किया जा सकता है।
लक्ष्य प्रोग्राम को फिर से संकलित करने का सही तरीका बिल्ड प्रक्रिया की विशिष्टताओं के आधार पर भिन्न हो सकता है, लेकिन लगभग-सार्वभौमिक दृष्टिकोण यह होगा:```shell $ CC=/path/to/afl/afl-gcc ./configure $ make clean all
C++ प्रोग्रामों के लिए, आप `CXX=/path/to/afl/afl-g++` भी सेट करना चाहेंगे।
clang रैपर (afl-clang और afl-clang++) उसी तरह इस्तेमाल किए जा सकते हैं;
clang उपयोगकर्ता उच्च-प्रदर्शन वाले इंस्ट्रूमेंटेशन मोड का लाभ ले सकते हैं,
जैसा कि llvm_mode/README.llvm में वर्णित है।
लाइब्रेरीज़ का परीक्षण करते समय, आपको एक सरल प्रोग्राम खोजने या लिखने की आवश्यकता होती है जो
stdin या किसी फ़ाइल से डेटा पढ़ता है और उसे परीक्षण की जा रही लाइब्रेरी तक पहुँचाता है। ऐसे
मामले में, इस एक्ज़ीक्यूटेबल को इंस्ट्रूमेंटेड लाइब्रेरी के स्टैटिक संस्करण के साथ लिंक करना आवश्यक है, या यह सुनिश्चित करना आवश्यक है कि सही .so फ़ाइल रनटाइम पर लोड हो (आमतौर पर `LD_LIBRARY_PATH` सेट करके)। सबसे आसान विकल्प स्टैटिक बिल्ड है, जो आमतौर पर इस प्रकार संभव है:```shell
$ CC=/path/to/afl/afl-gcc ./configure --disable-shared
AFL_HARDEN=1 सेट करके 'make' कॉल करने पर CC रैपर
स्वचालित रूप से कोड हार्डनिंग विकल्प सक्षम करेगा जिससे साधारण मेमोरी बग्स का पता लगाना
आसान हो जाता है। Libdislocator, AFL के साथ शामिल एक सहायक लाइब्रेरी (देखें
libdislocator/README.dislocator) हीप करप्शन समस्याओं को उजागर करने में भी मदद कर सकती है।
पी.एस. ASAN उपयोगकर्ताओं को सलाह दी जाती है कि वे महत्वपूर्ण चेतावनियों के लिए notes_for_asan.txt फ़ाइल देखें।
जब सोर्स कोड उपलब्ध नहीं होता, तो फ़ज़र ब्लैक-बॉक्स बाइनरीज़ के तेज़, ऑन-द-फ्लाई इंस्ट्रुमेंटेशन के लिए प्रायोगिक समर्थन प्रदान करता है। यह QEMU के एक संस्करण के साथ पूरा किया जाता है जो कम-ज्ञात "यूज़र स्पेस एमुलेशन" मोड में चलता है।
QEMU, AFL से अलग एक प्रोजेक्ट है, लेकिन आप आसानी से इस सुविधा को निम्न प्रकार से बना सकते हैं:```shell $ cd qemu_mode $ ./build_qemu_support.sh
For additional instructions and caveats, see qemu_mode/README.qemu.
The mode is approximately 2-5x slower than compile-time instrumentation, is
less conducive to parallelization, and may have some other quirks.
## 5) प्रारंभिक परीक्षण मामले चुनना
सही ढंग से काम करने के लिए, फ़ज़र को एक या अधिक प्रारंभिक फ़ाइल की आवश्यकता होती है जो
लक्षित एप्लिकेशन द्वारा सामान्य रूप से अपेक्षित इनपुट डेटा का एक अच्छा उदाहरण शामिल करती है।
दो बुनियादी नियम हैं:
- फ़ाइलों को छोटा रखें। 1 kB से कम आदर्श है, हालांकि यह सख्त रूप से आवश्यक नहीं है।
आकार क्यों मायने रखता है, इस चर्चा के लिए, [perf_tips.txt](https://github.com/google/afl/blob/HEAD/docs/perf_tips.txt) देखें।
- एकाधिक परीक्षण मामलों का उपयोग केवल तभी करें जब वे कार्यात्मक रूप से
एक-दूसरे से भिन्न हों। पचास अलग-अलग छुट्टियों की तस्वीरों का उपयोग किसी इमेज लाइब्रेरी को
फ़ज़ करने के लिए कोई मतलब नहीं है।
आप इस टूल के साथ आने वाली testcases/ उपनिर्देशिका में प्रारंभिक फ़ाइलों के कई अच्छे उदाहरण
पा सकते हैं।
PS. यदि स्क्रीनिंग के लिए डेटा का एक बड़ा कॉर्पस उपलब्ध है, तो आप
afl-cmin उपयोगिता का उपयोग करके कार्यात्मक रूप से भिन्न फ़ाइलों का एक उपसमुच्चय पहचानना चाह सकते हैं जो
लक्षित बाइनरी में विभिन्न कोड पथों का अभ्यास करते हैं।
## 6) बाइनरी फ़ज़िंग
फ़ज़िंग प्रक्रिया स्वयं afl-fuzz उपयोगिता द्वारा संचालित होती है। यह प्रोग्राम
प्रारंभिक परीक्षण मामलों के साथ एक केवल-पठनीय निर्देशिका, निष्कर्षों को संग्रहीत करने के लिए एक अलग स्थान,
और परीक्षण के लिए बाइनरी का एक पथ की आवश्यकता होती है।
उन लक्षित बाइनरी के लिए जो सीधे stdin से इनपुट स्वीकार करते हैं, सामान्य सिंटैक्स है:```shell
$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program [...params...]
फ़ाइल से इनपुट लेने वाले प्रोग्रामों के लिए, '@@' का उपयोग उस स्थान को चिह्नित करने के लिए करें जहाँ लक्ष्य की कमांड लाइन में इनपुट फ़ाइल का नाम रखा जाना चाहिए। फ़ज़र आपके लिए इसे प्रतिस्थापित कर देगा:```shell $ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@
आप म्यूटेटेड डेटा को किसी विशेष फ़ाइल में लिखवाने के लिए -f विकल्प का भी उपयोग कर सकते हैं,
यह तब उपयोगी है जब प्रोग्राम किसी विशेष फ़ाइल एक्सटेंशन या ऐसी ही चीज़ की अपेक्षा करता है।
बिना इंस्ट्रूमेंटेशन वाले बाइनरी को QEMU मोड में (कमांड लाइन में -Q जोड़ें)
या पारंपरिक, ब्लाइंड-फज़र मोड में (-n निर्दिष्ट करें) फ़ज़ किया जा सकता है।
निष्पादित प्रक्रिया के लिए डिफ़ॉल्ट टाइमआउट और मेमोरी सीमा को ओवरराइड करने के लिए आप -t और -m का उपयोग कर सकते हैं;
ऐसे टारगेट्स के दुर्लभ उदाहरण जिन्हें इन सेटिंग्स को बदलने की आवश्यकता हो सकती है,
उनमें कंपाइलर और वीडियो डिकोडर शामिल हैं।
फ़ज़िंग प्रदर्शन को अनुकूलित करने के टिप्स [perf_tips.txt](https://github.com/google/afl/blob/HEAD/docs/perf_tips.txt) में चर्चित हैं।
ध्यान दें कि afl-fuzz नियतात्मक (deterministic) फ़ज़िंग चरणों की एक श्रृंखला करके शुरू करता है,
जिसमें कई दिन लग सकते हैं, लेकिन वे अच्छे टेस्ट केस उत्पन्न करते हैं। यदि आप
तुरंत क्विक एंड डर्टी परिणाम चाहते हैं - zzuf और अन्य पारंपरिक फ़ज़र्स की तरह -
तो कमांड लाइन में -d विकल्प जोड़ें।
## 7) आउटपुट की व्याख्या करना
प्रदर्शित आँकड़ों की व्याख्या कैसे करें और प्रक्रिया के स्वास्थ्य की निगरानी कैसे करें,
इसकी जानकारी के लिए [status_screen.txt](https://github.com/google/afl/blob/HEAD/docs/status_screen.txt) फ़ाइल देखें।
यदि कोई UI तत्व लाल रंग में हाइलाइट किया गया है, तो इस फ़ाइल को विशेष रूप से
अवश्य देखें।
फ़ज़िंग प्रक्रिया तब तक जारी रहेगी जब तक आप Ctrl-C नहीं दबाते। न्यूनतम रूप से, आप
फ़ज़र को एक कतार चक्र पूरा करने देना चाहते हैं, जिसमें कुछ घंटों से लेकर
लगभग एक सप्ताह तक का समय लग सकता है।
आउटपुट निर्देशिका के भीतर तीन उपनिर्देशिकाएँ बनाई जाती हैं और वास्तविक समय में
अद्यतन की जाती हैं:
- queue/ - टेस्ट केस हर विशिष्ट निष्पादन पथ के लिए, साथ ही सभी
उपयोगकर्ता द्वारा दी गई प्रारंभिक फ़ाइलें। यह संश्लेषित कॉर्पस है
जिसका उल्लेख अनुभाग 2 में किया गया है।
इस कॉर्पस को किसी अन्य उद्देश्य के लिए उपयोग करने से पहले, आप इसे
afl-cmin टूल का उपयोग करके छोटे आकार में बदल सकते हैं। यह टूल
फ़ाइलों का एक छोटा सबसेट खोज लेगा जो समान एज कवरेज देता है।
- crashes/ - अद्वितीय टेस्ट केस जो परीक्षण किए गए प्रोग्राम को एक
घातक संकेत (जैसे SIGSEGV, SIGILL, SIGABRT) प्राप्त करने का कारण बनते हैं। प्रविष्टियाँ
प्राप्त संकेत के अनुसार समूहीकृत की जाती हैं।
- hangs/ - अद्वितीय टेस्ट केस जो परीक्षण किए गए प्रोग्राम को टाइम आउट करने का कारण बनते हैं।
किसी चीज़ को हैंग के रूप में वर्गीकृत करने से पहले डिफ़ॉल्ट समय सीमा
1 सेकंड और -t पैरामीटर के मान में से बड़ा होता है।
मान को AFL_HANG_TMOUT सेट करके ठीक किया जा सकता है, लेकिन
यह शायद ही कभी आवश्यक होता है।
क्रैश और हैंग को "अद्वितीय" माना जाता है यदि संबद्ध निष्पादन पथों में
पहले दर्ज किए गए दोषों में न देखे गए कोई राज्य संक्रमण शामिल हों। यदि एक
ही बग तक कई तरीकों से पहुँचा जा सकता है, तो प्रक्रिया के आरंभ में कुछ गिनती वृद्धि
होगी, लेकिन यह जल्दी ही कम हो जानी चाहिए।
क्रैश और हैंग के फ़ाइल नाम मूल (parent), गैर-दोषपूर्ण कतार प्रविष्टियों के साथ सहसंबद्ध होते हैं।
इससे डिबगिंग में मदद मिलनी चाहिए।
जब आप afl-fuzz द्वारा पाए गए क्रैश को पुनः उत्पन्न नहीं कर पाते हैं, तो सबसे संभावित कारण यह है
कि आप टूल द्वारा उपयोग की गई समान मेमोरी सीमा निर्धारित नहीं कर रहे हैं। प्रयास करें:```shell
$ LIMIT_MB=50
$ ( ulimit -Sv $[LIMIT_MB << 10]; /path/to/tested_binary ... )
LIMIT_MB को afl-fuzz को दिए गए -m पैरामीटर से मेल खाने के लिए बदलें। OpenBSD पर, -Sv को -Sd में भी बदलें।
किसी भी मौजूदा आउटपुट निर्देशिका का उपयोग निरस्त कार्यों को फिर से शुरू करने के लिए भी किया जा सकता है; आज़माएँ:```shell $ ./afl-fuzz -i- -o existing_output_dir [...etc...]
यदि आपके पास gnuplot स्थापित है, तो आप किसी भी
सक्रिय फ़ज़िंग कार्य के लिए afl-plot का उपयोग करके कुछ सुंदर ग्राफ़ भी उत्पन्न कर सकते हैं। यह कैसा दिखता है, इसका एक उदाहरण
[http://lcamtuf.coredump.cx/afl/plot/](http://lcamtuf.coredump.cx/afl/plot/) देखें।
## 8) समानांतर फ़ज़िंग
afl-fuzz का प्रत्येक उदाहरण लगभग एक कोर लेता है। इसका मतलब है कि
मल्टी-कोर सिस्टम पर, हार्डवेयर का पूर्ण उपयोग करने के लिए समानांतरीकरण आवश्यक है।
एक सामान्य लक्ष्य को कई कोर या कई नेटवर्क-युक्त मशीनों पर फ़ज़ करने के सुझावों के लिए,
कृपया [parallel_fuzzing.txt](https://github.com/google/afl/blob/HEAD/docs/parallel_fuzzing.txt) देखें।
समानांतर फ़ज़िंग मोड AFL को अन्य फ़ज़र्स,
सिम्बोलिक या कॉन्कोलिक एक्ज़ीक्यूशन इंजन, इत्यादि से जोड़ने का एक सरल तरीका भी प्रदान करता है; फिर से,
सुझावों के लिए [parallel_fuzzing.txt](https://github.com/google/afl/blob/HEAD/docs/parallel_fuzzing.txt) का अंतिम अनुभाग देखें।
## 9) फ़ज़र डिक्शनरी
डिफ़ॉल्ट रूप से, afl-fuzz म्यूटेशन इंजन कॉम्पैक्ट डेटा प्रारूपों के लिए अनुकूलित है -
जैसे, छवियाँ, मल्टीमीडिया, संपीड़ित डेटा, रेगुलर एक्सप्रेशन सिंटैक्स, या शेल
स्क्रिप्ट। यह विशेष रूप से वर्बोज़ और
अनावश्यक शब्दावली वाली भाषाओं के लिए कुछ हद तक कम उपयुक्त है - विशेष रूप से HTML, SQL, या JavaScript सहित।
सिंटैक्स-जागरूक उपकरण बनाने की झंझट से बचने के लिए, afl-fuzz एक तरीका प्रदान करता है
फ़ज़िंग प्रक्रिया को भाषा कीवर्ड,
मैजिक हेडर, या लक्षित डेटा प्रकार से जुड़े अन्य विशेष टोकन के वैकल्पिक डिक्शनरी के साथ सीड करने का
-- और उसका उपयोग अंतर्निहित व्याकरण को चलते-चलते पुनर्निर्माण करने के लिए करें।
[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)
इस सुविधा का उपयोग करने के लिए, आपको पहले दो प्रारूपों में से किसी एक में एक डिक्शनरी बनानी होगी
जिनकी चर्चा dictionaries/README.dictionaries में की गई है; और फिर कमांड लाइन में -x विकल्प के माध्यम से फ़ज़र को
उसकी ओर इंगित करना होगा।
(उस उपनिर्देशिका में कई सामान्य डिक्शनरी भी पहले से प्रदान की गई हैं।)
अंतर्निहित सिंटैक्स के अधिक संरचित विवरण प्रदान करने का कोई तरीका नहीं है,
लेकिन फ़ज़र संभवतः केवल इंस्ट्रुमेंटेशन फीडबैक के आधार पर इसका कुछ हिस्सा समझ लेगा।
यह वास्तव में व्यवहार में काम करता है, जैसे:
[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. जब कोई स्पष्ट डिक्शनरी नहीं दी गई हो, तब भी afl-fuzz निकालने का प्रयास करेगा
इनपुट कॉर्पस में मौजूद सिंटैक्स टोकन को डिटर्मिनिस्टिक बाइट फ्लिप्स के दौरान
इंस्ट्रुमेंटेशन को बहुत बारीकी से देखकर। यह कुछ प्रकार के
पार्सर और ग्रामर के लिए काम करता है, लेकिन यह -x मोड जितना अच्छा नहीं है।
यदि डिक्शनरी प्राप्त करना वास्तव में कठिन है, तो दूसरा विकल्प यह है कि AFL को कुछ समय चलने दें,
और फिर AFL के साथ सहायक उपयोगिता के रूप में आने वाली टोकन कैप्चर लाइब्रेरी का उपयोग करें।
इसके लिए, libtokencap/README.tokencap देखें।
## 10) क्रैश ट्राइएज
कवरेज-आधारित क्रैश समूहीकरण आमतौर पर एक छोटा डेटा सेट उत्पन्न करता है जिसे
मैन्युअल रूप से या बहुत सरल GDB या Valgrind स्क्रिप्ट के साथ शीघ्रता से ट्राइएज किया जा सकता है।
प्रत्येक क्रैश कतार में अपने पैरेंट नॉन-क्रैशिंग टेस्ट केस से भी जुड़ा होता है,
जिससे दोषों का निदान करना आसान हो जाता है।
फिर भी, यह स्वीकार करना महत्वपूर्ण है कि कुछ फ़ज़िंग क्रैश का शोषणीयता के लिए
शीघ्र मूल्यांकन करना बहुत अधिक डीबगिंग और
कोड विश्लेषण कार्य के बिना कठिन हो सकता है। इस कार्य में सहायता के लिए, afl-fuzz एक बहुत ही अनोखे
"क्रैश अन्वेषण" मोड का समर्थन करता है, जो -C फ्लैग से सक्षम होता है।
इस मोड में, फ़ज़र एक या अधिक क्रैशिंग टेस्ट केस को इनपुट के रूप में लेता है,
और अपनी फीडबैक-संचालित फ़ज़िंग रणनीतियों का उपयोग करके उन सभी कोड पथों की बहुत तेज़ी से गणना करता है
जिन तक प्रोग्राम में पहुंचा जा सकता है, जबकि उसे
क्रैशिंग अवस्था में रखता है।
जो म्यूटेशन क्रैश का परिणाम नहीं देते उन्हें अस्वीकार कर दिया जाता है; साथ ही वे परिवर्तन भी
जो एक्ज़ीक्यूशन पथ को प्रभावित नहीं करते।
आउटपुट फ़ाइलों का एक छोटा कॉर्पस होता है जिसकी बहुत तेज़ी से जांच की जा सकती है
कि हमलावर का फॉल्टिंग एड्रेस पर कितना नियंत्रण है, या क्या
प्रारंभिक आउट-ऑफ-बाउंड्स रीड से आगे निकलना संभव है - और यह देखना कि नीचे
क्या है।
ओह, एक और बात: टेस्ट केस न्यूनीकरण के लिए, afl-tmin आज़माएं। यह उपकरण
बहुत सरल तरीके से संचालित किया जा सकता है:```shell
$ ./afl-tmin -i test_case -o minimized_result -- /path/to/program [...]
यह उपकरण क्रैश होने वाले और बिना क्रैश वाले, दोनों प्रकार के टेस्ट केसेस के साथ काम करता है। क्रैश मोड में, यह इंस्ट्रूमेंटेड और नॉन-इंस्ट्रूमेंटेड बाइनरी को स्वीकार करने में प्रसन्न रहता है। नॉन-क्रैशिंग मोड में, मिनिमाइज़र निष्पादन पथ को बदले बिना फ़ाइल को सरल बनाने के लिए मानक AFL इंस्ट्रूमेंटेशन पर निर्भर करता है।
मिनिमाइज़र afl-fuzz के अनुरूप तरीके से -m, -t, -f और @@ सिंटैक्स स्वीकार करता है।
AFL में एक और हालिया जोड़ afl-analyze उपकरण है। यह एक इनपुट फ़ाइल लेता है, क्रमिक रूप से बाइट्स को फ्लिप करने का प्रयास करता है, और परीक्षण किए गए प्रोग्राम के व्यवहार का अवलोकन करता है। फिर यह इनपुट को रंग-कोडित करता है, जिसके आधार पर यह दिखाता है कि कौन से अनुभाग महत्वपूर्ण प्रतीत होते हैं और कौन से नहीं; हालाँकि यह अचूक नहीं है, यह अक्सर जटिल फ़ाइल स्वरूपों में त्वरित अंतर्दृष्टि प्रदान कर सकता है। इसके संचालन के बारे में अधिक जानकारी technical_details.txt के अंत के पास पाई जा सकती है।
फ़ज़िंग गैर-क्रैशिंग डिज़ाइन और कार्यान्वयन त्रुटियों की खोज के लिए भी एक अद्भुत और कम उपयोग की जाने वाली तकनीक है। लक्ष्य प्रोग्रामों को संशोधित करके काफी कुछ दिलचस्प बग पाए गए हैं, जैसे जब वे abort() को कॉल करते हैं, जैसे कि:
दो बिग्नम लाइब्रेरीज़, जब एक ही फ़ज़र-जनरेटेड इनपुट दिया जाता है, तो अलग-अलग आउटपुट उत्पन्न करती हैं,
एक इमेज लाइब्रेरी, जब एक ही इनपुट इमेज को लगातार कई बार डिकोड करने के लिए कहा जाता है, तो अलग-अलग आउटपुट उत्पन्न करती है,
एक सीरियलाइज़ेशन / डिसीरियलाइज़ेशन लाइब्रेरी, जब फ़ज़र-आपूर्ति किए गए डेटा को बार-बार सीरियलाइज़ और डिसीरियलाइज़ करती है, तो स्थिर आउटपुट उत्पन्न करने में विफल रहती है,
एक कम्प्रेशन लाइब्रेरी, जब किसी विशेष ब्लॉब को कंप्रेस और फिर डीकंप्रेस करने के लिए कहा जाता है, तो इनपुट फ़ाइल के साथ असंगत आउटपुट उत्पन्न करती है।
इन या समान सैनिटी जांचों को लागू करने में आमतौर पर बहुत कम समय लगता है; यदि आप किसी विशेष पैकेज के अनुरक्षक हैं, तो आप इस कोड को #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION (एक फ़्लैग जो libfuzzer के साथ भी साझा किया जाता है) या #ifdef __AFL_COMPILER (यह केवल AFL के लिए है) के साथ सशर्त बना सकते हैं।
कृपया ध्यान रखें कि, कई अन्य कम्प्यूटेशनल-गहन कार्यों के समान, फ़ज़िंग आपके हार्डवेयर और ओएस पर दबाव डाल सकती है। विशेष रूप से:
आपका CPU गर्म चलेगा और उसे पर्याप्त कूलिंग की आवश्यकता होगी। अधिकांश मामलों में, यदि कूलिंग अपर्याप्त है या ठीक से काम करना बंद कर देती है, तो CPU की गति स्वचालित रूप से थ्रॉटल हो जाएगी। फिर भी, विशेष रूप से कम उपयुक्त हार्डवेयर (लैपटॉप, स्मार्टफोन, आदि) पर फ़ज़िंग करते समय, किसी चीज़ के विस्फोट होने की संभावना पूरी तरह से असंभव नहीं है।
लक्षित प्रोग्राम अंततः अजीब तरीके से गीगाबाइट्स मेमोरी हथिया सकते हैं या जंक फ़ाइलों के साथ डिस्क स्थान भर सकते हैं। AFL बुनियादी मेमोरी सीमाएँ लागू करने का प्रयास करता है, लेकिन हर संभव दुर्घटना को नहीं रोक सकता। मूल बात यह है कि आपको उन प्रणालियों पर फ़ज़िंग नहीं करनी चाहिए जहाँ डेटा हानि की संभावना स्वीकार्य जोखिम नहीं है।
फ़ज़िंग में फाइल सिस्टम पर अरबों रीड और राइट शामिल हैं। आधुनिक प्रणालियों पर, यह आमतौर पर भारी रूप से कैश्ड होगा, जिसके परिणामस्वरूप काफी मामूली "भौतिक" I/O होगा - लेकिन कई कारक हैं जो इस समीकरण को बदल सकते हैं। संभावित परेशानी की निगरानी करना आपकी ज़िम्मेदारी है; बहुत भारी I/O के साथ, कई HDD और SSD का जीवनकाल कम हो सकता है।
Linux पर डिस्क I/O की निगरानी करने का एक अच्छा तरीका 'iostat' कमांड है:```shell $ iostat -d 3 -x -k [...optional disk ID...]
## 13) ज्ञात सीमाएँ और सुधार के क्षेत्र
AFL के लिए कुछ सबसे महत्वपूर्ण चेतावनियाँ निम्नलिखित हैं:
- AFL दोषों का पता पहले स्पॉन किए गए प्रोसेस के सिग्नल के कारण मरने की जाँच करके लगाता है
(SIGSEGV, SIGABRT, आदि)। जो प्रोग्राम इन सिग्नलों के लिए कस्टम हैंडलर स्थापित करते हैं,
उन्हें प्रासंगिक कोड को कमेंट आउट करने की आवश्यकता हो सकती है। इसी तरह,
फ़ज़ किए गए टारगेट द्वारा स्पॉन किए गए चाइल्ड प्रोसेस में होने वाले दोषों का पता नहीं चल सकता
जब तक कि आप उसे पकड़ने के लिए मैन्युअल रूप से कुछ कोड न जोड़ें।
- किसी भी अन्य ब्रूट-फोर्स टूल की तरह, फ़ज़र सीमित कवरेज प्रदान करता है यदि
एन्क्रिप्शन, चेकसम, क्रिप्टोग्राफ़िक हस्ताक्षर, या संपीड़न का उपयोग
परीक्षण किए जाने वाले वास्तविक डेटा प्रारूप को पूरी तरह से लपेटने के लिए किया जाता है।
इससे निपटने के लिए, आप प्रासंगिक जाँचों को कमेंट आउट कर सकते हैं (प्रेरणा के लिए
experimental/libpng_no_checksum/ देखें); यदि यह संभव न हो, तो आप
एक पोस्टप्रोसेसर भी लिख सकते हैं, जैसा कि
experimental/post_library/ में समझाया गया है।
- ASAN और 64-बिट बाइनरीज़ के साथ कुछ दुर्भाग्यपूर्ण समझौते हैं। यह
afl-fuzz के किसी विशिष्ट दोष के कारण नहीं है; [notes_for_asan.txt](https://github.com/google/afl/blob/HEAD/docs/notes_for_asan.txt) देखें
सुझावों के लिए।
- नेटवर्क सेवाओं, बैकग्राउंड डेमन्स, या इंटरैक्टिव ऐप्स को फ़ज़ करने के लिए कोई सीधा समर्थन नहीं है,
जिन्हें काम करने के लिए UI इंटरैक्शन की आवश्यकता होती है। उन्हें अधिक पारंपरिक तरीके से व्यवहार करने के लिए
आपको सरल कोड परिवर्तन करने पड़ सकते हैं।
Preeny भी एक अपेक्षाकृत सरल विकल्प प्रदान कर सकता है - देखें:
https://github.com/zardus/preeny
नेटवर्क-आधारित सेवाओं को संशोधित करने के लिए कुछ उपयोगी सुझाव भी यहाँ पाए जा सकते हैं:
https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop
- AFL मानव-पठनीय कवरेज डेटा आउटपुट नहीं करता है। यदि आप निगरानी करना चाहते हैं
कवरेज की, तो Michael Rash का afl-cov उपयोग करें: https://github.com/mrash/afl-cov
- कभी-कभी, संवेदनशील मशीनें अपने रचनाकारों के विरुद्ध उठ खड़ी होती हैं। यदि ऐसा
आपके साथ होता है, तो कृपया http://lcamtuf.coredump.cx/prep/ देखें।
इसके अलावा, प्लेटफ़ॉर्म-विशिष्ट सुझावों के लिए INSTALL देखें।
## 14) विशेष धन्यवाद
afl-fuzz में किए गए कई सुधार निम्नलिखित से प्राप्त प्रतिक्रिया, बग रिपोर्ट,
या पैच के बिना संभव नहीं होते:```
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
धन्यवाद!
प्रश्न? चिंताएँ? बग रिपोर्ट? कृपया GitHub का उपयोग करें।
परियोजना के लिए एक मेलिंग सूची भी है; शामिल होने के लिए, एक मेल भेजें [email protected] पर। या, यदि आप पहले अभिलेखागार ब्राउज़ करना पसंद करते हैं, तो देखें: https://groups.google.com/group/afl-users।