poc实例
本次编写指南将拿一个实际的漏洞(CVE-2021-43798)来举例,讲解如何将其变为高质量POC
视频教程(Video)
环境搭建(Environment)
准备docker
为了方便环境的复现,我们一般选择使用docker来搭建环境。 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化。可以理解成一个准备好环境的虚拟机。 Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,可以使用 YML 文件来配置应用程序需要的所有服务。然后使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
- ubuntu20.04 + docker-compose
- 本地搭建好ubuntu的环境,或者直接在阿里云上开一个机器
- 执行如下命令安装:
apt-get update && apt-get install docker-compose -y && docker help
- 执行完成后应该就可以看到docker的help
找漏洞所对应版本的环境(Vulnerability environment)
- 在知道漏洞编号的情况下,可以选择前往NVD去查看CPE来了解到影响版本:CVE-2021-43798
- 在知道版本后,可以去: Docker Hub 查找是否有对应版本。
- 前往Docker Hub后,首先可以搜索该漏洞编号,也就是CVE-2021-43798查看是否有人已经搭建了对应的环境,如果有是最方便的,可以直接拉取环境进行复现,如果没有,再找对应的版本拉取搭建。
- 或者还可以前往vulhub,vulfocus等看是否有对应的靶场,如果有也可以直接搭建启动测试
- vulhub:
- vulfocus:
搭建环境准备测试(Built Environment)
为了方便长时间的测试,我将使用vulhub所提供的靶场进行搭建。
在搭建好docker-compose后,执行
然后就可以查看到启动的端口,这个时候要注意,如果是使用云服务器搭建的话,请前往控制台将对应端口开放,否则无法对该端口进行访问。 同时,记得及时关闭靶场环境,不要给坏人可乘之机。
-
现在访问对应IP+端口即可看到Grafana的登录界面
漏洞复现(Reappear)
从NVD的对于该漏洞的描述部分可以看到对应的exp的网站,或者直接在baidu,bing,github等直接搜索该漏洞编号,也可以找到对应的复现文章。
此处将直接使用vulhub的描述来进行测试
可以看到只要对搭建好的环境进行如下内容的发包,即可看到etc/passwd
的内容
编写POC
通过上述规则,我们可以很容易的转换成一个yaml的poc:
其中在匹配/etc/passwd
的时候,我们可以使用正则匹配的方式对读取到的文件进行匹配,也是为了防止某些系统的passwd文件并不是x,而是直接显示真实的加密后的密码的情况。
优化POC
优化一(Optimisation One)
但通过对复现文章仔细的分析会发现,该漏洞的路径/public/plugins/alertlist/..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc/passwd
中,alertlist
是可以被替换的,如果目标没有安装这个插件,那么将会出现这种情况:
所以这个时候,我们的POC就应该包括多个插件的访问。 通过对该漏洞的信息收集,我们可以发现,grafana初始安装的插件为40个,也就是说我们可以写40个规则,然后通过‘或’的逻辑对这40个规则进行连接,只要命中其中一个规则,则证明漏洞存在。
优化二(Optimisation Two)
通过搜索我们可以知道,grafana可以安装在linux上,也可以安装在windows上,而对于windows,并没有/etc/passwd
给我们读取,所以我们需要添加上针对windows的情况,windows我们可以读取:c:/windows/win.ini
,我们可以匹配:for 16-bit app support
优化三(Optimisation Three)
就目前的POC来看,基本已经覆盖了绝大多数的情况,这个时候我们可以考虑一下发包的问题。首先此处需要确认一个原则:
- 也就是说我们不需要将产品指纹相关的内容放置到poc中作为check规则,这些内容应该交给专门的工具,比如xapp去实现,这样解耦,工具之间才能更灵活的调度,也不会出现发包过多的问题
- 而像
存在某个路径/文件,这个漏洞才存在
这种情况,去写一个check规则来降低发包量是完全合理的。
对于这个漏洞来说,没有什么明显的特征,所以优化为下述内容即可,注意添加了response.body_string.contains(“xxxxx”),用来指代一些其他的特征,以防止误报。
Was this page helpful?