这不是聊聊流量本次的重点,相关介绍及使用方法相信大家已经了解 ,码及所以此处就直接引用其开发者对该工具的特征介绍 。

To do 聊聊流量its magic, WAFW00F does the following:
Sends a normal HTTP request and analyses the response; this identifies a number of WAF solutions.通过发送正常的HTTP请求并且分析其返回包,判断其是码及否使用 WAF ,若使用确认WAF类型If that is 特征not successful, it sends a number of (potentially malicious) HTTP requests and uses simple logic to deduce which WAF it is.若是无法通过正常的HTTP请求结果分析出是否使用WAF以及其类型 ,则构造恶意的聊聊流量请求通过简单的逻辑再次进行判断If that is also not successful, it analyses the responses previously returned and uses another simple algorithm to guess if a WAF or security solution is actively responding to our attacks.如果这也不成功,免费模板它会分析之前返回的码及响应,并使用另一种简单的特征算法来猜测WAF或安全解决方案是否正在积极响应我们的攻击使用场景/方法这不是本次的重点,想要具体了解其用法去其github主页即可
https://github.com/EnableSecurity/wafw00f
本工具的聊聊流量作用上面已经很详细的描述出来了 ,概括一下很简单:探测目标是码及否存在WAF,也可以说wafw00f是特征一个Web应用防火墙(WAF)指纹识别的工具 。云计算
使用方法不难 ,聊聊流量此处不做介绍,码及若想进一步了解见:WEB 防火墙探测工具 -- wafw00f 使用教程 - General 的特征个人博客
wafw00f 源码解析所谓源码解析并不会完整分析其源码中的所有功能 ,比如 日志、输出 、展示 等功能不在我们分析的范围内,而其对 WAF 的检测逻辑 、所发流量的特征 、WAF 识别的指纹等将是重点要分析的高防服务器地方。
流程 :
解析源码含义,分析特征抓包观察源码文件结构为了方便大家之后去看源码,此处简单描述一下源码的组成,其中没有描述的说明其用不大 ,大家自己去看就知道了,其中标注important是本工具的主要功能文件 ,后续将重点说明。

asciiarts.py
evillib.py用于向目标建立连接发起请求( important )
plugins用于判断各个WAF的指纹 ( important )aliyundun.py阿里云盾的特征值匹配文件
huaweicloud.py****华为云的特征值匹配文件
baidu.py百度云加速的服务器租用特征匹配文件
……
还有很多特征文件大家自己去看就好
__init__.pymain.py该工具主要的检测、判断功能的类与函数都在该文件中实现( important )manager.py加载plugins中的WAF指纹判断文件识别目标WAF类型wafprio.py上述非important的文件起到的作用多是一些起到 输出选项、连接 等功能的文件/函数,所以不做特殊介绍
基本流程请求的流程并不复杂,和最开始介绍处的流程如出一辙:
发送正常HTTP请求,并判断是否存在WAF若存在根据指纹判断其类型若正常HTTP检测不出WAF,源码库则附加恶意的请求尝试出发WAF并分析其类型最后所谓的根据算法猜测 ,流量特征不明显 ,不在此次分析的范围内,实际用处也不大 。
请求运行流程( important)以第一次的正常HTTP请求探测为例(其余的都一致)。

由于对 Python 并不是太了解 ,所以作用域的表示采用了C++中的::(若是不对请及时指出会做更改)。模板下载
main.py分析完整的源码就不放在这占地方了 ,大家随时可到其github主页获取,此处直接分析其重点部分
由上述流程可以看出 ,所有的请求均是从class WAFW00F中发起,所以该类就是我们分析的重中之重!
请求的具体实现(比如请求中携带了哪些内容)将在分析evillib.py文件是分析 ,此处主要分析何时要发出何种请求 。
从main()函数出发看其逻辑:(解析参数等功能将直接略过)
没有指定其余参数
对输入的URL做相关处理后放到target中传入WAFW00F进行处理复制attacker = WAFW00F(target, debuglevel=options.verbose, path=path,followredirect=options.followredirect, extraheaders=extraheaders,proxies=proxies)
# 若请求没有结果则说明目标网站或本地网络有问题
if attacker.rq is None:
log.error(Site %s appears to be down % hostname)
continue1.2.3.4.5.6. 由于第一次做的是常规探测 ,若此处就匹配到了WAF的指纹则输出结束即可 ,具体的输出等逻辑不是重点,略过;若无法分析出其是否存在WAF或匹配不出WAF则通过identwaf()函数进步拼凑恶意参数进行探测; 复制waf = attacker.identwaf(options.findall)log.info(Identified WAF: %s % waf)1.2. 进入identwaf()函数后 ,便会尝试匹配各个WAF的特征; 复制def identwaf(self, findall=False): detected = list() try: self.attackres = self.performCheck(self.centralAttack) except RequestBlocked:return detected
for wafvendor in self.checklist: self.log.info(Checking for %s % wafvendor) if self.wafdetections[wafvendor](self): detected.append(wafvendor) if not findall:break
self.knowledge[wafname] =detected
return detected1.2.3.4.5.6.7.8.9.10.11.12.13.14.这就是基本的流程。
解析来如果还没有确定出WAF便会进入其自己提供的一个算法,但这并不是我们对流量特征分析所要关注的地方,所以就不探讨了。
下面到了激动人心的时刻 ,WAFW00F类中到底是如何实现的呢 ?
class WAFW00F
一上来就中了大奖 :
复制class WAFW00F(waftoolsengine): xsstring = <script>alert("XSS");</script> sqlistring = "UNION SELECT ALL FROM information_schema AND or SLEEP(5) or " lfistring = ../../../../etc/passwd rcestring = /bin/cat /etc/passwd; ping 127.0.0.1; curl google.com xxestring = <!ENTITY xxe SYSTEM "file:///etc/shadow">]><pwn>&hack;</pwn>1.2.3.4.5.6.7.WAFW00F这个工具所要构造拼接的恶意代码在一开始就全部列出了,而且在之后的使用中绝无变化,要构造恶意的请求就是从上述5个字符串中选择1个或多个直接使用。
可以看到改用据用于判断是否存在WAF的语句就以下五类 :
XSS类 <script>alert("XSS");</script>SQL注入类 UNION SELECT ALL FROM information_schema AND or SLEEP(5) or 遍历类 ../../../../etc/passwd命令执行/拼接类 /bin/cat /etc/passwd; ping 127.0.0.1; curl google.comXXE类 <!ENTITY xxe SYSTEM "file:///etc/shadow">]><pwn>&hack;</pwn>那么有了这些语句,WAFW00F又该如何拼接呢 ?
复制def normalRequest(self): return self.Request()def customRequest(self, headers=None): return self.Request(headers=headers)def nonExistent(self): return self.Request(path=self.path + str(random.randrange(100, 999)) + .html)def xssAttack(self): return self.Request(path=self.path, params= { s: self.xsstring})def xxeAttack(self): return self.Request(path=self.path, params= { s: self.xxestring})def lfiAttack(self): return self.Request(path=self.path + self.lfistring)def centralAttack(self): return self.Request(path=self.path, params={ a: self.xsstring, b: self.sqlistring, c: self.lfistring})def sqliAttack(self): return self.Request(path=self.path, params= { s: self.sqlistring})def oscAttack(self): return self.Request(path=self.path, params= { s: self.rcestring})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.具体逻辑并不难理解,拿出几种几个来说一下。
1:def xssAttack(self)
复制def xssAttack(self): return self.Request(path=self.path, params= { s: self.xsstring})1.2.例如给一个简单的例子:我们传给wafw00f的URL为:http://127.0.0.1:9000则经过该参数拼接后的请求就为 :
http://127.0.0.1:9000/?s=<script>alert("XSS");</script>(URL编码前 ) 。
2 :def centralAttack(self):
复制def centralAttack(self): return self.Request(path=self.path, params={ a: self.xsstring, b: self.sqlistring, c: self.lfistring})1.2.例如给一个简单的例子 :我们传给wafw00f的URL为:http://127.0.0.1:9000则经过该参数拼接后的请求就为 :
http://127.0.0.1:9000/?s=<script>alert("XSS");</script>&b=UNION SELECT ALL FROM information_schema AND or SLEEP(5) or &c=../../../../etc/passwd(URL编码前 )
从前面的流程可以看出,在def identwaf(self, findall=False):中调用的拼接的语句的方法就是本方法 ,拼接进三个语句 ,
其他的逻辑相同 。
evillib.py分析
上面只是在上层对要拼接哪些参数进行构造 ,实际上组合成完整的 HTTP 报文调用requests.get()进行请求的是在该文件中。
wafw00f中若没有通过—headers指定头部的话 ,会使用自己默认的—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, # Do NotTrack request header
User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3770.100 Safari/537.36, Upgrade-Insecure-Requests: 1#
}1.2.3.4.5.6.7.默认情况下,接下来通过requests.get()请求时便会使用该头部,
复制def Request(self, headers=None, path=None, params={ }, delay=0, timeout=7): try: time.sleep(delay) if not headers: h = self.headers else: h =headers
req = requests.get(self.target, proxies=self.proxies, headers=h, timeout=timeout, allow_redirects=self.allowredir, params=params, verify=False) self.log.info(Request Succeeded) self.log.debug(Headers: %s\\n % req.headers) self.log.debug(Content: %s\\n % req.content) self.requestnumber += 1return req
except requests.exceptions.RequestException as e: self.log.error(Something went wrong %s % (e.__str__()))1.2.3.4.5.6.7.8.9.10.11.12.13.14.15. 指纹的识别拿Huawei Cloud WAF的指纹来说
复制#!/usr/bin/env python
Copyright (C) 2022, WAFW00F Developers.See the LICENSE file for copying permission.NAME = Huawei Cloud Firewall (Huawei)def is_waf(self): schemes = [# 匹配 cookie
self.matchCookie(r^HWWAFSESID=),# 匹配 header 中的 Server
self.matchHeader((Server, rHuaweiCloudWAF)),# 匹配 body
self.matchContent(rhwclouds\\.com), self.matchContent(rhws_security@) ] if any(i for i in schemes): return True return False1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.CSDN使用华为云防护

其余脚本见:wafw00f/wafw00f/plugins at master · EnableSecurity/wafw00f
wafw00f 流量

本文作者:Deutsh, 转载请注明来自FreeBuf.COM
顶: 9321踩: 1486
评论专区