(汉化改进作品)BruteXSS:Xss漏洞扫描脚本
今天给大家进行汉化改进的事一款脚本工具:BruteXSS,这款脚本能自动进行插入XSS,而且可以自定义攻击载荷。
该脚本也同时提供包含了一些绕过各种WAF(Web应用防护系统)的语句。
0×01简介
简单的介绍一下这个工具吧:BruteXSS是一个非常强大和快速的跨站点脚本暴力注入。它用于暴力注入一个参数。该BruteXSS从指定的词库加载多种有效载荷进行注入并且使用指定的载荷和扫描检查这些参数很容易受到XSS漏洞。得益于非常强大的扫描功能。在执行任务时, BruteXSS是非常准确而且极少误报。 BruteXSS支持POST和GET请求,适应现代Web应用程序。
特点:
XSS暴力破解
XSS扫描
支持GET/ POST请求
自定义单词可以包含
人性化的UI
(仅供参考)
0×02修复与更新改进
因为原版中的BruteXss是英文版而且存在着一些小问题,所以我就尝试着进行汉化和改进:
原版英文界面:
汉化改进界面:
修复:
1、修复旧版中扫描错误网址异常退出的问题。
2、修复旧版本错误判断网址存活问题。
3、修复旧版本扫描XSS时卡死问题。
更新改进:
1、更新默认字典(约5800条语句,可以执行一个非常全面的并且绕过WAF的XSS检查)
2、减少替换部分代码,脚本运行更迅速。
0×03安装运行
(汉化改进版)BruteXSS下载:https://files.cnblogs.com/files/Pitcoft/Brutexss.zip
脚本需要以下条件方可正常执行:
Python 2.7 #在运行python 2.7的平台上,Windows , Linux 或者其他设备
python2.7下载地址:https://www.python.org/ftp/python/2.7.13/python-2.7.13.msi
0×04实战测试
检测一款脚本工具的好坏就是要用于实践当中~~所以下面我将会对一个有XSS漏洞的网站进行测试
目标站:https://www.xxxx.cn/search(因为没有事先得到网站管理员的允许,所以这里我没有公布网址)
00x1这个网站存在一个POST XSS 所以我这里提交一下参数,并用火狐插件Live Http headers抓包
00x2可以看到参数是word= 下面用汉化改进的Brutexss进行测试
运行后先会让你选择xss漏洞的类型(POST或GET)
00x2这里我们选择POST类型的,然后输入url以及post参数:
00x3按回车使用默认字典(注意:使用自定义字典需将字典放至运行目录下)
00x4等字典命令加载完,可以发现brutexss已经检测出xss漏洞了
是一个反射型的xss
文字汉化的时候编码很让人烦恼,编译不对出来直接乱码,最后是使用GBK才解决问题的。
最后我附上原英文版脚本的源码(仅供参考):
1 #!/usr/bin/env python 2 #!BruteXSS 3 #!Cross-Site Scripting Bruteforcer 4 #!Author: Shawar Khan 5 #!Site: [url=https://shawarkhan.com]https://shawarkhan.com[/url] 6 from string import whitespace 7 import httplib 8 import urllib 9 import socket 10 import urlparse 11 import os 12 import sys 13 import time 14 from colorama import init , Style, Back,Fore 15 import mechanize 16 import httplib 17 init() 18 banner = """ 19 ____ _ __ ______ ____ 20 | __ ) _ __ _ _| |_ ___ \ \/ / ___/ ___| 21 | _ \| '__| | | | __/ _ \ \ /\___ \___ \ 22 | |_) | | | |_| | || __/ / \ ___) |__) | 23 |____/|_| \__,_|\__\___| /_/\_\____/____/ 24 25 BruteXSS - Cross-Site Scripting BruteForcer 26 27 Author: Shawar Khan - [url=https://shawarkhan.com]https://shawarkhan.com[/url] 28 29 Sponsored & Supported by Netsparker Web Application Security Scanner ( [url=https://www.netsparker.com]https://www.netsparker.com[/url] ) 30 Note: Using incorrect payloads in the custom 31 wordlist may give you false positives so its 32 better to use the wordlist which is already 33 provided for positive results. 34 """ 35 def brutexss(): 36 if os.name == 'nt': 37 os.system('cls') 38 else: 39 os.system('clear') 40 print banner 41 def again(): 42 inp = raw_input("[?] [E]xit or launch [A]gain? (e/a)").lower() 43 if inp == 'a': 44 brutexss() 45 elif inp == 'e': 46 exit() 47 else: 48 print("[!] Incorrect option selected") 49 again() 50 grey = Style.DIM+Fore.WHITE 51 def wordlistimport(file,lst): 52 try: 53 with open(file,'r') as f: #Importing Payloads from specified wordlist. 54 print(Style.DIM+Fore.WHITE+"[+] Loading Payloads from specified wordlist..."+Style.RESET_ALL) 55 for line in f: 56 final = str(line.replace("\n","")) 57 lst.append(final) 58 except IOError: 59 print(Style.BRIGHT+Fore.RED+"[!] Wordlist not found!"+Style.RESET_ALL) 60 again() 61 def bg(p,status): 62 try: 63 b = "" 64 l = "" 65 lostatus = "" 66 num = [] 67 s = len(max(p, key=len)) #list 68 if s < 10: 69 s = 10 70 for i in range(len(p)): num.append(i) 71 maxval = str(len(num)) #number 72 for i in range(s) : b = b + "-" 73 for i in range(len(maxval)):l = l + "-" 74 statuslen = len(max(status, key=len)) 75 for i in range(statuslen) : lostatus = lostatus + "-" 76 if len(b) < 10 : 77 b = "----------" 78 if len(lostatus) < 14: 79 lostatus="--------------" 80 if len(l) < 2 : 81 l = "--" 82 los = statuslen 83 if los < 14: 84 los = 14 85 lenb=len(str(len(b))) 86 if lenb < 14: 87 lenb = 10 88 else: 89 lenb = 20 90 upb = ("+-%s-+-%s-+-%s-+")%(l,b,lostatus) 91 print(upb) 92 st0 = "Parameters" 93 st1 = "Status" 94 print("| Id | "+st0.center(s," ")+" | "+st1.center(los," ")+" |") 95 print(upb) 96 for n,i,d in zip(num,p,status): 97 string = (" %s | %s ")%(str(n),str(i)); 98 lofnum = str(n).center(int(len(l))," ") 99 lofstr = i.center(s," ") 100 lofst = d.center(los," ") 101 if "Not Vulnerable" in lofst: 102 lofst = Fore.GREEN+d.center(los," ")+Style.RESET_ALL 103 else: 104 lofst = Fore.RED+d.center(los," ")+Style.RESET_ALL 105 print("| "+lofnum+" | "+lofstr+" | "+lofst+" |") 106 print(upb) 107 return("") 108 except(ValueError): 109 print(Style.BRIGHT+Fore.RED+"[!] Uh oh! No parameters in URL!"+Style.RESET_ALL) 110 again() 111 def complete(p,r,c,d): 112 print("[+] Bruteforce Completed.") 113 if c == 0: 114 print("[+] Given parameters are "+Style.BRIGHT+Fore.GREEN+"not vulnerable"+Style.RESET_ALL+" to XSS.") 115 elif c ==1: 116 print("[+] %s Parameter is "+Style.BRIGHT+Fore.RED+"vulnerable"+Style.RESET_ALL+" to XSS.")%c 117 else: 118 print("[+] %s Parameters are "+Style.BRIGHT+Fore.RED+"vulnerable"+Style.RESET_ALL+" to XSS.")%c 119 print("[+] Scan Result for %s:")%d 120 print bg(p,r) 121 again() 122 def GET(): 123 try: 124 try: 125 grey = Style.DIM+Fore.WHITE 126 site = raw_input("[?] Enter [url=\n]URL:\n[/url][?] > ") #Taking URL 127 if 'https://' in site: 128 pass 129 elif 'http://' in site: 130 pass 131 else: 132 site = "[url=http://]http://"+site[/url] 133 finalurl = urlparse.urlparse(site) 134 urldata = urlparse.parse_qsl(finalurl.query) 135 domain0 = '{uri.scheme}://{uri.netloc}/'.format(uri=finalurl) 136 domain = domain0.replace("[url=https://]https://","").replace("http://","").replace("www.","").replace("/[/url]","") 137 print (Style.DIM+Fore.WHITE+"[+] Checking if "+domain+" is available..."+Style.RESET_ALL) 138 connection = httplib.HTTPConnection(domain) 139 connection.connect() 140 print("[+] "+Fore.GREEN+domain+" is available! Good!"+Style.RESET_ALL) 141 url = site 142 paraname = [] 143 paravalue = [] 144 wordlist = raw_input("[?] Enter location of Wordlist (Press Enter to use default wordlist.txt)\n[?] > ") 145 if len(wordlist) == 0: 146 wordlist = 'wordlist.txt' 147 print(grey+"[+] Using Default wordlist..."+Style.RESET_ALL) 148 else: 149 pass 150 payloads = [] 151 wordlistimport(wordlist,payloads) 152 lop = str(len(payloads)) 153 grey = Style.DIM+Fore.WHITE 154 print(Style.DIM+Fore.WHITE+"[+] "+lop+" Payloads loaded..."+Style.RESET_ALL) 155 print("[+] Bruteforce start:") 156 o = urlparse.urlparse(site) 157 parameters = urlparse.parse_qs(o.query,keep_blank_values=True) 158 path = urlparse.urlparse(site).scheme+"://"+urlparse.urlparse(site).netloc+urlparse.urlparse(site).path 159 for para in parameters: #Arranging parameters and values. 160 for i in parameters[para]: 161 paraname.append(para) 162 paravalue.append(i) 163 total = 0 164 c = 0 165 fpar = [] 166 fresult = [] 167 progress = 0 168 for pn, pv in zip(paraname,paravalue): #Scanning the parameter. 169 print(grey+"[+] Testing '"+pn+"' parameter..."+Style.RESET_ALL) 170 fpar.append(str(pn)) 171 for x in payloads: # 172 validate = x.translate(None, whitespace) 173 if validate == "": 174 progress = progress + 1 175 else: 176 sys.stdout.write("\r[+] %i / %s payloads injected..."% (progress,len(payloads))) 177 sys.stdout.flush() 178 progress = progress + 1 179 enc = urllib.quote_plus(x) 180 data = path+"?"+pn+"="+pv+enc 181 page = urllib.urlopen(data) 182 sourcecode = page.read() 183 if x in sourcecode: 184 print(Style.BRIGHT+Fore.RED+"\n[!]"+" XSS Vulnerability Found! \n"+Fore.RED+Style.BRIGHT+"[!]"+" Parameter:\t%s\n"+Fore.RED+Style.BRIGHT+"[!]"+" Payload:\t%s"+Style.RESET_ALL)%(pn,x) 185 fresult.append(" Vulnerable ") 186 c = 1 187 total = total+1 188 progress = progress + 1 189 break 190 else: 191 c = 0 192 if c == 0: 193 print(Style.BRIGHT+Fore.GREEN+"\n[+]"+Style.RESET_ALL+Style.DIM+Fore.WHITE+" '%s' parameter not vulnerable."+Style.RESET_ALL)%pn 194 fresult.append("Not Vulnerable") 195 progress = progress + 1 196 pass 197 progress = 0 198 complete(fpar,fresult,total,domain) 199 except(httplib.HTTPResponse, socket.error) as Exit: 200 print(Style.BRIGHT+Fore.RED+"[!] Site "+domain+" is offline!"+Style.RESET_ALL) 201 again() 202 except(KeyboardInterrupt) as Exit: 203 print("\nExit...") 204 def POST(): 205 try: 206 try: 207 try: 208 br = mechanize.Browser() 209 br.addheaders = [('User-agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11)Gecko/20071127 Firefox/2.0.0.11')] 210 br.set_handle_robots(False) 211 br.set_handle_refresh(False) 212 site = raw_input("[?] Enter [url=\n]URL:\n[/url][?] > ") #Taking URL 213 if 'https://' in site: 214 pass 215 elif 'http://' in site: 216 pass 217 else: 218 site = "[url=http://]http://"+site[/url] 219 finalurl = urlparse.urlparse(site) 220 urldata = urlparse.parse_qsl(finalurl.query) 221 domain0 = '{uri.scheme}://{uri.netloc}/'.format(uri=finalurl) 222 domain = domain0.replace("[url=https://]https://","").replace("http://","").replace("www.","").replace("/[/url]","") 223 print (Style.DIM+Fore.WHITE+"[+] Checking if "+domain+" is available..."+Style.RESET_ALL) 224 connection = httplib.HTTPConnection(domain) 225 connection.connect() 226 print("[+] "+Fore.GREEN+domain+" is available! Good!"+Style.RESET_ALL) 227 path = urlparse.urlparse(site).scheme+"://"+urlparse.urlparse(site).netloc+urlparse.urlparse(site).path 228 url = site 229 param = str(raw_input("[?] Enter post data: > ")) 230 wordlist = raw_input("[?] Enter location of Wordlist (Press Enter to use default wordlist.txt)\n[?] > ") 231 if len(wordlist) == 0: 232 wordlist = 'wordlist.txt' 233 print("[+] Using Default wordlist...") 234 else: 235 pass 236 payloads = [] 237 wordlistimport(wordlist,payloads) 238 lop = str(len(payloads)) 239 grey = Style.DIM+Fore.WHITE 240 print(Style.DIM+Fore.WHITE+"[+] "+lop+" Payloads loaded..."+Style.RESET_ALL) 241 print("[+] Bruteforce start:") 242 params = "[url=http://www.site.com/?]http://www.site.com/?"+param[/url] 243 finalurl = urlparse.urlparse(params) 244 urldata = urlparse.parse_qsl(finalurl.query) 245 o = urlparse.urlparse(params) 246 parameters = urlparse.parse_qs(o.query,keep_blank_values=True) 247 paraname = [] 248 paravalue = [] 249 for para in parameters: #Arranging parameters and values. 250 for i in parameters[para]: 251 paraname.append(para) 252 paravalue.append(i) 253 fpar = [] 254 fresult = [] 255 total = 0 256 progress = 0 257 pname1 = [] #parameter name 258 payload1 = [] 259 for pn, pv in zip(paraname,paravalue): #Scanning the parameter. 260 print(grey+"[+] Testing '"+pn+"' parameter..."+Style.RESET_ALL) 261 fpar.append(str(pn)) 262 for i in payloads: 263 validate = i.translate(None, whitespace) 264 if validate == "": 265 progress = progress + 1 266 else: 267 progress = progress + 1 268 sys.stdout.write("\r[+] %i / %s payloads injected..."% (progress,len(payloads))) 269 sys.stdout.flush() 270 pname1.append(pn) 271 payload1.append(str(i)) 272 d4rk = 0 273 for m in range(len(paraname)): 274 d = paraname[d4rk] 275 d1 = paravalue[d4rk] 276 tst= "".join(pname1) 277 tst1 = "".join(d) 278 if pn in d: 279 d4rk = d4rk + 1 280 else: 281 d4rk = d4rk +1 282 pname1.append(str(d)) 283 payload1.append(str(d1)) 284 data = urllib.urlencode(dict(zip(pname1,payload1))) 285 r = br.open(path, data) 286 sourcecode = r.read() 287 pname1 = [] 288 payload1 = [] 289 if i in sourcecode: 290 print(Style.BRIGHT+Fore.RED+"\n[!]"+" XSS Vulnerability Found! \n"+Fore.RED+Style.BRIGHT+"[!]"+" Parameter:\t%s\n"+Fore.RED+Style.BRIGHT+"[!]"+" Payload:\t%s"+Style.RESET_ALL)%(pn,i) 291 fresult.append(" Vulnerable ") 292 c = 1 293 total = total+1 294 progress = progress + 1 295 break 296 else: 297 c = 0 298 if c == 0: 299 print(Style.BRIGHT+Fore.GREEN+"\n[+]"+Style.RESET_ALL+Style.DIM+Fore.WHITE+" '%s' parameter not vulnerable."+Style.RESET_ALL)%pn 300 fresult.append("Not Vulnerable") 301 progress = progress + 1 302 pass 303 progress = 0 304 complete(fpar,fresult,total,domain) 305 except(httplib.HTTPResponse, socket.error) as Exit: 306 print(Style.BRIGHT+Fore.RED+"[!] Site "+domain+" is offline!"+Style.RESET_ALL) 307 again() 308 except(KeyboardInterrupt) as Exit: 309 print("\nExit...") 310 except (mechanize.HTTPError,mechanize.URLError) as e: 311 print(Style.BRIGHT+Fore.RED+"\n[!] HTTP ERROR! %s %s"+Style.RESET_ALL)%(e.code,e.reason) 312 try: 313 methodselect = raw_input("[?] Select method: [G]ET or [P]OST (G/P): ").lower() 314 if methodselect == 'g': 315 GET() 316 elif methodselect == 'p': 317 POST() 318 else: 319 print("[!] Incorrect method selected.") 320 again() 321 except(KeyboardInterrupt) as Exit: 322 print("\nExit...") 323 brutexss()
由于本人也是第一次汉化脚本,一些专业术语翻译稍有欠妥,所以如果有什么不足之处也请大家能够体谅
如果你也有好的意见和建议,可以通过博客联系我或者直接在下方评论
新年即将到来,在这里也祝大家新年快乐,天天开心!