分析BruteXss来拓展python工具开发思路
Posted 合天智汇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分析BruteXss来拓展python工具开发思路相关的知识,希望对你有一定的参考价值。
原创投稿详情:
用工具特点、工具结构、工具主文件各类函数几个维度去分析前人的优秀工具可以拓展自己的开发思路。通过整体分析我们可以学习到前人优秀的开发思想(分层、分模块)和了解工具出色的结构,在以后的开发中安全可以借鉴他们的开发思想和结构这样可以缩短我们开发的周期而且可以让工具更加稳定。
在寻找工具之前一定要明确自己打算写哪方面的工具,等你明确了需求之后你可以去借助百度、谷歌等在线搜索引擎,那么我建议最好去github上面寻找。
那我这里提供一个github上开源扫描器集合的链接:https://github.com/We5ter/Scanners-Box/blob/master/README_CN.md
在github上开源扫描器集合中我找了一款XSS扫描工具,那么多类别不选为啥要选XSS呢?那是因为近些年来XSS漏洞数量急剧上升,它的出现严重危害到网站的整体安全,作为安全人员XSS使我们无法逃避的一个名词,我们能做的只有尽快了解它并且征服它,这样才能更好维护网络安全。所以为了让大家了解XSS的攻击原理我这里打算带大家分析一款XSS扫描工具BruteXSS。
(https://github.com/shawarkhanethicalhacker/BruteXSS)
阅读说明文档我们可以简单了解工具的依赖环境,运行命令以及工具架构等。
a明确工具用途
Description:
BruteXSSis a very powerful and fast Cross-Site Scripting Brutforcer which isused for bruteforcing a parameters. The BruteXSS injects multiplepayloads loaded from a specified wordlist and fires them at thespecified parameters and scans if any of the parameter is vulnerableto XSS vulnerability. BruteXSS is very accurate at doing its task andthere is no chance of false positive as the scanning is muchpowerful. BruteXSS supports POST and GET requests which makes itcompatible with the modern web applications.
BruteXSS是一款能快速爆破XSS的工具。BruteXSS注入从指定的单词列表加载的多个有效载荷,并在指定的参数下触发它们,并扫描参数是否有任何参数容易受到XSS漏洞的影响。BruteXSS在执行任务时非常准确,因为扫描功能非常强大,所以不存在误报的可能性。BruteXSS支持POST和GET请求,使其与现代Web应用程序兼容。
b运行环境分析
Compatibility:
Windows, Linux or any device running python 2.7
分析得知其工具可以运行在各种系统上,但是python的版本要求是2.7
c依赖
Requirements:
Python2.7
Wordlistincluded(wordlist.txt)
Modulesrequired: Colorama, Mechanize
分析得知依赖环境是python2.7,存放payload的文件wordlist.txt,python依赖库有Colorama,Mechanize。那么后面我们肯定要安装python2.7,然后安装对应的依赖库Colorama,Mechanize。
d工具特点
Features:(特点)
XSSBruteforcing(XSS暴力破解)
XSSScanning(xss扫描)
SupportsGET/POST requests(支持get/post请求)
Customwordlist can be included(自定义单词可以包含)
User-friendlyUI(人性化UI)
分析得知它有快速扫描,支持GET/POST请求,可自定义payload文件等特点。我们分析工具的特点是为了了解它工具的优点,然后思考自己能否在其基础上打造出属于自己工具的特点。
e工具用法
Usage(GETMethod):
COMMAND: python brutexss.py
METHOD: g
URL: http://www.site.com/?parameter=value
WORDLIST:wordlist.txt
Usage(POSTmethod):
COMMAND: python brutexss.py
METHOD: p
URL: http://www.site.com/file.php
POSTDATA: parameter=value¶meter1=value1
WORDLIST: wordlist.txt
你按"g"就是使用GET方法,而使用"p"就是使用POST方法。简单使用之后可以得知这个工具时使用交互式而非我们平时见到的参数式。这样更人性化,但是不好的地方就是有可能需要使用者多次选择。所以我建议大家在工具用法的时候最好使用参数式而非交互式,当然如何你的交互只有一次那可以考虑使用交互式。
a分析结构
colorama 用于存放调用windowapi的py文件
mechanize存放工具运行的依赖库
brutexss.py主文件
License.txt证书文件
README.md说明文档
wordlist.txt存放payload的文件
最好是使用图来表示,这样看起来更容易理解。
从图可以清晰看到工具的整体结构,这里我有一个很不喜欢的地方,就是文件夹的命名不规范,命名的英文一定要见文知意,大概是作者随意写的。在这里提醒一点自己的文件或者文件夹命名一定要规范,这样别人看起来才不会那么费劲,不能说自己随意写。但是这个工具的结构还是值得借鉴的例如:独立文件夹存放依赖库,独立文件夹存放调用windowapi的文件。这个以后自己在编写工具的时候也可以参考一下这种分层思想。
b分析主文件
我把从上往下把函数抽出来给大家分析一下。
again函数用于判断用户是否再一次使用工具爆破,否则退出。
defagain():
inp= raw_input("[?][E]xit or launch [A]gain? (e/a)").lower()
#获取用户输入值 然后进行判断
ifinp == 'a':
brutexss()
elifinp == 'e':
#退出
exit()
else:
print("[!]Incorrect option selected")
again()
wordlistimport函数非常重要,是用于读取文件(wordlist.txt)然后导入payload的一个函数。我们以后可以借用其代码,稍微修改一下即可,这样可以减少我们的代码编写量,缩短开发时间。补充一点:wordlist.txt中的payload可以实现自定义,你只需要把你自定义的payload添加到wordlist.txt即可。
defwordlistimport(file,lst):
try:
#打开文件
withopen(file,'r')asf: #ImportingPayloads from specified wordlist.
print(Style.DIM+Fore.WHITE+"[+]Loading Payloads from specified wordlist..."+Style.RESET_ALL)
#循环遍历获取
forline inf:
final= str(line.replace("\n",""))
lst.append(final)
exceptIOError:
#异常处理
print(Style.BRIGHT+Fore.RED+"[!]Wordlist not found!"+Style.RESET_ALL)
again()
bg函数这个函数不重要,只是一个判断结果进行输出的函数,bg函数接收complete函数传来的结果值传入zip函数将元素打包成一个个元组,然后返回由这些元组组成的列表,紧接着进行循环判断,最后输出格式化后的扫描结果,出现异常时候打印Uhoh! No parameters in URL。
defbg(p,status):
try:
b= ""
l= ""
lostatus= ""
num= []
s= len(max(p,key=len))#list
ifs < 10:
s= 10
fori inrange(len(p)):num.append(i)
maxval= str(len(num))#number
fori inrange(s): b = b + "-"
fori inrange(len(maxval)):l= l + "-"
statuslen= len(max(status,key=len))
fori inrange(statuslen): lostatus = lostatus + "-"
iflen(b)< 10:
b= "----------"
iflen(lostatus)< 14:
lostatus="--------------"
iflen(l)< 2:
l= "--"
los= statuslen
iflos < 14:
los= 14
lenb=len(str(len(b)))
iflenb < 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)
forn,i,d inzip(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"NotVulnerable"inlofst:
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()
complete函数判断GET或者POST传来的结果值然后判断c(其实就是传过来的total对应的值)的值,如果c等于0打印结果”[+]Given parameters are not vulnerabl XSS.”(不存在XSS)。如果c不等于0紧接着判断其值是否等于1打印结果”[+]%s Parameter is vulnerable to XSS”.(存在XSS),如果c不等于0也不等于1的话打印”[+]%s Parameters are vulnerable to XSS”然后调用bg函数最后调用again函数进行重复一次扫描。
defcomplete(p,r,c,d):
print("[+]Bruteforce Completed.")
ifc == 0:
print("[+]Given parameters are "+Style.BRIGHT+Fore.GREEN+"notvulnerable"+Style.RESET_ALL+"to XSS.")
elifc ==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
printbg(p,r)
again()
defGET():
try:
try:
grey= Style.DIM+Fore.WHITE
site= raw_input("[?]Enter URL:\n[?] > ")#TakingURL
if'https://'insite:
pass
elif'http://'insite:
pass
else:
site= "http://"+site
#切割url将url分为6个部分,返回一个包含6个字符串项目的元组:协议、位置、路径、参数、查询、片段。
finalurl= urlparse.urlparse(site)
#返回列表
urldata= urlparse.parse_qsl(finalurl.query)
#拼接目标domain
domain0= '{uri.scheme}://{uri.netloc}/'.format(uri=finalurl)
domain=domain0.replace("https://","").replace("http://","").replace("www.","").replace("/","")
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 defaultwordlist.txt)\n[?] > ")
#这里是准备拼接payload到我们的目标上
iflen(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
forpara inparameters: #Arrangingparameters and values.
#循环添加进列表
fori inparameters[para]:
paraname.append(para)
paravalue.append(i)
total= 0
c= 0
fpar= []
fresult= []
progress= 0
#zip 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。 forpn, pv inzip(paraname,paravalue):#Scanningthe parameter.
print(grey+"[+]Testing '"+pn+"'parameter..."+Style.RESET_ALL)
fpar.append(str(pn))
forx inpayloads:
validate= x.translate(None,whitespace)
ifvalidate == "":
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()
ifx insourcecode:
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
ifc == 0:
print(Style.BRIGHT+Fore.GREEN+"\n[+]"+Style.RESET_ALL+Style.DIM+Fore.WHITE+"'%s' parameter not vulnerable."+Style.RESET_ALL)%pn
fresult.append("NotVulnerable")
progress= progress + 1
pass
progress= 0
#打印结果
complete(fpar,fresult,total,domain)
except(httplib.HTTPResponse,socket.error) asExit:
print(Style.BRIGHT+Fore.RED+"[!]Site "+domain+"is offline!"+Style.RESET_ALL)
again()
except(KeyboardInterrupt)asExit:
print("\nExit...")
本文讲了如何寻找优秀开源工具、阅读说明文档、以及具体如何分析工具。分析工具的时候首先要明确自己的需求是什么,例如我们想要研究XSS的,我们就得去找和XSS有关的工具进行分析,然后阅读文档是一个必须养成的习惯,因为只有通读文档我们才能更好了解工具的用途、运行环境、依赖以及工具特点等。最后才是对工具结构和主文件进行分析,在这个功能要耐下心来看代码,如果遇到不懂可以先行思考思考过后还是不懂的话可以考虑百度进行求解,反正分析工具要本着一个独立思考、耐心分析的原则。对于工具分析我给大家多去看别人的分析思路然后过后自己多去尝试独立分析。
看不过瘾?合天2017年度干货精华请点击《》
明天又是一年一度的高考啦!
还记得当初你高考的场景吗?
以上是关于分析BruteXss来拓展python工具开发思路的主要内容,如果未能解决你的问题,请参考以下文章