Files
XSStrike/core/utils.py

263 lines
7.4 KiB
Python
Raw Normal View History

2018-11-13 12:43:47 +05:30
import json
2018-10-27 18:58:52 +05:30
import random
import re
2018-11-22 13:43:25 +05:30
from urllib.parse import urlparse
2018-11-22 01:47:04 +05:30
import core.config
from core.config import xsschecker
2018-11-13 12:43:47 +05:30
2018-11-22 13:43:25 +05:30
def converter(data, url=False):
2018-11-22 01:47:04 +05:30
if 'str' in str(type(data)):
2018-11-22 13:43:25 +05:30
if url:
dictized = {}
parts = data.split('/')[3:]
for part in parts:
dictized[part] = part
return dictized
else:
return json.loads(data)
2018-11-22 01:47:04 +05:30
else:
2018-11-22 13:43:25 +05:30
if url:
url = urlparse(url).scheme + '://' + urlparse(url).netloc
for part in list(data.values()):
url += '/' + part
return url
else:
return json.dumps(data)
2018-11-22 01:47:04 +05:30
def counter(string):
2018-12-07 23:43:45 +05:30
string = re.sub(r'\s|\w', '', string)
2018-11-22 01:47:04 +05:30
return len(string)
2018-11-16 21:13:45 +05:30
def closest(number, numbers):
difference = [abs(list(numbers.values())[0]), {}]
for index, i in numbers.items():
diff = abs(number - i)
if diff < difference[0]:
2018-11-16 21:13:45 +05:30
difference = [diff, {index: i}]
return difference[1]
2018-11-16 21:13:45 +05:30
def fillHoles(original, new):
filler = 0
filled = []
for x, y in zip(original, new):
if int(x) == (y + filler):
filled.append(y)
else:
filled.extend([0, y])
filler += (int(x) - y)
return filled
2018-11-16 21:13:45 +05:30
2018-10-28 23:54:57 +05:30
def stripper(string, substring, direction='right'):
done = False
strippedString = ''
if direction == 'right':
string = string[::-1]
for char in string:
if char == substring and not done:
done = True
else:
strippedString += char
if direction == 'right':
strippedString = strippedString[::-1]
return strippedString
2018-11-16 21:13:45 +05:30
2018-10-27 18:58:52 +05:30
def extractHeaders(headers):
2018-12-20 12:36:47 +05:30
headers = headers.replace('\\n', '\n')
2018-10-27 18:58:52 +05:30
sorted_headers = {}
matches = re.findall(r'(.*):\s(.*)', headers)
for match in matches:
header = match[0]
value = match[1]
try:
if value[-1] == ',':
value = value[:-1]
sorted_headers[header] = value
except IndexError:
pass
return sorted_headers
2018-11-16 21:13:45 +05:30
2018-11-18 22:46:31 +01:00
def replaceValue(mapping, old, new, strategy=None):
"""
Replace old values with new ones following dict strategy.
The parameter strategy is None per default for inplace operation.
A copy operation is injected via strateg values like copy.copy
or copy.deepcopy
Note: A dict is returned regardless of modifications.
"""
anotherMap = strategy(mapping) if strategy else mapping
if old in anotherMap.values():
for k in anotherMap.keys():
if anotherMap[k] == old:
anotherMap[k] = new
return anotherMap
2018-10-27 18:58:52 +05:30
2018-11-16 21:13:45 +05:30
2018-11-13 12:43:47 +05:30
def getUrl(url, GET):
2018-10-27 18:58:52 +05:30
if GET:
return url.split('?')[0]
else:
return url
2018-11-16 21:13:45 +05:30
2018-10-27 18:58:52 +05:30
def extractScripts(response):
scripts = []
matches = re.findall(r'(?s)<script.*?>(.*?)</script>', response.lower())
for match in matches:
if xsschecker in match:
scripts.append(match)
return scripts
2018-11-16 21:13:45 +05:30
2018-10-27 18:58:52 +05:30
def randomUpper(string):
2018-11-16 21:13:45 +05:30
return ''.join(random.choice((x, y)) for x, y in zip(string.upper(), string.lower()))
2018-10-27 18:58:52 +05:30
def flattenParams(currentParam, params, payload):
flatted = []
for name, value in params.items():
if name == currentParam:
value = payload
flatted.append(name + '=' + value)
return '?' + '&'.join(flatted)
2018-11-16 21:13:45 +05:30
2019-04-19 07:53:00 +05:30
def genGen(fillings, eFillings, lFillings, eventHandlers, tags, functions, ends, badTag=None):
2018-10-27 18:58:52 +05:30
vectors = []
2018-11-16 21:13:45 +05:30
r = randomUpper # randomUpper randomly converts chars of a string to uppercase
2018-10-27 18:58:52 +05:30
for tag in tags:
if tag == 'd3v' or tag == 'a':
bait = xsschecker
2018-10-27 18:58:52 +05:30
else:
bait = ''
for eventHandler in eventHandlers:
2018-11-16 21:13:45 +05:30
# if the tag is compatible with the event handler
2018-10-27 18:58:52 +05:30
if tag in eventHandlers[eventHandler]:
for function in functions:
for filling in fillings:
for eFilling in eFillings:
for lFilling in lFillings:
for end in ends:
if tag == 'd3v' or tag == 'a':
if '>' in ends:
2018-11-16 21:13:45 +05:30
end = '>' # we can't use // as > with "a" or "d3v" tag
2019-04-19 07:53:00 +05:30
breaker = ''
if badTag:
breaker = '</' + r(badTag) + '>'
vector = breaker + '<' + r(tag) + filling + r(
2018-11-16 21:13:45 +05:30
eventHandler) + eFilling + '=' + eFilling + function + lFilling + end + bait
2018-10-27 18:58:52 +05:30
vectors.append(vector)
return vectors
2018-11-16 21:13:45 +05:30
2018-10-27 18:58:52 +05:30
def getParams(url, data, GET):
params = {}
2018-11-22 02:14:06 +05:30
if '=' in url:
data = url.split('?')[1]
if data[:1] == '?':
data = data[1:]
elif data:
2019-04-06 20:45:10 +05:30
if getVar('jsonData') or getVar('path'):
params = data
else:
try:
params = json.loads(data.replace('\'', '"'))
return params
except json.decoder.JSONDecodeError:
pass
2018-11-22 02:14:06 +05:30
else:
return None
if not params:
2018-11-21 21:46:15 +05:30
parts = data.split('&')
for part in parts:
each = part.split('=')
try:
params[each[0]] = each[1]
except IndexError:
params = None
return params
2018-11-18 22:46:31 +01:00
def writer(obj, path):
kind = str(type(obj)).split('\'')[0]
if kind == 'list' or kind == 'tuple':
obj = '\n'.join(obj)
elif kind == 'dict':
obj = json.dumps(obj, indent=4)
savefile = open(path, 'w+')
2018-12-19 00:00:54 +05:30
savefile.write(str(obj.encode('utf-8')))
2018-11-18 22:46:31 +01:00
savefile.close()
def reader(path):
with open(path, 'r') as f:
2019-04-06 20:45:10 +05:30
result = [line.rstrip(
2018-11-18 22:46:31 +01:00
'\n').encode('utf-8').decode('utf-8') for line in f]
return result
2019-04-06 20:45:10 +05:30
def js_extractor(response):
"""Extract js files from the response body"""
scripts = []
matches = re.findall(r'<(?:script|SCRIPT).*?(?:src|SRC)=([^\s>]+)', response)
for match in matches:
match = match.replace('\'', '').replace('"', '').replace('`', '')
scripts.append(match)
return scripts
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
if url[:4] == 'http':
return url
elif url[:2] == '//':
return scheme + ':' + url
elif url[:1] == '/':
return parent_url + url
else:
if parent_url.endswith('/') or url.startswith('/'):
return parent_url + url
else:
return parent_url + '/' + url
def deJSON(data):
return data.replace('\\\\', '\\')
def getVar(name):
return core.config.globalVariables[name]
def updateVar(name, data, mode=None):
if mode:
if mode == 'append':
core.config.globalVariables[name].append(data)
elif mode == 'add':
core.config.globalVariables[name].add(data)
else:
core.config.globalVariables[name] = data
def isBadContext(position, non_executable_contexts):
badContext = ''
for each in non_executable_contexts:
if each[0] < position < each[1]:
badContext = each[2]
break
return badContext
2019-04-19 07:53:00 +05:30
def equalize(array, number):
if len(array) < number:
array.append('')