1.反射型xss的介绍
xss代码出现在URL中,浏览器访问这个url后,服务端响应的内容中包含有这段xss代码,这样的xss被称作反射型xss.
2.工具的介绍
reflected_xss工具目前可以用来检测网站中是否可能存在反射型xss,程序是用python写的.
我用的python版本是2.7.3,系统上需要有python的requests模块.
工具有四个文件
spider.py用来爬取网页中的符合规则的url,可以指定爬取深度,然后生成一个urllist文件
reflect_xss.py检测urllist文件中的每一个url是否可能存在反射型xss漏洞
filter.py中的函数会被spider.py调用,过滤掉一些不带参数的url和重复的url.
config文件中,目前只有两个选项:timeout和sleep.
timeout是请求最多等待响应的时间.发送响应时,超过timout秒后就当作请求超时了.
sleep是每次请求url的间隔时间,因为有的网站会限制ip访问速度.
3.工具工作的流程
spider.py接受一个url参数,根据这个url发送请求,接收到响应后,把响应中符合规则的url提取出来,保存到urllist文件中.如果有指定爬取深度的话,会递归的爬取规则的url.这个规则是用正则写的,目前的规则是爬取到的url都应该是一个网站下的,并且url必须是带参数了的.
比如,spider.py “http://127.0.0.1/test.php?x=1” 能够保存的url都是以http://127.0.0.1开头的,并且url中有一个?号.
reflect_xss.py会检查urllist文件中的每一个url是否存在反射型xss.检测流程是:分析每一个url的参数,将”参数”挨个替换成”参数+xss payload”,然后发送出去,分析响应的内容中是否有xss payload字符串.其中的xss payload可以自定义,keywords文件中的每一行都会被当作一个xss payload.可以向keywords文件添加或删除xss payload.
4.工具用法演示
先来大致看下当前目录下的文件吧
再来看看我用来在本机测试的两个文件吧.
只有http://127.0.0.1/rxss.php?a=1&x=2这个url是符合规则的,所以一会儿爬虫爬完了,urllist中应该只有这一条url.
spider.py就是我们的小爬虫.
直接运行spider.py可以看到用法.
爬虫爬完了,生成了一个urllist文件,文件中只有一条url,一会儿就来检测这条url是否可能存在反射型xss缺陷
这个url参数最好还是要带上双引号,就跟用sqlmap的时候一样.
reflect_xss.py就是用来检测的.
直接python reflect_xss.py 运行程序就可以检测了.
如果有发现可能存在反射型xss,会在当前目录下生成一个Found文件,文件记录了有缺陷的url.
检测的时候,如果发生了异常,会被记录到当前目录下的error.log日志文件.这里没什么异常,所以没有记录.这个日志文件记录的比较简洁明了,我就不多做介绍了.
我的邮箱是:happy7513159@qq.com 欢迎交流
下载地址:http://vdisk.weibo.com/lc/3GawHF1w1aTxKu2BJjr 密码:CMB6
核心代码:
spider.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
|
#!/usr/bin/env python
#coding=utf-8
import requests
import re
import string
import sys
import filter
headers={‘Connection’:‘keep-alive’,“User-Agent”:“Mozilla/5.0 (X11; Linux i686) AppleWebkit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36″,“Origin”:“http://www.oschina.net”,‘Accept-Encoding’:‘gzip,deflate,sdch’,‘Accept-Language’:‘zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4′,‘X-Requested-With’:‘XMLHttpRequest’,‘Accept’:‘application/json,text/javascript,*/*;q=0.01′}
def saveurl(urlset):
try:
f=open(“urllist”,“a”)
for url in urlset:
#unicode字符码写入文件,添加换行
f.write(url.encode(‘UTF-8′)+“n”)
#except:
# print “Failed to write urllist to file!”
finally:
f.close()
def main(requestsurl,depth):
try:
#print “%d”%depth
depth=depth+1
urlset=parseContent(requests.get(requestsurl,timeout=2,headers=headers).text)
saveurl(urlset)
if depth==string.atoi(sys.argv[2]):
pass
else:
for u in urlset:
main(u,depth)
except:
pass
def parseContent(content):
strlist = re.split(‘”‘,content)
urlset = set([])
for strstr in strlist:
#python正则匹配时,需要//表示
#if re.match(‘http://.*com(/|w)+’, str):
#这个正则有点简单,只匹配了当前网站
#if re.match(‘http://’+domain, str):
rules=“http://”+domain+“[^,^ ^ ^']*”
#strstr是unicode对象
result=re.compile(rules).findall(strstr.encode(“utf-8″))
#result是一个数组
if len(result)==0:
pass
else:
for i in result:
urlset.add(i)
return list(urlset)
if __name__==“__main__”:
if len(sys.argv)!=3:
print “usage:”+sys.argv[0]+” http://test.com/”+” depth”
print “example:”+sys.argv[0]+‘ “http://127.0.0.1/a.php?c=1″‘+” 3″
else:
domain=sys.argv[1].split(‘/’)[2]
#保存最开始的url
tmp=[]
tmp.insert(0,sys.argv[1]);
saveurl(tmp)
#开始抓取
main(sys.argv[1],0)
filter.filter()
|
reflect_xss.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
|
#!/usr/bin/env python
#coding=utf-8
import requests
import sys
import time
import re
#global payloads
#payloads=['"><sCript>alert(1)</sCript>','<img src=@ onerror=x>']
jindu=0
def readconf(keyname):
isFound=0
try:
f=open(“config”,“r”)
lines=f.readlines()
for line in lines:
if line.startswith(keyname):
isFound=1
return line.split(‘=’)[1]
if isFound==0:
errorlog(“Warn:Can not to read key “+keyname+” from configure file”)
return False
except:
errorlog(“Warn:can not to read configure file “)
return False
def errorlog(str):
str=str+“n”
t=time.strftime(‘%m-%d %H.%M.%S—>’,time.localtime(time.time()))
f=open(“error.log”,“a”)
f.write(t+str)
f.close()
def findlog(url):
try:
f=open(“Found”,“a”)
f.write(url+“n”)
except:
errorlog(“Fail:open ‘Found’ file”)
finally:
f.close()
def main(payload,canshu,checkurl):
global jindu
url=checkurl.replace(canshu,canshu+payload)
#print “checking: “+url
#TODO timeout,防止ip被屏蔽应该有
if readconf(“sleep”):
time.sleep(float(readconf(“sleep”)))
#可能有Timeout异常
try:
a=requests.get(url,timeout=1)
if a.text.find(payload)!=-1:
#print “Find!!!!”
#print url
#print “———————–”
findlog(url)
else:
if jindu%10==0:
print time.strftime(‘%H:%M.%S->’,time.localtime(time.time()))+“checking the “+str(jindu)+“th”+” url:”+url
except:
errorlog(“Fail:request.get “+url)
jindu=jindu+1
def parse(url):
#url=http://test.com/test.php?a=1&b=2&c=3
#canshus=["a=1","c=3"]
#有可能url是http://test.com这种,没有参数
#这种情况,返回一个空对象
try:
canshus=url.split(“?”)[1].split(“&”)
return canshus
except:
kong=[]
return kong
pass
def readfile(filename):
#这个global的位置放在上面效果就不一样,不懂为什么
#global payloads
try:
aa=open(filename,“r”)
f=aa.readlines();
for i in range(0,len(f)):
#过滤掉n
f[i]=f[i].rstrip(“n”)
return f
except:
print “Failed to access “+‘”‘+filename+‘” ‘“file!”
finally:
aa.close()
if __name__==“__main__”:
if len(sys.argv)!=1:
print ‘usage:’+sys.argv[0]+” url depth”
print ‘example:’+sys.argv[0]+‘”http://url/test.php?x=1&y=2″ 3′
else:
#global payloads
payloads=readfile(“keywords.txt”)
urls=readfile(“urllist”)
for checkurl in urls:
for payload in payloads:
for canshu in parse(checkurl):
if len(canshu)!=0:
main(payload,canshu,checkurl)
|
赏金发放情况:本文获得赏金150RMB,已于4.11日发放到作者账号。
征稿启事:91RI一直相信“你不与人分享,谁与你分享”,分享的确是件非常有意义的事情。为了让优秀的同学有 地方分享自己的独到见解,也为了让更多同学从分享中受益,同时我们也希望给那些愿意分享的小伙伴们一点点心意作为感谢,所以我们隆重了推出“有奖征文”活 动!本次活动的详情可以围观《征稿启事》
Copyright © hongdaChiaki. All Rights Reserved. 鸿大千秋 版权所有
联系方式:
地址: 深圳市南山区招商街道沿山社区沿山路43号创业壹号大楼A栋107室
邮箱:service@hongdaqianqiu.com
备案号:粤ICP备15078875号