class GUIGrammarMiner(GUIGrammarMiner): START_STATE = "<state>" UNEXPLORED_STATE = "<unexplored>" FINAL_STATE = "<end>" GUI_GRAMMAR = ({ START_SYMBOL: [START_STATE], UNEXPLORED_STATE: [""], FINAL_STATE: [""], "<text>": ["<string>"], "<string>": ["<character>", "<string><character>"], "<character>": ["<letter>", "<digit>", "<special>"], "<letter>": crange('a', 'z') + crange('A', 'Z'), "<number>": ["<digits>"], "<digits>": ["<digit>", "<digits><digit>"], "<digit>": crange('0', '9'), "<special>": srange(". !"), "<email>": ["<letters>@<letters>"], "<letters>": ["<letter>", "<letters><letter>"], "<boolean>": ["True", "False"], # Use a fixed password in case we need to repeat it "<password>": ["abcABC.123"], "<hidden>": "<string>", })
class HTMLGrammarMiner(HTMLGrammarMiner): QUERY_GRAMMAR = extend_grammar( CGI_GRAMMAR, { "<start>": ["<action>?<query>"], "<text>": ["<string>"], "<number>": ["<digits>"], "<digits>": ["<digit>", "<digits><digit>"], "<digit>": crange('0', '9'), "<checkbox>": ["<_checkbox>"], "<_checkbox>": ["on", "off"], "<email>": ["<_email>"], "<_email>": [cgi_encode("<string>@<string>", "<>")], # Use a fixed password in case we need to repeat it "<password>": ["<_password>"], "<_password>": ["abcABC.123"], # Stick to printable characters to avoid logging problems "<percent>": ["%<hexdigit-1><hexdigit>"], "<hexdigit-1>": srange("34567"), # Submissions: "<submit>": [""] })
if __name__ == "__main__": integer_fuzzer = GrammarFuzzer(PROBABILISTIC_EXPR_GRAMMAR, start_symbol="<leadinteger>") print([integer_fuzzer.fuzz() for i in range(20)]) if __name__ == "__main__": leaddigit_fuzzer = ProbabilisticGrammarFuzzer(PROBABILISTIC_EXPR_GRAMMAR, start_symbol="<leaddigit>") leaddigit_fuzzer.fuzz() if __name__ == "__main__": trials = 10000 count = {} for c in crange('0', '9'): count[c] = 0 for i in range(trials): count[leaddigit_fuzzer.fuzz()] += 1 print([(digit, count[digit] / trials) for digit in count]) # ## Directed Fuzzing if __name__ == "__main__": print('\n## Directed Fuzzing') def set_prob(grammar, symbol, expansion, prob): """Set the probability of the given expansion of grammar[symbol]"""
if __package__ is None or __package__ == "": from Grammars import crange, is_valid_grammar else: from .Grammars import crange, is_valid_grammar ORDER_GRAMMAR = { "<start>": ["<order>"], "<order>": ["order?item=<item>&name=<name>&email=<email>&city=<city>&zip=<zip>"], "<item>": ["tshirt", "drill", "lockset"], "<name>": ["Jane Doe", "John Smith"], "<email>": ["*****@*****.**"], "<city>": ["Seattle", "New York"], "<zip>": ["<digit>" * 5], "<digit>": crange('0', '9') } assert is_valid_grammar(ORDER_GRAMMAR) BAD_ORDER_GRAMMAR = { "<name>": ["Robert'; drop table students; --"], # https://xkcd.com/327/ "<city>": ["Mötley Crüe"], } ... if __name__ == "__main__": time.sleep(5) http_process.terminate() import os
def add_int_rule(self): self.grammar["<int>"] = ["(-)?<digit>+"] self.grammar["<digit>"] = crange('0', '9')
if __package__ is None or __package__ == "": from Grammars import crange, srange, convert_ebnf_grammar, is_valid_grammar, START_SYMBOL, new_symbol else: from .Grammars import crange, srange, convert_ebnf_grammar, is_valid_grammar, START_SYMBOL, new_symbol PROCESS_NUMBERS_EBNF_GRAMMAR = { "<start>": ["<operator> <integers>"], "<operator>": ["--sum", "--min", "--max"], "<integers>": ["<integer>", "<integers> <integer>"], "<integer>": ["<digit>+"], "<digit>": crange('0', '9') } assert is_valid_grammar(PROCESS_NUMBERS_EBNF_GRAMMAR) PROCESS_NUMBERS_GRAMMAR = convert_ebnf_grammar(PROCESS_NUMBERS_EBNF_GRAMMAR) if __package__ is None or __package__ == "": from GrammarCoverageFuzzer import GrammarCoverageFuzzer else: from .GrammarCoverageFuzzer import GrammarCoverageFuzzer if __name__ == "__main__": f = GrammarCoverageFuzzer(PROCESS_NUMBERS_GRAMMAR, min_nonterminals=10) for i in range(3):
if __package__ is None or __package__ == "": from Grammars import convert_ebnf_grammar, crange else: from .Grammars import convert_ebnf_grammar, crange if __package__ is None or __package__ == "": from ProbabilisticGrammarFuzzer import ProbabilisticGrammarFuzzer else: from .ProbabilisticGrammarFuzzer import ProbabilisticGrammarFuzzer INT_EBNF_GRAMMAR = { "<start>": ["<int>"], "<int>": ["<_int>"], "<_int>": ["(-)?<leaddigit><digit>*", "0"], "<leaddigit>": crange('1', '9'), "<digit>": crange('0', '9') } assert is_valid_grammar(INT_EBNF_GRAMMAR) INT_GRAMMAR = convert_ebnf_grammar(INT_EBNF_GRAMMAR) INT_GRAMMAR if __name__ == "__main__": int_fuzzer = GrammarFuzzer(INT_GRAMMAR) print([int_fuzzer.fuzz() for i in range(10)]) if __package__ is None or __package__ == "": from Grammars import set_opts else:
if __name__ == "__main__": integer_fuzzer = GrammarFuzzer(PROBABILISTIC_EXPR_GRAMMAR, start_symbol="<leadinteger>") print([integer_fuzzer.fuzz() for i in range(20)]) if __name__ == "__main__": leaddigit_fuzzer = ProbabilisticGrammarFuzzer(PROBABILISTIC_EXPR_GRAMMAR, start_symbol="<leaddigit>") leaddigit_fuzzer.fuzz() if __name__ == "__main__": trials = 10000 count = {} for c in crange('0', '9'): count[c] = 0 for i in range(trials): count[leaddigit_fuzzer.fuzz()] += 1 print([(digit, count[digit] / trials) for digit in count]) # ## Directed Fuzzing if __name__ == "__main__": print('\n## Directed Fuzzing') if __package__ is None or __package__ == "": from Grammars import URL_GRAMMAR else:
if __package__ is None or __package__ == "": from Grammars import EXPR_GRAMMAR, is_valid_grammar, is_nonterminal, extend_grammar else: from .Grammars import EXPR_GRAMMAR, is_valid_grammar, is_nonterminal, extend_grammar if __package__ is None or __package__ == "": from Grammars import opts, exp_opt, exp_string, crange else: from .Grammars import opts, exp_opt, exp_string, crange CHARGE_GRAMMAR = { "<start>": ["Charge <amount> to my credit card <credit-card-number>"], "<amount>": ["$<float>"], "<float>": ["<integer>.<digit><digit>"], "<integer>": ["<digit>", "<integer><digit>"], "<digit>": crange('0', '9'), "<credit-card-number>": ["<digits>"], "<digits>": ["<digit-block><digit-block><digit-block><digit-block>"], "<digit-block>": ["<digit><digit><digit><digit>"], } assert is_valid_grammar(CHARGE_GRAMMAR) if __package__ is None or __package__ == "": from GrammarFuzzer import GrammarFuzzer, all_terminals, display_tree else: from .GrammarFuzzer import GrammarFuzzer, all_terminals, display_tree if __name__ == "__main__": g = GrammarFuzzer(CHARGE_GRAMMAR) [g.fuzz() for i in range(5)]
if __package__ is None or __package__ == "": from GrammarFuzzer import GrammarFuzzer # minor dependency else: from .GrammarFuzzer import GrammarFuzzer # minor dependency if __package__ is None or __package__ == "": from Grammars import is_valid_grammar, crange, convert_ebnf_grammar # minor dependency else: from .Grammars import is_valid_grammar, crange, convert_ebnf_grammar # minor dependency SUM2_EBNF_GRAMMAR = { "<start>": ["<sum2>"], "<sum2>": ["sum2(<int>, <int>)"], "<int>": ["<_int>"], "<_int>": ["(-)?<leaddigit><digit>*", "0"], "<leaddigit>": crange('1', '9'), "<digit>": crange('0', '9') } assert is_valid_grammar(SUM2_EBNF_GRAMMAR) if __name__ == "__main__": sum2_grammar = convert_ebnf_grammar(SUM2_EBNF_GRAMMAR) if __name__ == "__main__": sum2_fuzzer = GrammarFuzzer(sum2_grammar) [sum2_fuzzer.fuzz() for i in range(10)] if __name__ == "__main__": with InvariantAnnotator() as annotator: for i in range(10):
VAR_GRAMMAR = { '<start>': ['<statements>'], '<statements>': ['<statement>;<statements>', '<statement>'], '<statement>': ['<assignment>'], '<assignment>': ['<identifier>=<expr>'], '<identifier>': ['<word>'], '<word>': ['<alpha><word>', '<alpha>'], '<alpha>': list(string.ascii_letters), '<expr>': ['<term>+<expr>', '<term>-<expr>', '<term>'], '<term>': ['<factor>*<term>', '<factor>/<term>', '<factor>'], '<factor>': ['+<factor>', '-<factor>', '(<expr>)', '<identifier>', '<number>'], '<number>': ['<integer>.<integer>', '<integer>'], '<integer>': ['<digit><integer>', '<digit>'], '<digit>': crange('0', '9') } if __name__ == "__main__": syntax_diagram(VAR_GRAMMAR) if __name__ == "__main__": mystring = 'va=10;vb=20' def hl_predicate(_d, _n, symbol, _a): return symbol in {'<number>', '<identifier>'} if __package__ is None or __package__ == "": from Parser import PEGParser, highlight_node