笔者是个基层的"安全研究员",poc 编写算是我最基础的日常工作。本文描述的是我所构思的一款漏洞验证框架以及具体实现。
谈谈漏洞验证框架的构思与实现(一)
0x01 写在前面
笔者是个基层的"安全研究员",poc 编写算是我最基础的日常工作。
每当有新漏洞细节披露后,对于安全领域的工作者来说,通常会经过这样的一个的”漏洞应急声明周期“:
漏洞复现 ---->原理分析 ----> poc 编写 ----> 靶机验证 ----> 大规模目标扫描
poc 完成后,通常有多种使用场景,或是快速刷洞(时间就是money),或是赋能到公司商业化产品(工作价值)。因此要有一套标准化的 poc 框架,否则会浪费很多时间研究同一个 poc 的N种语言实现。
0x02 需求
基于以上分析,笔者认为一款优秀的漏洞验证框架应该具备以下基础功能:
- 跨平台
- 可视化
- 支持高并发
- 资源(cpu / 内存)占用小
- 对于框架 poc 维护来说,应该具备:
- poc 格式标准化,具备统一的 poc 定义规范和解析 SDK
- 不应该限制只能使用某种特定语言编写
- poc 构建过程尽可能简单,能不写代码就不写代码
- poc 易读,最好能可视化。
在经过对多种流行的 poc 框架对比后发现,需要编写 python 脚本来维护 poc 的框架通常摆脱不了 python 自身的性能问题,而且不方便规则可视化,维护困难。长亭的 xray 以及 ywolf 师傅的 kunpeng,使用 yaml / json 定义 poc 是个不错的选择。经过对比发现 xray 的poc 体系更为完善,更能经得起时间的推敲,但无奈 xray 并不开源,即使维护 poc ,也无法给 poc 调用方提供 SDK。
因此,我决定自己实现一个poc框架。主要实现 poc管理、poc 编辑、编写过程中的靶机验证、大规模目标批量检测等等都通过前端配置就能搞定,希望帮助安全研究员们集中精力专注于 poc 的原理分析和逻辑实现,避免浪费大量时间在编写代码上。
由于篇幅的原因,本文内容为分享整个框架的设计思路,具体模块代码实现将于后续逐一分享。
0x02 框架构思
框架主要分为两个主要模块:poc可视化编辑和测试、和大规模目标检测。
具体可以细分为:poc运行、poc 管理、并发引擎、任务管理四大模块。
2-1 poc 运行
是整个框架的核心:
- 定义 poc 的规则体系
- 运行 poc:解析 poc 规则,并根据 poc 规则对原始请求变形,然后获取变形后的响应,再检查响应是否匹配规则中定义的表达式
- 支持自定义条件加载并运行特定的 poc
2-2 poc 管理
主要提供:
- poc 规则的可视化编辑:增、删、改、查
- 配置靶机实时对当前编辑的 poc 规则进行验证
- 关联漏洞描述:方便 poc 维护人员一眼就能看出该 poc 用于检测哪个漏洞
2-3 并发引擎
大规模目标扫描检测的核心。主要提供:
- 扫描任务调度
- 并发控制
- 速率控制
- 资源控制:避免无节制的占用主机资源(内存/cpu/带宽)
- 日志:记录检测过程中所有里程碑日志、错误日志、网络请求、响应,方便后续的回溯。
2-4 任务管理
- 任务列表(任务状态、任务下发时间、任务完成时间)
- 扫描结果展示
0x03 部分技术栈
本节主要分享框架开发过程中用到的技术框架,具体代码实现将于后续文章详细分享。
3-1 开发语言
要支持跨平台,同时追求高效、资源占用小,而且对 xray 使用的 google-cel 表达式兼容性好,毫无疑问使用 go 语言开发,web server 选择 gin 框架。
3-2 高并发
go 语言中有一个比多线程更加好用的并发模型——goroutine。追求极致效率可以使用 ants 复用 goroutine,降低不断创建 goroutine 的开销。
3-3 内存复用
面向web的 poc 框架占用的内存资源绝大多数来源于开辟请求
和响应
。目前常见的 poc 框架并发都是在同时运行多少个poc
这个维度上控制的。那么这里就会产生几个问题:
- 单纯控制 poc 并发,在每个 poc 内部是面向过程的。在一个 poc 结束之前,这个 poc 所占用的资源不会被立即释放,造成资源浪费。例如:一个 poc 通常会发多个请求,而且要对每个请求的响应进行解析。每一个请求和响应在使用之后都进行初始化,下一个请求/响应复用这块内存,是不是就降低了内存开销。
- 单纯控制 poc 并发,占用资源的总量是无法预估的,容易造成崩溃。
- 还有,我们知道,发送一个请求是很快的,而解析该请求的响应所用的开销要多的多。实际上解析响应时,已经不再需要request对象了,这里也会有一个资源浪费。
go 语言中有一个神奇的对象池 sync.Pool
。神奇的地方在于,一开始这个池子会初始化一些对象供你使用,如果不够了呢,自己会通过new产生一些,当你放回去了之后这些对象会被别人进行复用。
因此,如果我们把使用频率高的对象,如请求、响应、响应的解析等对象,开辟对象池 sync.Pool
进行管理,可以大大的减少对象的创建和回收的时间,极大的优化内存使用。
3-4 规则存储
xray 使用 yaml 文件定义和保存 poc。但我使用了数据库来存储 yaml。主要有以下几个原因:
- 支持 poc 内容的快捷搜索
- poc 和漏洞描述能通过外键关联
- 可以通过筛选条件加载某一类 poc
- 可以任意添加poc的字段类型,比如是否启用,创建时间,创建人等等
- 数据库维护和扫描引擎个分离部署
- 可以做到热加载
3-5 可视化
基于 go 语言的可视化技术的选型,流行的有以下两种方案:
我使用的是B/S架构开发。前后端分离项目可单独部署,也可使用go-bindata打包部署。
0x04总结
本文描述的是我所构思的一款漏洞验证框架,https://github.com/jweny/pocassist
想了解具体实现的师傅可以先自行研究下源码,我也会在后续文档逐一分析具体的实现细节。
如果文章内有描述不清或其他问题,烦请各位师傅斧正。
- 本文作者: jweny
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/160
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!