
DOM fuzzer
इवान फ्रैट्रिक द्वारा लिखित और अनुरक्षित, [email protected]
कॉपीराइट 2017 Google Inc. सर्वाधिकार सुरक्षित।
Apache लाइसेंस, संस्करण 2.0 ("लाइसेंस") के अंतर्गत लाइसेंस प्राप्त; आप इस फ़ाइल का उपयोग केवल लाइसेंस के अनुपालन में कर सकते हैं। आप लाइसेंस की एक प्रति यहाँ प्राप्त कर सकते हैं:
http://www.apache.org/licenses/LICENSE-2.0
जब तक लागू कानून द्वारा आवश्यक न हो या लिखित रूप में सहमति न दी गई हो, लाइसेंस के अंतर्गत वितरित सॉफ़्टवेयर बिना किसी प्रकार की वारंटी या शर्तों के, स्पष्ट या निहित, "जैसा है" ("AS IS") आधार पर वितरित किया जाता है। लाइसेंस के अंतर्गत लागू होने वाली विशिष्ट अनुमतियों और सीमाओं के लिए लाइसेंस देखें।
उपयोग संबंधी जानकारी देखने के लिए निम्नलिखित कमांड चलाएँ:
python3 generator.py --help
एकल .html नमूना उत्पन्न करने के लिए चलाएँ:
python generator.py --file <output file>
अपने द्वारा लिखे गए टेम्पलेट का उपयोग करके एकल .html नमूना उत्पन्न करने के लिए चलाएँ:
python generator.py --file <output file> --template <your custom template file>
एक ही कॉल से कई नमूने उत्पन्न करने के लिए चलाएँ:
python generator.py --output_dir <output directory> --no_of_files <number of output files>
उत्पन्न नमूने निर्दिष्ट निर्देशिका में रखे जाएँगे और उनका नाम fuzz-<number>.html होगा, जैसे fuzz-00001.html, fuzz-00002.html आदि। कई नमूने उत्पन्न करना अधिक तेज़ है क्योंकि इनपुट व्याकरण फ़ाइलों को केवल एक बार लोड और पार्स करने की आवश्यकता होती है।
generator.py मुख्य स्क्रिप्ट शामिल करता है। यह grammar.py को एक लाइब्रेरी के रूप में उपयोग करता है और DOM फ़ज़िंग के लिए अतिरिक्त सहायक कोड शामिल करता है।
grammar.py में जनरेशन इंजन शामिल है जो अधिकतर एप्लिकेशन-एग्नॉस्टिक है और इस प्रकार अन्य (यानी गैर-DOM) जनरेशन-आधारित फ़ज़र में उपयोग किया जा सकता है। चूँकि इसे एक लाइब्रेरी के रूप में उपयोग किया जा सकता है, इसका उपयोग नीचे एक अलग अनुभाग में वर्णित है।
.txt फ़ाइलों में व्याकरण परिभाषाएँ होती हैं। 3 मुख्य फ़ाइलें हैं, html.txt, css.txt और js.txt जिनमें क्रमशः HTML, CSS और JavaScript व्याकरण होते हैं। ये रूट व्याकरण फ़ाइलें अन्य फ़ाइलों की सामग्री शामिल कर सकती हैं।
कस्टम व्याकरण के साथ जनरेशन इंजन का उपयोग करने के लिए, आप निम्नलिखित python कोड का उपयोग कर सकते हैं:
from grammar import Grammar
my_grammar = Grammar()
my_grammar.parse_from_file('input_file.txt')
result_string = my_grammar.generate_symbol('symbol_name')
निम्नलिखित अनुभाग व्याकरण फ़ाइलों की सिंटैक्स का वर्णन करते हैं।
Domato एक ऐसे इंजन पर आधारित है जो, नीचे निर्दिष्ट सरल प्रारूप में एक संदर्भ-मुक्त व्याकरण दिए जाने पर, उस व्याकरण से नमूने उत्पन्न करता है।
एक व्याकरण निम्नलिखित मूल प्रारूप में नियमों के एक समूह के रूप में वर्णित है:
<symbol> = a mix of constants and <other_symbol>s
प्रत्येक व्याकरण नियम में एक बायाँ पक्ष और दायाँ पक्ष होता है जो बराबर (equal) वर्ण द्वारा अलग किए जाते हैं। बायाँ पक्ष एक प्रतीक शामिल करता है, जबकि दायाँ पक्ष इस बात का विवरण शामिल करता है कि उस प्रतीक का विस्तार कैसे किया जा सकता है। किसी प्रतीक का विस्तार करते समय, दाईं ओर के सभी प्रतीकों का पुनरावर्ती रूप से विस्तार किया जाता है जबकि जो कुछ भी प्रतीक नहीं है उसे बस आउटपुट में कॉपी कर दिया जाता है। ध्यान दें कि एक एकल नियम इनपुट फ़ाइल की कई पंक्तियों में विस्तारित नहीं हो सकता।
CSS व्याकरण के एक भाग के निम्नलिखित सरलीकृत उदाहरण पर विचार करें:
<cssrule> = <selector> { <declaration> }
<selector> = a
<selector> = b
<declaration> = width:100%
यदि हम व्याकरण इंजन को उस व्याकरण को पार्स करने और 'cssrule' उत्पन्न करने का निर्देश देते हैं, तो हमारे पास निम्न में से कोई एक परिणाम हो सकता है:
a { width:100% }
या
b { width:100% }
ध्यान दें कि 'selector' प्रतीक के लिए दो नियम हैं। ऐसे मामलों में, जब जनरेटर से 'selector' उत्पन्न करने के लिए कहा जाता है, तो यह उपयोग के लिए नियम को यादृच्छिक रूप से चुनेगा। 'p' गुण का उपयोग करके नियम की संभावना निर्दिष्ट करना भी संभव है, उदाहरण के लिए:
<selector p=0.9> = a
<selector p=0.1> = b
इस मामले में, स्ट्रिंग 'a' 'b' की तुलना में अधिक बार आउटपुट होगी।
संभावना के अतिरिक्त प्रतीकों पर अन्य गुण भी लागू किए जा सकते हैं। वे एक अलग अनुभाग में सूचीबद्ध हैं।
html नमूने उत्पन्न करने के लिए एक और उदाहरण पर विचार करें:
<html> = <lt>html<gt><head><body><lt>/html<gt>
<head> = <lt>head<gt>...<lt>/head<gt>
<body> = <lt>body<gt>...<lt>/body<gt>
ध्यान दें कि चूँकि '<' और '>' का व्याकरण सिंटैक्स में विशेष अर्थ है, इसलिए यहाँ हम इसके बजाय <lt> और <gt> का उपयोग कर रहे हैं। ये प्रतीक बिल्ट-इन हैं और उपयोगकर्ता द्वारा परिभाषित करने की आवश्यकता नहीं है। सभी बिल्ट-इन प्रतीकों की सूची एक अलग अनुभाग में दी गई है।
प्रोग्रामिंग भाषा कोड उत्पन्न करने के लिए, समान सिंटैक्स का उपयोग किया जा सकता है, लेकिन कुछ अंतर हैं। प्रोग्रामिंग भाषा व्याकरण की प्रत्येक पंक्ति आउटपुट की पंक्ति के अनुरूप होगी। इस कारण से, व्याकरण सिंटैक्स अधिक मुक्त-रूप (free-form) होगा ताकि विभिन्न प्रोग्रामिंग भाषाओं में निर्माणों (constructs) को व्यक्त किया जा सके। दूसरे, जब एक पंक्ति उत्पन्न होती है, तो पंक्ति को आउटपुट करने के अतिरिक्त, एक या अधिक चर बनाए जा सकते हैं और अन्य पंक्तियों को उत्पन्न करते समय उन चरों का पुनः उपयोग किया जा सकता है। फिर से, आइए सरलीकृत उदाहरण पर एक नज़र डालें:
!varformat fuzzvar%05d
!lineguard try { <line> } catch(e) {}
!begin lines
<new element> = document.getElementById("<string min=97 max=122>");
<element>.doSomething();
!end lines
यदि हम इंजन को 5 पंक्तियाँ उत्पन्न करने का निर्देश देते हैं, तो हमारे पास कुछ इस प्रकार का परिणाम हो सकता है:
try { var00001 = document.getElementById("hw"); } catch(e) {}
try { var00001.doSomething(); } catch(e) {}
try { var00002 = document.getElementById("feezcqbndf"); } catch(e) {}
try { var00002.doSomething(); } catch(e) {}
try { var00001.doSomething(); } catch(e) {}
ध्यान दें कि
<element> के बजाय <new element> का उपयोग किया। यह जनरेटर को 'element' प्रतीक उत्पन्न करने के बजाय 'element' प्रकार का एक नया चर बनाने का निर्देश देता है।<string> बिल्ट-इन प्रतीकों में से एक है इसलिए इसे परिभाषित करने की आवश्यकता नहीं है।पंक्ति में पहले '#' वर्ण के बाद सब कुछ एक टिप्पणी माना जाता है, इसलिए उदाहरण के लिए:
#This is a comment
व्याकरण सिंटैक्स में फ़ज़र को यह बताने का एक तरीका है कि कौन से नियम गैर-पुनरावर्ती हैं और अधिकतम पुनरावृत्ति स्तर तक पहुँचने पर भी उपयोग करने के लिए सुरक्षित हो सकते हैं। यह ‘nonrecursive’ गुण के साथ किया जाता है। एक उदाहरण नीचे दिया गया है।
!max_recursion 10
<test root=true> = <foobar>
<foobar> = foo<foobar>
<foobar nonrecursive> = bar
सबसे पहले, एक वैकल्पिक ‘!max_recursion’ कथन अधिकतम पुनरावृत्ति गहराई स्तर (डिफ़ॉल्ट रूप से 50) परिभाषित करता है। ध्यान दें कि ‘foobar’ के लिए दूसरा उत्पादन नियम गैर-पुनरावर्ती के रूप में चिह्नित है। यदि कभी अधिकतम पुनरावृत्ति स्तर तक पहुँच जाता है तो जनरेटर ‘foobar’ प्रतीक के लिए गैर-पुनरावर्ती नियम का उपयोग करने के लिए बाध्य करेगा, इस प्रकार अनंत पुनरावृत्ति को रोकेगा।
Domato में, व्याकरणों को शामिल करना और आयात करना दो अलग-अलग संदर्भ हैं।
शामिल करना सरल है। आप उपयोग कर सकते हैं:
!include other.txt
other.txt से नियमों को वर्तमान में पार्स किए जा रहे व्याकरण में शामिल करने के लिए।
आयात करना थोड़ा अलग तरीके से काम करता है:
!import other.txt
पार्सर को एक नया Grammar() ऑब्जेक्ट बनाने का निर्देश देता है, जिसे विशेष <import> प्रतीक का उपयोग करके वर्तमान व्याकरण से संदर्भित किया जा सकता है, उदाहरण के लिए इस प्रकार:
<cssrule> = <import from=css.txt symbol=rule>
आप नेमस्पेस के संदर्भ में आयात और शामिल करने के बारे में सोच सकते हैं: !include शामिल किए गए व्याकरण को एकल नेमस्पेस में रखेगा, जबकि !import एक नया नेमस्पेस बनाएगा, जिसे बाद में <import> प्रतीक और 'from' गुण के माध्यम से निर्दिष्ट नेमस्पेस का उपयोग करके एक्सेस किया जा सकता है।
कभी-कभी आप अपने व्याकरण में कस्टम Python कोड को कॉल करना चाह सकते हैं। उदाहरण के लिए, मान लीजिए आप इंजन का उपयोग करके एक http प्रतिक्रिया उत्पन्न करना चाहते हैं और चाहते हैं कि बॉडी की लंबाई 'Size' हेडर से मेल खाए। चूँकि यह सामान्य व्याकरण नियमों के साथ संभव नहीं है, आप इसे पूरा करने के लिए कस्टम Python कोड शामिल कर सकते हैं, जैसे:
!begin function savesize
context['size'] = ret_val
!end function
!begin function createbody
n = int(context['size'])
ret_val = 'a' * n
!end function
<foo root> = <header><cr><lf><body>
<header> = Size: <int min=1 max=20 beforeoutput=savesize>
<body> = <call function=createbody>
Python फ़ंक्शन '!begin function <function_name>' और '!end function' कमांड के बीच परिभाषित किए जाते हैं। फ़ंक्शन को दो तरीकों से कॉल किया जा सकता है: 'beforeoutput' गुण का उपयोग करके और <call> प्रतीक का उपयोग करके।
किसी प्रतीक में 'beforeoutput' गुण निर्दिष्ट करके, संबंधित फ़ंक्शन तब कॉल किया जाएगा जब इस प्रतीक का विस्तार किया जाएगा, विस्तार का परिणाम नमूने में आउटपुट होने से ठीक पहले। विस्तार का परिणाम फ़ंक्शन को ret_val चर में पारित किया जाएगा। फ़ंक्शन तब ret_val को संशोधित करने, बाद में उपयोग के लिए संग्रहीत करने या कोई अन्य ऑपरेशन करने के लिए स्वतंत्र है।
विशेष <call> प्रतीक का उपयोग करते समय, फ़ंक्शन (जो 'function' गुण में निर्दिष्ट है) तब कॉल किया जाएगा जब भाषा जनरेशन के दौरान उस प्रतीक का सामना होता है। फ़ंक्शन द्वारा ret_val में संग्रहीत कोई भी मान विस्तार का परिणाम माना जाएगा (ret_val नमूने में शामिल हो जाता है)।
आपके python कोड में निम्नलिखित चरों तक पहुँच है:
context - एक डिक्शनरी जो पूरे नमूना जनरेशन के दौरान पारित की जाती है। आप इसका उपयोग मानों को संग्रहीत करने (जैसे ऊपर के उदाहरण में आकार संग्रहीत करना) और बाद में सक्रिय होने वाले नियमों में उन्हें पुनः प्राप्त करने के लिए कर सकते हैं।attributes - वर्तमान में संसाधित किए जा रहे प्रतीक के अनुरूप एक डिक्शनरी। आप इसका उपयोग अपने फ़ंक्शनों को पैरामीटर पारित करने के लिए कर सकते हैं। उदाहरण के लिए यदि आपने अपने फ़ंक्शन को कॉल करने के लिए <call function=func foo=bar> जैसा कुछ उपयोग किया है तो attributes[‘foo’] ‘bar’ पर सेट होगा।ret_val - वह मान जो फ़ंक्शन कॉल के परिणामस्वरूप आउटपुट होगा। फ़ंक्शन को कॉल करने के लिए <call> प्रतीक का उपयोग करते समय यह एक खाली मान के साथ प्रारंभिकृत होता है, अन्यथा यह प्रतीक द्वारा उत्पन्न मान के साथ प्रारंभिकृत होगा।निम्नलिखित प्रतीकों का एक विशेष अर्थ है और उन्हें उपयोगकर्ताओं द्वारा पुनः परिभाषित नहीं किया जाना चाहिए:
<lt> - ‘<’ वर्ण<gt> - ‘>’ वर्ण<hash> - ‘#’ वर्ण<cr> - CR वर्ण<lf> - LF वर्ण<space> - स्पेस वर्ण<tab> - टैब वर्ण<ex> - ‘!’ वर्ण<char> - ‘code’ गुण का उपयोग करके एक मनमाना ascii वर्ण उत्पन्न करने के लिए उपयोग किया जा सकता है। उदाहरण के लिए <char code=97> ‘a’ के अनुरूप है। निर्दिष्ट न होने पर यादृच्छिक वर्ण उत्पन्न करता है। ‘min’ और ‘max’ गुण का समर्थन करता है।<hex> - एक यादृच्छिक hex अंक उत्पन्न करता है।<int>, <int 8>, <uint8>, , , , , , - यादृच्छिक पूर्णांक उत्पन्न करने के लिए उपयोग किया जा सकता है। ‘min’ और ‘max’ गुण का समर्थन करता है जिसका उपयोग उत्पन्न किए जाने वाले पूर्णांकों की सीमा को सीमित करने के लिए किया जा सकता है। ‘b’ और ‘be’ गुण का समर्थन करता है जो टेक्स्ट आउटपुट के बजाय आउटपुट को लिटिल/बिग एंडियन प्रारूप में बाइनरी बनाता है।निम्नलिखित गुण समर्थित हैं:
doSomething(<int id=1>, <int id=1>)’ में दोनों ints का मान समान होगा। केवल पहला उदाहरण वास्तव में विस्तारित होता है, दूसरा केवल पहले से कॉपी किया जाता है।<call> प्रतीक में उपयोग किया जाता है, अधिक जानकारी के लिए ‘Python कोड शामिल करना’ अनुभाग देखें।Domato के साथ पाए गए कुछ बग:
यह एक आधिकारिक Google उत्पाद नहीं है।
<int16><uint16><int32><uint32><int64><uint64><float>, <double> - एक यादृच्छिक फ्लोटिंग-पॉइंट संख्या उत्पन्न करता है। ‘min’ और ‘max’ गुण का समर्थन करता है (निर्दिष्ट न होने पर 0 और 1)। ‘b’ गुण का समर्थन करता है जो आउटपुट को बाइनरी बनाता है।<string> - एक यादृच्छिक स्ट्रिंग उत्पन्न करता है। ‘min’ और ‘max’ गुणों का समर्थन करता है जो उत्पन्न न्यूनतम और अधिकतम कैरेक्टर-कोड (charcode) को नियंत्रित करते हैं, साथ ही ‘minlength’ और ‘maxlength’ गुण जो स्ट्रिंग की लंबाई को नियंत्रित करते हैं।<htmlsafestring> - <string> के समान, सिवाय इसके कि HTML मेटा-कैरेक्टर एस्केप किए जाएँगे, जिससे स्ट्रिंग को HTML टेक्स्ट या एट्रिब्यूट मानों के भाग के रूप में एम्बेड करना सुरक्षित हो जाता है।<lines> - ‘count’ गुण के माध्यम से दी गई संख्या में कोड की पंक्तियाँ आउटपुट करता है। उदाहरण के लिए प्रोग्रामिंग भाषा कोड उत्पन्न करने वाला अनुभाग देखें।<import> - किसी अन्य व्याकरण से एक प्रतीक आयात करता है, विवरण के लिए बाहरी व्याकरणों को शामिल करने वाला अनुभाग देखें।<call> - function गुण के अनुरूप एक उपयोगकर्ता-परिभाषित फ़ंक्शन को कॉल करता है। अधिक जानकारी के लिए व्याकरण में Python कोड शामिल करने वाला अनुभाग देखें।