wafw00f的介绍这不是本文的重点。相信大家已经了解了相关的介绍和使用方法,所以这里直接引用其开发者对该工具的介绍。为了发挥其魔力,WAFW00F执行以下操作:发送正常的HTTP请求并分析响应;这确定了许多WAF解决方案。通过发送一个正常的HTTP请求,分析其返回包,判断是否使用WAF,如果使用,确认WAF类型,如果不成功,则发送若干(潜在恶意)HTTP请求,并使用简单推断它是哪个WAF的逻辑。如果无法通过正常的HTTP请求结果分析是否使用WAF及其类型,则构造恶意请求,通过简单的逻辑重新判断。如果这也不成功,它会分析之前返回的响应,并使用另一种简单的算法来猜测WAF或安全解决方案是否正在积极响应我们的攻击。如果这也不成功,它会分析之前返回的响应,并使用另一种简单的算法来猜测WAF或安全解决方案是否在主动响应我们的攻击使用场景/方法。这不是本文的重点。如果你想了解更多关于它的用法,去它的github主页就是https://github.com/EnableSecurity/wafw00f。上面已经详细描述了该工具的功能。总结起来很简单:检测目标中是否存在WAF。也可以说wafw00f是一个用于指纹识别的Web应用防火墙(WAF)工具。使用方法并不难,这里就不介绍了。想深入了解可以看:WEB防火墙检测工具--wafw00f教程-将军的个人博客wafw00f日志、输出、展示等功能不在我们的分析范围内,但是WAF的检测逻辑,发送流量的特征,以及WAF识别的指纹将是分析的重点。过程:分析源码含义,分析特征,抓包,观察源码文件结构。为了方便大家后面看源码,这里简单说明一下源码的组成。如果没有说明,用处不大。你可以自己看看。其中Markingimportant是这个工具的主要功能文件,后面会讲解。binlibasciiarts.pyevillib.py用于与目标建立连接并发起请求(重要)plugins用于确定每个WAF的指纹(重要)aliyundun.py阿里云盾特征值匹配文件huaweicloud.py****华为云特征值匹配文件baidu.py百度云加速的特征匹配文件...特征文件很多,自己去看看__init__.pymain.py这个工具主要的检测判断功能实现在此文件(重要)manager.py在插件中加载WAF指纹并确定文件以识别目标WAF类型。wafprio.py以上非重要文件,大多服务于输出选项、连接等文件/功能的功能,所以不做特别介绍。基本流程请求流程并不复杂。和开头介绍的流程完全一样:发送一个普通的HTTP请求,判断是否有WAF。如果存在,则根据指纹判断其类型。然后附加恶意请求尝试启动WAF并分析其类型。最后,所谓算法猜测,流量特征不明显,不在本次分析范围内,实际用处不大。请求运行过程(重要)以第一次正常HTTP请求检测为例(其他同理)。由于本人对Python了解不多,scope的表达方式采用C++中的::(如有错误请指出,会及时修改)。main.py分析的完整源码这里就不放了。大家可以随时去它的github主页获取。这里可以直接分析关键部分。从上面的流程可以看出,所有的请求都是从类WAFW00F发起的。所以这个类是我们分析的重中之重!请求的具体实现(比如请求中携带什么内容)会在evillib.py文件的分析中分析。这里主要分析应该在什么时候发出什么样的请求。从main()函数开始看它的逻辑:(解析参数等函数直接跳过)不指定其余参数对输入的URL做相关处理,然后放入target传给WAFW00Fforprocessingattacker=WAFW00F(target,debuglevel=options.verbose,path=path,followredirect=options.followredirect,extraheaders=extraheaders,proxies=proxies)#如果请求没有结果,说明请求有问题targetwebsiteorlocalnetworkifattacker.rqisNone:log.error('Site%sappearstobedown'%hostname)continue由于第一次是常规检测,如果这里匹配到WAF的指纹,那么即可完成输出。具体输出逻辑不是重点,略过;如果无法分析出是否存在WAF或者与WAF不匹配,则使用identwaf()函数拼凑恶意参数进行检测;waf=attacker.identwaf(options.findall)log.info('IdentifiedWAF:%s'%waf)enteridentwaf()函数后,会尝试匹配每个WAF的特征;defidentwaf(self,findall=False):detected=list()try:self.attackres=self.performCheck(self.centralAttack)exceptRequestBlocked:returndetectedforwafvendorinself.checklist:self.log.info('检查%s'%wafvendor)ifself.wafdetections[wafvendor](self):detected.append(wafvendor)ifnotfindall:breakself.knowledge['wafname']=detectedreturndetected这是分析的基本过程。如果WAF还没有确定,它会进入一个自己提供的算法,但这不是我们在分析流量特性时要注意的,就不展开讨论了。激动人心的时刻来了,在WAFW00F类中是如何实现的呢?classWAFW00F一上来就中奖了:classWAFW00F(waftoolsengine):xsstring=''sqlisting="UNIONSELECTALLFROMinformation_schemaAND'orSLEEP(5)或'"lfistring='../../../../etc/passwd'rcestring='/bin/cat/etc/passwd;平127.0.0.1;curlgoogle.com'xxestring=']>&hack;'WAFW00F由此构造拼接的恶意代码tool都列在开头,绝对没有变化,构造恶意请求就是选择以上五个字符串中的一个或多个直接使用。可以看出判断是否存在WAF的语句有以下五类:5)or'遍历类../../../../etc/passwd命令执行/拼接类/bin/cat/etc/passwd;平127.0.0.1;curlgoogle.comXXEclass]>&hack;那么有了这几句,如何拼接WAFW00F呢?defnormalRequest(self):返回self.Request()defcustomRequest(self,headers=None):返回self.Request(headers=headers)defnonExistent(self):返回self.Request(path=self.path+str(random.randrange(100,999))+'.html')defxssAttack(self):返回self.Request(path=self.path,params={'s':self.xsstring})defxxeAttack(self):返回self.Request(path=self.path,params={'s':self.xxestring})deflfiAttack(self):returnself.Request(path=self.path+self.lfistring)defcentralAttack(self):返回self.Request(path=self.path,params={'a':self.xsstring,'b':self.qlisting,'c':self.llisting})defsqliAttack(self):returnself.Request(path=self.path,params={'s':self.qlisting})defoscAttack(self):返回自我.Request(path=self.path,params={'s':self.rcesstring})具体逻辑不难理解,说几个:defxssAttack(self)defxssAttack(self):returnself。Request(path=self.path,params={'s':self.xsstring})例如,举个简单的例子:我们传给wafw00f的URL是:http://127.0.0.1:9000,然后通过参数拼接后的request为:http://127.0.0.1:9000/?s=(URL编码前)。2:defcentralAttack(self):defcentralAttack(self):returnself.Request(path=self.path,params={'a':self.xsstring,'b':self.qlisting,'c':self.lfistring})例如,举个简单的例子:我们传给wafw00f的URL是:http://127.0.0.1:9000,拼接这个参数后的请求是:http://127.0.0.1:9000/?s=&b=UNIONSELECTALLFROMinformation_schemaAND'orSLEEP(5)or'&c=../../../../etc/passwd(URL编码之前)从前面的流程可以看出,defidentwaf(self,findall=False):中调用的拼接语句的方法就是这个方法,拼接成三个语句,其他逻辑相同。上面的evillib.py分析只是构造了上层拼接哪些参数。事实上,正是在这个文件中,将请求组合成一个完整的HTTP消息,并调用了requests.get()。如果标题未在wafw00f中由--headers指定,它将使用其默认--headers。默认标头在此文件中定义。def_headers={'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3','Accept-Encoding':'gzip,deflate','Accept-Language':'en-US,en;q=0.9','DNT':'1',#DoNotTrack请求标头'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/78.0.3770.100Safari/537.36','Upgrade-Insecure-Requests':'1'#}默认情况下,接下通过requests.get()请求时方便会使用该头部,defRequest(self,headers=None,path=None,params={},delay=0,timeout=7):try:time.睡眠(延迟)如果不是标题:h=self.headers其他:h=headersreq=requests.get(self.target,proxies=self.proxies,headers=h,timeout=timeout,allow_redirects=self.allowredir,params=params,verify=False)self.log.info('请求成功')self.log.debug('Headers:%s\\n'%req.headers)self.log.debug('Content:%s\\n'%req.content)self.requestnumber+=1returnreqexceptrequests.exceptions.RequestExceptionase:self.log.error('Somethingwentwrong%s'%(e.__str__()))指纹识别以华为云WAF的指纹为例#!/usr/bin/envpython'''Copyright(C)2022,WAFW00FDevelopers.SeetheLICENSEfileforcopyingpermission.'''NAME='HuaweiCloudFirewall(Huawei)'defis_waf(self):schemes=[#matchcookieself.matchCookie(r'^HWWAFSESID='),#匹配header中的Serverself.matchHeader(('Server',r'HuaweiCloudWAF')),#匹配bodyself.matchContent(r'hwclouds\\.com'),self.matchContent(r'hws_security@')]ifany(iforiinschemes):returnTruereturnFalseCSDN使用华为云保护其他脚本,参见:wafw00f/wafw00f/pluginsatmaster·EnableSecurity/wafw00fwafw00ftrafficFreeBuf.CO米