17 |
18 |
document.querySelector("#xss-d").innerHTML = new URLSearchParams(window.location.search).get("d")
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/xsstrike.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | from __future__ import print_function
4 |
5 | from core.colors import end, red, white, bad, info
6 |
7 | # Just a fancy ass banner
8 | print('''%s
9 | \tXSStrike %sv3.1.5
10 | %s''' % (red, white, end))
11 |
12 | try:
13 | import concurrent.futures
14 | from urllib.parse import urlparse
15 | try:
16 | import fuzzywuzzy
17 | except ImportError:
18 | import os
19 | print ('%s fuzzywuzzy isn\'t installed, installing now.' % info)
20 | ret_code = os.system('pip3 install fuzzywuzzy')
21 | if(ret_code != 0):
22 | print('%s fuzzywuzzy installation failed.' % bad)
23 | quit()
24 | print ('%s fuzzywuzzy has been installed, restart XSStrike.' % info)
25 | quit()
26 | except ImportError: # throws error in python2
27 | print('%s XSStrike isn\'t compatible with python2.\n Use python > 3.4 to run XSStrike.' % bad)
28 | quit()
29 |
30 | # Let's import whatever we need from standard lib
31 | import sys
32 | import json
33 | import argparse
34 |
35 | # ... and configurations core lib
36 | import core.config
37 | import core.log
38 |
39 | # Processing command line arguments, where dest var names will be mapped to local vars with the same name
40 | parser = argparse.ArgumentParser()
41 | parser.add_argument('-u', '--url', help='url', dest='target')
42 | parser.add_argument('--data', help='post data', dest='paramData')
43 | parser.add_argument('-e', '--encode', help='encode payloads', dest='encode')
44 | parser.add_argument('--fuzzer', help='fuzzer',
45 | dest='fuzz', action='store_true')
46 | parser.add_argument('--update', help='update',
47 | dest='update', action='store_true')
48 | parser.add_argument('--timeout', help='timeout',
49 | dest='timeout', type=int, default=core.config.timeout)
50 | parser.add_argument('--proxy', help='use prox(y|ies)',
51 | dest='proxy', action='store_true')
52 | parser.add_argument('--crawl', help='crawl',
53 | dest='recursive', action='store_true')
54 | parser.add_argument('--json', help='treat post data as json',
55 | dest='jsonData', action='store_true')
56 | parser.add_argument('--path', help='inject payloads in the path',
57 | dest='path', action='store_true')
58 | parser.add_argument(
59 | '--seeds', help='load crawling seeds from a file', dest='args_seeds')
60 | parser.add_argument(
61 | '-f', '--file', help='load payloads from a file', dest='args_file')
62 | parser.add_argument('-l', '--level', help='level of crawling',
63 | dest='level', type=int, default=2)
64 | parser.add_argument('--headers', help='add headers',
65 | dest='add_headers', nargs='?', const=True)
66 | parser.add_argument('-t', '--threads', help='number of threads',
67 | dest='threadCount', type=int, default=core.config.threadCount)
68 | parser.add_argument('-d', '--delay', help='delay between requests',
69 | dest='delay', type=int, default=core.config.delay)
70 | parser.add_argument('--skip', help='don\'t ask to continue',
71 | dest='skip', action='store_true')
72 | parser.add_argument('--skip-dom', help='skip dom checking',
73 | dest='skipDOM', action='store_true')
74 | parser.add_argument('--blind', help='inject blind XSS payload while crawling',
75 | dest='blindXSS', action='store_true')
76 | parser.add_argument('--console-log-level', help='Console logging level',
77 | dest='console_log_level', default=core.log.console_log_level,
78 | choices=core.log.log_config.keys())
79 | parser.add_argument('--file-log-level', help='File logging level', dest='file_log_level',
80 | choices=core.log.log_config.keys(), default=None)
81 | parser.add_argument('--log-file', help='Name of the file to log', dest='log_file',
82 | default=core.log.log_file)
83 | args = parser.parse_args()
84 |
85 | # Pull all parameter values of dict from argparse namespace into local variables of name == key
86 | # The following works, but the static checkers are too static ;-) locals().update(vars(args))
87 | target = args.target
88 | path = args.path
89 | jsonData = args.jsonData
90 | paramData = args.paramData
91 | encode = args.encode
92 | fuzz = args.fuzz
93 | update = args.update
94 | timeout = args.timeout
95 | proxy = args.proxy
96 | recursive = args.recursive
97 | args_file = args.args_file
98 | args_seeds = args.args_seeds
99 | level = args.level
100 | add_headers = args.add_headers
101 | threadCount = args.threadCount
102 | delay = args.delay
103 | skip = args.skip
104 | skipDOM = args.skipDOM
105 | blindXSS = args.blindXSS
106 | core.log.console_log_level = args.console_log_level
107 | core.log.file_log_level = args.file_log_level
108 | core.log.log_file = args.log_file
109 |
110 | logger = core.log.setup_logger()
111 |
112 | core.config.globalVariables = vars(args)
113 |
114 | # Import everything else required from core lib
115 | from core.config import blindPayload
116 | from core.encoders import base64
117 | from core.photon import photon
118 | from core.prompt import prompt
119 | from core.updater import updater
120 | from core.utils import extractHeaders, reader, converter
121 |
122 | from modes.bruteforcer import bruteforcer
123 | from modes.crawl import crawl
124 | from modes.scan import scan
125 | from modes.singleFuzz import singleFuzz
126 |
127 | if type(args.add_headers) == bool:
128 | headers = extractHeaders(prompt())
129 | elif type(args.add_headers) == str:
130 | headers = extractHeaders(args.add_headers)
131 | else:
132 | from core.config import headers
133 |
134 | core.config.globalVariables['headers'] = headers
135 | core.config.globalVariables['checkedScripts'] = set()
136 | core.config.globalVariables['checkedForms'] = {}
137 | core.config.globalVariables['definitions'] = json.loads('\n'.join(reader(sys.path[0] + '/db/definitions.json')))
138 |
139 | if path:
140 | paramData = converter(target, target)
141 | elif jsonData:
142 | headers['Content-type'] = 'application/json'
143 | paramData = converter(paramData)
144 |
145 | if args_file:
146 | if args_file == 'default':
147 | payloadList = core.config.payloads
148 | else:
149 | payloadList = list(filter(None, reader(args_file)))
150 |
151 | seedList = []
152 | if args_seeds:
153 | seedList = list(filter(None, reader(args_seeds)))
154 |
155 | encoding = base64 if encode and encode == 'base64' else False
156 |
157 | if not proxy:
158 | core.config.proxies = {}
159 |
160 | if update: # if the user has supplied --update argument
161 | updater()
162 | quit() # quitting because files have been changed
163 |
164 | if not target and not args_seeds: # if the user hasn't supplied a url
165 | logger.no_format('\n' + parser.format_help().lower())
166 | quit()
167 |
168 | if fuzz:
169 | singleFuzz(target, paramData, encoding, headers, delay, timeout)
170 | elif not recursive and not args_seeds:
171 | if args_file:
172 | bruteforcer(target, paramData, payloadList, encoding, headers, delay, timeout)
173 | else:
174 | scan(target, paramData, encoding, headers, delay, timeout, skipDOM, skip)
175 | else:
176 | if target:
177 | seedList.append(target)
178 | for target in seedList:
179 | logger.run('Crawling the target')
180 | scheme = urlparse(target).scheme
181 | logger.debug('Target scheme: {}'.format(scheme))
182 | host = urlparse(target).netloc
183 | main_url = scheme + '://' + host
184 | crawlingResult = photon(target, headers, level,
185 | threadCount, delay, timeout, skipDOM)
186 | forms = crawlingResult[0]
187 | domURLs = list(crawlingResult[1])
188 | difference = abs(len(domURLs) - len(forms))
189 | if len(domURLs) > len(forms):
190 | for i in range(difference):
191 | forms.append(0)
192 | elif len(forms) > len(domURLs):
193 | for i in range(difference):
194 | domURLs.append(0)
195 | threadpool = concurrent.futures.ThreadPoolExecutor(max_workers=threadCount)
196 | futures = (threadpool.submit(crawl, scheme, host, main_url, form,
197 | blindXSS, blindPayload, headers, delay, timeout, encoding) for form, domURL in zip(forms, domURLs))
198 | for i, _ in enumerate(concurrent.futures.as_completed(futures)):
199 | if i + 1 == len(forms) or (i + 1) % threadCount == 0:
200 | logger.info('Progress: %i/%i\r' % (i + 1, len(forms)))
201 | logger.no_format('')
202 |
--------------------------------------------------------------------------------