REVERTED TO STABLE BUILD

This commit is contained in:
Somdev Sangwan
2019-10-31 18:40:14 +05:30
committed by GitHub
8 changed files with 236 additions and 229 deletions

View File

@@ -8,7 +8,6 @@ def dom(response):
sources = r'''document\.(URL|documentURI|URLUnencoded|baseURI|cookie|referrer)|location\.(href|search|hash|pathname)|window\.name|history\.(pushState|replaceState)(local|session)Storage''' sources = r'''document\.(URL|documentURI|URLUnencoded|baseURI|cookie|referrer)|location\.(href|search|hash|pathname)|window\.name|history\.(pushState|replaceState)(local|session)Storage'''
sinks = r'''eval|evaluate|execCommand|assign|navigate|getResponseHeaderopen|showModalDialog|Function|set(Timeout|Interval|Immediate)|execScript|crypto.generateCRMFRequest|ScriptElement\.(src|text|textContent|innerText)|.*?\.onEventName|document\.(write|writeln)|.*?\.innerHTML|Range\.createContextualFragment|(document|window)\.location''' sinks = r'''eval|evaluate|execCommand|assign|navigate|getResponseHeaderopen|showModalDialog|Function|set(Timeout|Interval|Immediate)|execScript|crypto.generateCRMFRequest|ScriptElement\.(src|text|textContent|innerText)|.*?\.onEventName|document\.(write|writeln)|.*?\.innerHTML|Range\.createContextualFragment|(document|window)\.location'''
scripts = re.findall(r'(?i)(?s)<script[^>]*>(.*?)</script>', response) scripts = re.findall(r'(?i)(?s)<script[^>]*>(.*?)</script>', response)
sinkFound, sourceFound = False, False
for script in scripts: for script in scripts:
script = script.split('\n') script = script.split('\n')
num = 1 num = 1
@@ -32,7 +31,6 @@ def dom(response):
for part in parts: for part in parts:
if source in part: if source in part:
controlledVariables.add(re.search(r'[a-zA-Z$_][a-zA-Z0-9$_]+', part).group().replace('$', '\$')) controlledVariables.add(re.search(r'[a-zA-Z$_][a-zA-Z0-9$_]+', part).group().replace('$', '\$'))
sourceFound = True
line = line.replace(source, yellow + source + end) line = line.replace(source, yellow + source + end)
for controlledVariable in controlledVariables: for controlledVariable in controlledVariables:
allControlledVariables.add(controlledVariable) allControlledVariables.add(controlledVariable)
@@ -46,13 +44,12 @@ def dom(response):
sink = newLine[grp.start():grp.end()].replace(' ', '') sink = newLine[grp.start():grp.end()].replace(' ', '')
if sink: if sink:
line = line.replace(sink, red + sink + end) line = line.replace(sink, red + sink + end)
sinkFound = True
if line != newLine: if line != newLine:
highlighted.append('%-3s %s' % (str(num), line.lstrip(' '))) highlighted.append('%-3s %s' % (str(num), line.lstrip(' ')))
num += 1 num += 1
except MemoryError: except MemoryError:
pass pass
if sinkFound and sourceFound: if (yellow and red) in highlighted:
return highlighted return highlighted
else: else:
return [] return []

View File

@@ -2,32 +2,44 @@ from core.checker import checker
def filterChecker(url, params, headers, GET, delay, occurences, timeout, encoding): def filterChecker(url, params, headers, GET, delay, occurences, timeout, encoding):
positions = occurences.keys() positions = {}
sortedEfficiencies = {} sortedEfficiencies = {}
# adding < > to environments anyway because they can be used in all contexts # adding < > to environments anyway because they can be used in all contexts
environments = set(['<', '>']) environments = set(['<', '>'])
for i in range(len(positions)): for i in range(len(occurences)):
sortedEfficiencies[i] = {} sortedEfficiencies[i] = {}
for i in occurences: for i, occurence in zip(range(len(occurences)), occurences.values()):
occurences[i]['score'] = {} environments.add(occurence['context'][1])
context = occurences[i]['context'] location = occurence['context'][0]
if context == 'comment': try:
attributeName = list(occurence['context'][3].keys())[0]
attributeValue = list(occurence['context'][3].values())[0]
except AttributeError:
attributeName = occurence['context'][3]
positions[str(i)] = occurence['position']
if location == 'comment':
environments.add('-->') environments.add('-->')
elif context == 'script': elif location == 'script':
environments.add(occurences[i]['details']['quote'])
environments.add('</scRipT/>') environments.add('</scRipT/>')
elif context == 'attribute': elif attributeName == 'srcdoc': # srcdoc attribute accepts html data with html entity encoding
if occurences[i]['details']['type'] == 'value': environments.add('&lt;') # so let's add the html entity
if occurences[i]['details']['name'] == 'srcdoc': # srcdoc attribute accepts html data with html entity encoding environments.add('&gt;') # encoded versions of < and >
environments.add('&lt;') # so let's add the html entity
environments.add('&gt;') # encoded versions of < and >
if occurences[i]['details']['quote']:
environments.add(occurences[i]['details']['quote'])
for environment in environments: for environment in environments:
if environment: if environment == '':
efficiencies = [100 for i in range(len(occurences))]
else:
efficiencies = checker( efficiencies = checker(
url, params, headers, GET, delay, environment, positions, timeout, encoding) url, params, headers, GET, delay, environment, positions, timeout, encoding)
efficiencies.extend([0] * (len(occurences) - len(efficiencies))) if len(efficiencies) < len(occurences):
for occurence, efficiency in zip(occurences, efficiencies): for i in range(len(occurences) - len(efficiencies)):
occurences[occurence]['score'][environment] = efficiency efficiencies.append(0)
for i, efficiency in zip(range(len(efficiencies)), efficiencies):
try:
sortedEfficiencies[i][environment] = efficiency
except:
sortedEfficiencies[i] = {}
sortedEfficiencies[i][environment] = efficiency
for efficiency, occurence in zip(sortedEfficiencies.values(), occurences.values()):
occurence['score'] = efficiency
return occurences return occurences

View File

@@ -9,120 +9,116 @@ def generator(occurences, response):
vectors = {11: set(), 10: set(), 9: set(), 8: set(), 7: set(), vectors = {11: set(), 10: set(), 9: set(), 8: set(), 7: set(),
6: set(), 5: set(), 4: set(), 3: set(), 2: set(), 1: set()} 6: set(), 5: set(), 4: set(), 3: set(), 2: set(), 1: set()}
for i in occurences: for i in occurences:
context = occurences[i]['context'] context = occurences[i]['context'][0]
breaker = occurences[i]['context'][1]
special = occurences[i]['context'][2]
try:
attributeName = list(occurences[i]['context'][3].keys())[0]
attributeValue = list(occurences[i]['context'][3].values())[0]
except AttributeError:
attributeName = occurences[i]['context'][3]
if special not in badTags:
special = ''
elif context == 'attribute':
special = '</' + special + '/>'
else:
special = ''
if context == 'html': if context == 'html':
lessBracketEfficiency = occurences[i]['score']['<'] lessBracketEfficiency = occurences[i]['score']['<']
greatBracketEfficiency = occurences[i]['score']['>'] greatBracketEfficiency = occurences[i]['score']['>']
breakerEfficiency = occurences[i]['score'][breaker]
if breaker == '\'' or breaker == '"':
breaker = ''
breakerEfficiency = 100
ends = ['//'] ends = ['//']
badTag = occurences[i]['details']['badTag'] if 'badTag' in occurences[i]['details'] else ''
if greatBracketEfficiency == 100: if greatBracketEfficiency == 100:
ends.append('>') ends.append('>')
if lessBracketEfficiency: if lessBracketEfficiency == breakerEfficiency == 100:
payloads = genGen(fillings, eFillings, lFillings, payloads = genGen(fillings, eFillings, lFillings,
eventHandlers, tags, functions, ends, badTag) eventHandlers, tags, functions, ends, breaker, special)
for payload in payloads: for payload in payloads:
vectors[10].add(payload) vectors[10].add(payload)
elif context == 'attribute': elif context == 'attribute':
found = False found = False
tag = occurences[i]['details']['tag'] breakerEfficiency = occurences[i]['score'][breaker]
Type = occurences[i]['details']['type']
quote = occurences[i]['details']['quote'] or ''
attributeName = occurences[i]['details']['name']
attributeValue = occurences[i]['details']['value']
quoteEfficiency = occurences[i]['score'][quote] if quote in occurences[i]['score'] else 100
greatBracketEfficiency = occurences[i]['score']['>'] greatBracketEfficiency = occurences[i]['score']['>']
ends = ['//'] ends = ['//']
if greatBracketEfficiency == 100: if greatBracketEfficiency == 100:
ends.append('>') ends.append('>')
if greatBracketEfficiency == 100 and quoteEfficiency == 100: if greatBracketEfficiency == 100 and breakerEfficiency == 100:
payloads = genGen(fillings, eFillings, lFillings, payloads = genGen(fillings, eFillings, lFillings,
eventHandlers, tags, functions, ends) eventHandlers, tags, functions, ends, breaker, special)
for payload in payloads: for payload in payloads:
payload = quote + '>' + payload if breaker:
payload = payload.replace(breaker, breaker + '>')
else:
payload = '>' + payload
found = True found = True
vectors[9].add(payload) vectors[6].add(payload)
if quoteEfficiency == 100: if breakerEfficiency == 100:
for filling in fillings: for filling in fillings:
for function in functions: for function in functions:
vector = quote + filling + r('autofocus') + \ vector = breaker + filling + 'auTOfOcuS' + \
filling + r('onfocus') + '=' + quote + function filling + 'OnFoCUs' + '=' + breaker + function
found = True found = True
vectors[8].add(vector) vectors[6].add(vector)
if quoteEfficiency == 90: if breakerEfficiency == 90:
for filling in fillings: for filling in fillings:
for function in functions: for function in functions:
vector = '\\' + quote + filling + r('autofocus') + filling + \ vector = '\\' + breaker + filling + 'auTOfOcuS' + filling + \
r('onfocus') + '=' + function + filling + '\\' + quote 'OnFoCUs' + '=' + function + filling + '\\' + breaker
found = True found = True
vectors[7].add(vector) vectors[6].add(vector)
if Type == 'value': if attributeName == 'srcdoc':
if attributeName == 'srcdoc': if occurences[i]['score']['&lt;']:
if occurences[i]['score']['&lt;']: if occurences[i]['score']['&gt;']:
if occurences[i]['score']['&gt;']: del ends[:]
del ends[:] ends.append('%26gt;')
ends.append('%26gt;') payloads = genGen(
payloads = genGen( fillings, eFillings, lFillings, eventHandlers, tags, functions, ends, '', '')
fillings, eFillings, lFillings, eventHandlers, tags, functions, ends) for payload in payloads:
for payload in payloads:
found = True
vectors[9].add(payload.replace('<', '%26lt;'))
elif attributeName == 'href' and attributeValue == xsschecker:
for function in functions:
found = True found = True
vectors[10].add(r('javascript:') + function) vectors[9].add(payload.replace('<', '%26lt;'))
elif attributeName.startswith('on'): if attributeName.startswith('on'):
closer = jsContexter(attributeValue) closer = jsContexter(attributeValue)
quote = '' breaker = ''
for char in attributeValue.split(xsschecker)[1]: for char in attributeValue.split(xsschecker)[1]:
if char in ['\'', '"', '`']: if char in ['\'', '"', '`']:
quote = char breaker = char
break break
if closer:
suffix = '//\\' suffix = '//\\'
for filling in jFillings: for filling in jFillings:
for function in functions: for function in functions:
vector = quote + closer + filling + function + suffix vector = breaker + closer + filling + function + suffix
if found: if found:
vectors[7].add(vector) vectors[7].add(vector)
else: else:
vectors[9].add(vector) vectors[9].add(vector)
if quoteEfficiency > 83: elif breakerEfficiency > 83:
suffix = '//' suffix = '//'
for filling in jFillings: for filling in jFillings:
for function in functions:
if '=' in function:
function = '(' + function + ')'
if quote == '':
filling = ''
vector = '\\' + quote + closer + filling + function + suffix
if found:
vectors[7].add(vector)
else:
vectors[9].add(vector)
elif tag in ('script', 'iframe', 'embed', 'object'):
if attributeName in ('src', 'iframe', 'embed') and attributeValue == xsschecker:
payloads = ['//15.rs', '\\/\\\\\\/\\15.rs']
for payload in payloads:
vectors[10].add(payload)
elif tag == 'object' and attributeName == 'data' and attributeValue == xsschecker:
for function in functions: for function in functions:
found = True if '=' in function:
vectors[10].add(r('javascript:') + function) function = '(' + function + ')'
elif quoteEfficiency == greatBracketEfficiency == 100: if breaker == '':
payloads = genGen(fillings, eFillings, lFillings, filling = ''
eventHandlers, tags, functions, ends) vector = '\\' + breaker + closer + filling + function + suffix
for payload in payloads: if found:
payload = quote + '>' + r('</script/>') + payload vectors[7].add(vector)
found = True else:
vectors[11].add(payload) vectors[9].add(vector)
elif context == 'comment': elif context == 'comment':
lessBracketEfficiency = occurences[i]['score']['<'] lessBracketEfficiency = occurences[i]['score']['<']
greatBracketEfficiency = occurences[i]['score']['>'] greatBracketEfficiency = occurences[i]['score']['>']
breakerEfficiency = occurences[i]['score'][breaker]
ends = ['//'] ends = ['//']
if greatBracketEfficiency == 100: if greatBracketEfficiency == 100:
ends.append('>') ends.append('>')
if lessBracketEfficiency == 100: if lessBracketEfficiency == breakerEfficiency == 100:
payloads = genGen(fillings, eFillings, lFillings, payloads = genGen(fillings, eFillings, lFillings,
eventHandlers, tags, functions, ends) eventHandlers, tags, functions, ends, breaker, special)
for payload in payloads: for payload in payloads:
vectors[10].add(payload) vectors[10].add(payload)
elif context == 'script': elif context == 'script':
@@ -134,26 +130,27 @@ def generator(occurences, response):
else: else:
continue continue
closer = jsContexter(script) closer = jsContexter(script)
quote = occurences[i]['details']['quote']
scriptEfficiency = occurences[i]['score']['</scRipT/>'] scriptEfficiency = occurences[i]['score']['</scRipT/>']
greatBracketEfficiency = occurences[i]['score']['>'] greatBracketEfficiency = occurences[i]['score']['>']
breakerEfficiency = 100 breakerEfficiency = occurences[i]['score'][breaker]
if quote:
breakerEfficiency = occurences[i]['score'][quote]
ends = ['//'] ends = ['//']
if greatBracketEfficiency == 100: if greatBracketEfficiency == 100:
ends.append('>') ends.append('>')
if scriptEfficiency == 100: if scriptEfficiency == 100:
breaker = r('</script/>') breaker = r('</script/>')
payloads = genGen(fillings, eFillings, lFillings, payloads = genGen(fillings, eFillings, lFillings,
eventHandlers, tags, functions, ends) eventHandlers, tags, functions, ends, breaker, special)
for payload in payloads: for payload in payloads:
vectors[10].add(payload) vectors[10].add(payload)
if closer: if closer:
suffix = '//\\' suffix = '//\\'
if not breaker:
closer = closer[1:]
if breakerEfficiency != 100:
breaker = ''
for filling in jFillings: for filling in jFillings:
for function in functions: for function in functions:
vector = quote + closer + filling + function + suffix vector = breaker + closer + filling + function + suffix
vectors[7].add(vector) vectors[7].add(vector)
elif breakerEfficiency > 83: elif breakerEfficiency > 83:
suffix = '//' suffix = '//'
@@ -161,9 +158,9 @@ def generator(occurences, response):
for function in functions: for function in functions:
if '=' in function: if '=' in function:
function = '(' + function + ')' function = '(' + function + ')'
if quote == '': if breaker == '':
filling = '' filling = ''
vector = '\\' + quote + closer + filling + function + suffix vector = '\\' + breaker + closer + filling + function + suffix
vectors[6].add(vector) vectors[6].add(vector)
index += 1 index += 1
return vectors return vectors

View File

@@ -1,7 +1,7 @@
import re import re
from core.config import badTags, xsschecker from core.config import badTags, xsschecker
from core.utils import isBadContext, equalize, escaped from core.utils import isBadContext
def htmlParser(response, encoding): def htmlParser(response, encoding):
@@ -9,82 +9,104 @@ def htmlParser(response, encoding):
response = response.text # response content response = response.text # response content
if encoding: # if the user has specified an encoding, encode the probe in that if encoding: # if the user has specified an encoding, encode the probe in that
response = response.replace(encoding(xsschecker), xsschecker) response = response.replace(encoding(xsschecker), xsschecker)
reflections = response.count(xsschecker) tags = [] # tags in which the input is reflected
position_and_context = {} locations = [] # contexts in which the input is reflected
environment_details = {} attributes = [] # attribute names
clean_response = re.sub(r'<!--[.\s\S]*?-->', '', response) environments = [] # strings needed to break out of the context
script_checkable = clean_response positions = [] # postions of all the reflections of the xsschecker
for i in range(reflections): for match in re.finditer(xsschecker, response):
occurence = re.search(r'(?i)(?s)<script[^>]*>.*?(%s).*?</script>' % xsschecker, script_checkable) positions.append(match.start())
if occurence:
thisPosition = occurence.start(1)
position_and_context[thisPosition] = 'script'
environment_details[thisPosition] = {}
environment_details[thisPosition]['details'] = {'quote' : ''}
for i in range(len(occurence.group())):
currentChar = occurence.group()[i]
if currentChar in ('\'', '`', '"') and not escaped(i, occurence.group()):
environment_details[thisPosition]['details']['quote'] = currentChar
elif currentChar in (')', ']', '}', '}') and not escaped(i, occurence.group()):
break
script_checkable = script_checkable.replace(xsschecker, '', 1)
if len(position_and_context) < reflections:
attribute_context = re.finditer(r'<[^>]*?(%s)[^>]*?>' % xsschecker, clean_response)
for occurence in attribute_context:
match = occurence.group(0)
thisPosition = occurence.start(1)
parts = re.split(r'\s', match)
tag = parts[0][1:]
for part in parts:
if xsschecker in part:
Type, quote, name, value = '', '', '', ''
if '=' in part:
quote = re.search(r'=([\'`"])?', part).group(1)
name_and_value = part.split('=')[0], '='.join(part.split('=')[1:])
if xsschecker == name_and_value[0]:
Type = 'name'
else:
Type = 'value'
name = name_and_value[0]
value = name_and_value[1].rstrip('>').rstrip(quote).lstrip(quote)
else:
Type = 'flag'
position_and_context[thisPosition] = 'attribute'
environment_details[thisPosition] = {}
environment_details[thisPosition]['details'] = {'tag' : tag, 'type' : Type, 'quote' : quote, 'value' : value, 'name' : name}
if len(position_and_context) < reflections:
html_context = re.finditer(xsschecker, clean_response)
for occurence in html_context:
thisPosition = occurence.start()
if thisPosition not in position_and_context:
position_and_context[occurence.start()] = 'html'
environment_details[thisPosition] = {}
environment_details[thisPosition]['details'] = {}
if len(position_and_context) < reflections:
comment_context = re.finditer(r'<!--[\s\S]*?(%s)[\s\S]*?-->' % xsschecker, response)
for occurence in comment_context:
thisPosition = occurence.start(1)
position_and_context[thisPosition] = 'comment'
environment_details[thisPosition] = {}
environment_details[thisPosition]['details'] = {}
database = {}
for i in sorted(position_and_context):
database[i] = {}
database[i]['position'] = i
database[i]['context'] = position_and_context[i]
database[i]['details'] = environment_details[i]['details']
bad_contexts = re.finditer(r'(?s)(?i)<(style|template|textarea|title|noembed|noscript)>[.\s\S]*(%s)[.\s\S]*</\1>' % xsschecker, response) # It finds the contexts of the reflections
parts = response.split(xsschecker)
# remove first element since it doesn't contain xsschecker
parts.remove(parts[0])
# add xsschecker in front of all elements
parts = [xsschecker + s for s in parts]
for part in parts: # iterate over the parts
deep = part.split('>')
if '</script' in deep[0]:
location = 'script'
elif '</' in deep[0] or len(parts) == 1:
location = 'html'
else:
num = 0
for i in deep:
if i[-2:] == '--':
if '<!--' not in ''.join(deep[:num + 1]):
location = 'comment'
break
continue
location = 'script'
for char in part:
# the only way to find out if it's attribute context is to see if '<' is present.
if char == '<':
location = 'attribute' # no, it doesn't match '<script>'
break
num += 1
if '<' not in response:
if rawResponse.headers['Content-Type'].startswith('text/html'):
location = 'html'
locations.append(location) # add location to locations list
bad_contexts = re.finditer(r'''(?s)(?i)<(style|template|textarea|title|noembed|noscript)>[.\s\S]*(%s)[.\s\S]*</\1>''' % xsschecker, response)
non_executable_contexts = [] non_executable_contexts = []
for each in bad_contexts: for each in bad_contexts:
non_executable_contexts.append([each.start(), each.end(), each.group(1)]) non_executable_contexts.append([each.start(), each.end(), each.group(1)])
# Finds the "environment" of reflections. is it within double quotes? Which tag contains the reflection?
if non_executable_contexts: num = 0 # dummy value to keep record of occurence being processed
for key in database.keys(): # find xsschecker in response and return matches
position = database[key]['position'] for occ in re.finditer(xsschecker, response, re.IGNORECASE):
badTag = isBadContext(position, non_executable_contexts) # convert "xsschecker to EOF" into a list
if badTag: toLook = list(response[occ.end():])
database[key]['details']['badTag'] = badTag for loc in range(len(toLook)): # interate over the chars
else: if toLook[loc] in ('\'', '"', '`'): # if the char is a quote
database[key]['details']['badTag'] = '' environments.append(toLook[loc]) # add it to environments list
return database tokens = response.split('<')
goodTokens = [] # tokens which contain xsschecker
for token in tokens: # iterate over tokens
if xsschecker in token: # if xsschecker is in token
goodTokens.append(token) # add it to goodTokens list
# attributes and their values are generally seperated with space so...
attrs = token.split(' ')
for attr in attrs: # iterate over the attribute
if xsschecker in attr: # is xsschecker in this attribute?
# alright, this is the one we need
attributeName = attr.split('=')[0]
attributeValue = ''.join(attr.split('=')[1:])
if attributeValue.startswith('\'') or attributeValue.startswith('"'):
attributeValue = attributeValue[1:-1]
attributes.append({attributeName:attributeValue})
break
try:
# finds the tag "inside" which input is refelcted
tag = re.search(r'\w+', goodTokens[num]).group()
except IndexError:
try:
# finds the tag "inside" which input is refelcted
tag = re.search(r'\w+', goodTokens[num - 1]).group()
except IndexError:
tag = 'null'
tags.append(tag) # add the tag to the tags list
break
else: # if we encounter a closing angular brackt
# check if the next character to it is a / to make sure its a closing tag
badContext = isBadContext(positions[num], non_executable_contexts)
if badContext:
environments.append('</' + badContext + '>')
else:
environments.append('')
tags.append('')
attributes.append('')
break
loc += 1
num += 1
occurences = {} # a dict to store all the collected information about the reflections
for i, loc, env, tag, attr, position in zip(range(len(locations)), locations, environments, tags, attributes, positions):
occurences[i] = {}
occurences[i]['position'] = position
if loc == 'comment': # if context is html comment
env = '-->' # add --> as environment as we need this to break out
occurences[i]['context'] = [loc, env, tag, attr]
return [occurences, positions]

View File

@@ -54,19 +54,16 @@ def photon(seedUrl, headers, level, threadCount, delay, timeout, skipDOM):
for link in matches: # iterate over the matches for link in matches: # iterate over the matches
# remove everything after a "#" to deal with in-page anchors # remove everything after a "#" to deal with in-page anchors
link = link.split('#')[0] link = link.split('#')[0]
if link.endswith(('.pdf', '.png', '.jpg', '.jpeg', '.xls', '.xml', '.docx', '.doc')): if link[:4] == 'http':
pass if link.startswith(main_url):
storage.add(link)
elif link[:2] == '//':
if link.split('/')[2].startswith(host):
storage.add(schema + link)
elif link[:1] == '/':
storage.add(main_url + link)
else: else:
if link[:4] == 'http': storage.add(main_url + '/' + link)
if link.startswith(main_url):
storage.add(link)
elif link[:2] == '//':
if link.split('/')[2].startswith(host):
storage.add(schema + link)
elif link[:1] == '/':
storage.add(main_url + link)
else:
storage.add(main_url + '/' + link)
for x in range(level): for x in range(level):
urls = storage - processed # urls to crawl = all urls - urls that have been crawled urls = storage - processed # urls to crawl = all urls - urls that have been crawled
# for url in urls: # for url in urls:

View File

@@ -131,7 +131,7 @@ def flattenParams(currentParam, params, payload):
return '?' + '&'.join(flatted) return '?' + '&'.join(flatted)
def genGen(fillings, eFillings, lFillings, eventHandlers, tags, functions, ends, badTag=None): def genGen(fillings, eFillings, lFillings, eventHandlers, tags, functions, ends, breaker, special):
vectors = [] vectors = []
r = randomUpper # randomUpper randomly converts chars of a string to uppercase r = randomUpper # randomUpper randomly converts chars of a string to uppercase
for tag in tags: for tag in tags:
@@ -150,10 +150,7 @@ def genGen(fillings, eFillings, lFillings, eventHandlers, tags, functions, ends,
if tag == 'd3v' or tag == 'a': if tag == 'd3v' or tag == 'a':
if '>' in ends: if '>' in ends:
end = '>' # we can't use // as > with "a" or "d3v" tag end = '>' # we can't use // as > with "a" or "d3v" tag
breaker = '' vector = vector = r(breaker) + special + '<' + r(tag) + filling + r(
if badTag:
breaker = '</' + r(badTag) + '>'
vector = breaker + '<' + r(tag) + filling + r(
eventHandler) + eFilling + '=' + eFilling + function + lFilling + end + bait eventHandler) + eFilling + '=' + eFilling + function + lFilling + end + bait
vectors.append(vector) vectors.append(vector)
return vectors return vectors
@@ -180,8 +177,6 @@ def getParams(url, data, GET):
parts = data.split('&') parts = data.split('&')
for part in parts: for part in parts:
each = part.split('=') each = part.split('=')
if len(each) < 2:
each.append('')
try: try:
params[each[0]] = each[1] params[each[0]] = each[1]
except IndexError: except IndexError:
@@ -217,20 +212,22 @@ def js_extractor(response):
def handle_anchor(parent_url, url): def handle_anchor(parent_url, url):
if parent_url.count('/') > 2:
replacable = re.search(r'/[^/]*?$', parent_url).group()
if replacable != '/':
parent_url = parent_url.replace(replacable, '')
scheme = urlparse(parent_url).scheme scheme = urlparse(parent_url).scheme
if url[:4] == 'http': if url[:4] == 'http':
return url return url
elif url[:2] == '//': elif url[:2] == '//':
return scheme + ':' + url return scheme + ':' + url
elif url.startswith('/'): elif url[:1] == '/':
host = urlparse(parent_url).netloc
scheme = urlparse(parent_url).scheme
parent_url = scheme + '://' + host
return parent_url + url
elif parent_url.endswith('/'):
return parent_url + url return parent_url + url
else: else:
return parent_url + '/' + url if parent_url.endswith('/') or url.startswith('/'):
return parent_url + url
else:
return parent_url + '/' + url
def deJSON(data): def deJSON(data):
@@ -256,21 +253,3 @@ def isBadContext(position, non_executable_contexts):
badContext = each[2] badContext = each[2]
break break
return badContext return badContext
def equalize(array, number):
if len(array) < number:
array.append('')
def escaped(position, string):
usable = string[:position][::-1]
match = re.search(r'^\\*', usable)
if match:
match = match.group()
if len(match) == 1:
return True
elif len(match) % 2 == 0:
return False
else:
return True
else:
return False

View File

@@ -41,8 +41,9 @@ def crawl(scheme, host, main_url, form, blindXSS, blindPayload, headers, delay,
paramsCopy[paramName] = xsschecker paramsCopy[paramName] = xsschecker
response = requester( response = requester(
url, paramsCopy, headers, GET, delay, timeout) url, paramsCopy, headers, GET, delay, timeout)
occurences = htmlParser(response, encoding) parsedResponse = htmlParser(response, encoding)
positions = occurences.keys() occurences = parsedResponse[0]
positions = parsedResponse[1]
efficiencies = filterChecker( efficiencies = filterChecker(
url, paramsCopy, headers, GET, delay, occurences, timeout, encoding) url, paramsCopy, headers, GET, delay, occurences, timeout, encoding)
vectors = generator(occurences, response.text) vectors = generator(occurences, response.text)

View File

@@ -67,9 +67,11 @@ def scan(target, paramData, encoding, headers, delay, timeout, skipDOM, find, sk
else: else:
paramsCopy[paramName] = xsschecker paramsCopy[paramName] = xsschecker
response = requester(url, paramsCopy, headers, GET, delay, timeout) response = requester(url, paramsCopy, headers, GET, delay, timeout)
occurences = htmlParser(response, encoding) parsedResponse = htmlParser(response, encoding)
positions = occurences.keys() occurences = parsedResponse[0]
logger.debug('Scan occurences: {}'.format(occurences)) logger.debug('Scan occurences: {}'.format(occurences))
positions = parsedResponse[1]
logger.debug('Scan positions: {}'.format(positions))
if not occurences: if not occurences:
logger.error('No reflection found') logger.error('No reflection found')
continue continue