From 350cc15a7e038d453439de633dcd1a8568f1cc13 Mon Sep 17 00:00:00 2001 From: Dan McInerney Date: Tue, 19 Aug 2014 04:28:57 -0400 Subject: [PATCH] improved xss-testing payload and logic --- xsscrapy/.middlewares.py.swo | Bin 0 -> 8192 bytes xsscrapy/.pipelines.py.swp | Bin 0 -> 28672 bytes xsscrapy/pipelines.py | 51 ++++++++++++++---- xsscrapy/spiders/.xss_spider.py.swo | Bin 0 -> 65536 bytes xsscrapy/spiders/xss_spider.py | 77 +++++----------------------- 5 files changed, 54 insertions(+), 74 deletions(-) create mode 100644 xsscrapy/.middlewares.py.swo create mode 100644 xsscrapy/.pipelines.py.swp create mode 100644 xsscrapy/spiders/.xss_spider.py.swo diff --git a/xsscrapy/.middlewares.py.swo b/xsscrapy/.middlewares.py.swo new file mode 100644 index 0000000000000000000000000000000000000000..81f8798225e72e30cc537ae97e344a2031307d5f GIT binary patch literal 8192 zcmeIuy$*sf5C`z0v)_{&$}FG^_zDhAMqNx41tW<e$33GbC>i%jV9s2_p~!( zyTGE!w>Y`BeRN_gaF|MyqQ@|Y00hblMB#ogt`TE2)Rlfu?zHFS@8To`AOHafKmY;| zfB*y_@D~Chtq?AL^5UFtM3%Dk6n$OPR@PTVUg!F^m^X60C=n2V00bZa0SG_<0uX=z M1Rwwb2>htP2X&q?IRF3v literal 0 HcmV?d00001 diff --git a/xsscrapy/.pipelines.py.swp b/xsscrapy/.pipelines.py.swp new file mode 100644 index 0000000000000000000000000000000000000000..d0c307ad06b18a730ee7ed424a4510ea2e229899 GIT binary patch literal 28672 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 gkZ5' in escaped_payload and '<' in escaped_payload: if '<' in joined_chars and '>' in joined_chars: @@ -130,6 +129,37 @@ class XSSCharFinder(object): # In case it slips by all of the filters, then we move on raise DropItem('No XSS vulns in %s' % resp_url) + def get_inj_line(self, body, payload): + lines = [] + html_lines = body.splitlines() + for idx, line in enumerate(html_lines): + line = line.strip() + if payload in line: + #if len(line) > 500: + # line = line[:200]+'...' + num_txt = (idx, line) + lines.append(num_txt) + + if len(lines) > 0: + return lines + + def get_unfiltered_chars(self, match, escaped_payload): + ''' Check for the special chars and append them to a master list of tuples, one tuple per injection point ''' + unfiltered_chars = [] + + # Make sure js payloads remove escaped ' and " + escaped_chars = re.findall(r'\\(.)', match) + for escaped_char in escaped_chars: + if escaped_char not in ['x', 'u']: # x and u for hex and unicode like \x43, \u0022 + match = match.replace(escaped_char, '') + + for c in escaped_payload: + if c in match: + unfiltered_chars.append(c) + + if len(unfiltered_chars) > 0: + return unfiltered_chars + def make_item(self, joined_chars, xss_type, orig_payload, tag, orig_url, inj_point, line, POST_to, item): ''' Create the vulnerable item ''' @@ -180,17 +210,13 @@ class XSSCharFinder(object): with open('formatted-vulns.txt', 'a+') as f: f.write('\n') - if 'error' in item: - f.write('Error: '+item['error']+'\n') - spider.log(' Error: '+item['error'], level='INFO') + f.write('URL: '+item['url']+'\n') + spider.log(' URL: '+item['url'], level='INFO') if 'POST_to' in item: f.write('POST url: '+item['POST_to']+'\n') spider.log(' POST url: '+item['POST_to'], level='INFO') - f.write('URL: '+item['url']+'\n') - spider.log(' URL: '+item['url'], level='INFO') - f.write('Unfiltered: '+item['unfiltered']+'\n') spider.log(' Unfiltered: '+item['unfiltered'], level='INFO') @@ -206,3 +232,8 @@ class XSSCharFinder(object): for line in item['line']: f.write('Line: '+line[1]+'\n') spider.log(' Line: '+line[1], level='INFO') + + if 'error' in item: + f.write('Error: '+item['error']+'\n') + spider.log(' Error: '+item['error'], level='INFO') + diff --git a/xsscrapy/spiders/.xss_spider.py.swo b/xsscrapy/spiders/.xss_spider.py.swo new file mode 100644 index 0000000000000000000000000000000000000000..8d3e1b420804ddf09c0654d04b10ef98f7cc1124 GIT binary patch literal 65536 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 QCTDDtNtxjYU7fD{Zw#!^5&!@I literal 0 HcmV?d00001 diff --git a/xsscrapy/spiders/xss_spider.py b/xsscrapy/spiders/xss_spider.py index f99ade8..ce3a61b 100644 --- a/xsscrapy/spiders/xss_spider.py +++ b/xsscrapy/spiders/xss_spider.py @@ -1,13 +1,11 @@ # -- coding: utf-8 -- +#from scrapy.selector import HtmlXPathSelector from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor from scrapy.contrib.spiders import CrawlSpider, Rule -#from scrapy.selector import HtmlXPathSelector -from scrapy.http import Request, FormRequest - +from scrapy.http import FormRequest, Request from xsscrapy.items import vuln, inj_resp from loginform import fill_login_form - from urlparse import urlparse, parse_qsl import lxml.html import lxml.etree @@ -45,10 +43,9 @@ class XSSspider(CrawlSpider): hostname = urlparse(self.start_urls[0]).hostname self.allowed_domains = ['.'.join(hostname.split('.')[-2:])] # adding [] around the value seems to allow it to crawl subdomain of value self.test_str = '9zqjx' - self.tag_pld = '()=<>' + self.test_pld = '\'"()=' self.js_pld = '\'"(){}[];' self.redir_pld = 'JaVAscRIPT:prompt(99)' - #attr_pld = generated once injection points are found (requires checking if single or double quotes ends html attribute values) self.login_user = kwargs.get('user') self.login_pass = kwargs.get('pw') @@ -201,6 +198,8 @@ class XSSspider(CrawlSpider): if type(i).__name__ not in ['InputElement', 'TextareaElement']: continue if type(i).__name__ == 'InputElement': + # Don't change values for the below types because they + # won't be strings if i.type == 'password': continue if i.type == 'checkbox': @@ -413,8 +412,6 @@ class XSSspider(CrawlSpider): def xss_str_generator(self, injections, quote_enclosure, inj_type): ''' This is where the injection points are analyzed and specific payloads are created ''' - event_attrs = self.event_attributes() - attr_pld = quote_enclosure+self.tag_pld payloads = [] for i in injections: @@ -425,32 +422,14 @@ class XSSspider(CrawlSpider): if attr == 'href' and attr_val == self.test_str: if self.redir_pld not in payloads: payloads.append(self.redir_pld) - # Test for javacsript running attributes - if attr in event_attrs: - if self.js_pld not in payloads: - payloads.append(self.js_pld) - - # Test for normal attribute-based XSS (needs either ' or " to be unescaped depending on which char the value is wrapped in - if attr_pld not in payloads: - payloads.append(attr_pld) - - # Between tag XSS payloads else: # Test for embedded js xss if tag == 'script' and self.js_pld not in payloads: payloads.append(self.js_pld) - # Test for normal between tag XSS (no quotes necessary) - if self.tag_pld not in payloads: - payloads.append(self.tag_pld) - # attribute payload is equal to tag payload just with a quote attached so - # this eliminates some overlap - if self.tag_pld in payloads and attr_pld in payloads: - payloads.remove(self.tag_pld) - - # I don't think URL encoding the dangerous chars is all that important - #if inj_type == 'url': - # #payloads.append(urllib.quote_plus(payloads[0])) + # Test for normal XSS + if self.test_pld not in payloads: + payloads.append(self.test_pld) payloads = self.delim_payloads(payloads) if len(payloads) > 0: @@ -479,20 +458,6 @@ class XSSspider(CrawlSpider): item['POST_to'] = POST_to return item - def get_inj_line(self, body, payload, item): - lines = [] - html_lines = body.splitlines() - for idx, line in enumerate(html_lines): - line = line.strip() - if payload in line: - #if len(line) > 500: - # line = line[:200]+'...' - num_txt = (idx, line) - lines.append(num_txt) - - if len(lines) > 0: - return lines - def parse_injections(self, injection): attr = None attr_val = None @@ -504,24 +469,6 @@ class XSSspider(CrawlSpider): return line, tag, attr, attr_val - def get_unfiltered_chars(self, match, escaped_payload): - ''' Check for the special chars and append them to a master list of tuples, one tuple per injection point ''' - unfiltered_chars = [] - - # Make sure js payloads remove escaped ' and " - #if escaped_payload == self.js_pld: - escaped_chars = re.findall(r'\\(.)', match) - for escaped_char in escaped_chars: - if escaped_char not in ['x', 'u']: # x and u for hex and unicode \x43, \u0022 - match = match.replace(escaped_char, '') - - for c in escaped_payload: - if c in match: - unfiltered_chars.append(c) - - if len(unfiltered_chars) > 0: - return unfiltered_chars - def unescape_payload(self, payload): ''' Unescape the various payload encodings (html and url encodings)''' if '%' in payload: @@ -636,7 +583,7 @@ class XSSspider(CrawlSpider): return reqs def payloaded_reqs(self, response): - + ''' Create the payloaded requests ''' body = response.body orig_url = response.meta['orig_url'] try: @@ -691,7 +638,8 @@ class XSSspider(CrawlSpider): def make_form_reqs(self, orig_url, forms, payloads, quote_enclosure, injections): ''' Logic: Get forms, find injectable input values, confirm at least one value has been injected, - confirm that value + url + POST/GET has not been made into a request before, finally send the request ''' + confirm that value + url + POST/GET has not been made into a request before, finally send the request + Note: if you see lots and lots of errors when POSTing, it is probably because of captchas''' reqs = [] vals_urls_meths = [] @@ -711,6 +659,7 @@ class XSSspider(CrawlSpider): cb = self.xss_chars_finder # POST to both the orig url and the specified form action='http://url.com' url + # Just to prevent false negatives if url != orig_url: urls = [url, orig_url] else: @@ -722,7 +671,7 @@ class XSSspider(CrawlSpider): formdata=values, method=method, meta={'payload':payload, - 'inj_point':'form field names: '+form_fields, + 'inj_point':'form field names - '+form_fields, 'injections':injections, 'quote':quote_enclosure, 'orig_url':orig_url,