背景描述
一、概述
CodeQL根据扫描结果中的Source构造出入口URL,并标记漏洞参数,然后通过中转程序转发到黑盒扫描工具进行二次验证,用来增加扫描结果的可信度,不同等级的可信度做不同的处理,针对高可信的漏洞可以自动进入漏洞运营的环节。
如下以CodeQL与黑盒扫描器XRay为例,简单描述一下整个过程。
二、逻辑流程
三、代码示例
1、CodeQL构造Source的访问URL
在CodeQL中根据source所在位置构造出入口URL
组装参数部分
1、String类型的参数,直接拼接到URL里面;
2、DTO类型的参数,跟进并获取所有的字段,拼接到url里面。
独立运行时示例如下
2、入口程序运行CodeQL查询
如下,根据传入的CodeQL数据库跟QL文件,运行CodeQL查询,然后提取查询结果
3、中转程序构造请求包发送到XRay
在中转程序中可以组装出完整的URL,并装载Cookie的信息,发送HTTP请求到XRay
proxies = {"http":"http://127.0.0.1:7777",
"https":"https://127.0.0.1:7777"}
requests.get(url, headers=headers, cookies=cookies, proxies=proxies)
4、XRay黑盒扫描并发送到webhook
xray_windows_amd64.exe webscan --listen 127.0.0.1:7777 --plugins xss --webhook-output http://127.0.0.1:5000/webhook
5、webhook示例
如下以在控制台中打印自定义的漏洞信息为例。
from flask import Flask, request
import requests
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def xray_webhook():
if 'vuln_class' not in vuln:
return 'ok'
data = request.json['data']['detail']
url = data['addr']
param = data['extra']['param']['key']
payload = data['payload']
print('\n受影响URL\n{}\n受影响参数\n{}={}\n'.format(url, param, payload))
return 'ok'
if __name__ == '__main__':
app.run()
6、最终的输出
四、测试结果
测试了多个项目,并从以下维度进行分析。
本文更关注CodeQL,因此此处假设黑盒不存在误报,而且一般来说只要不是太垃圾的黑盒扫描器,只要请求包到位了误报还是极少的。
是否有漏洞 | CodeQL认为 | 黑盒认为 | 是否出现过此情景 | 原因 |
---|---|---|---|---|
真有 | 有漏洞 | 有漏洞 | 是 | 正向结果 |
有漏洞 | 没有漏洞 | 是 | CodeQL 最后一步参数构造的问题,某些参数的值必须属于某个数值集合,否则代码流程中断,较难优化 | |
没有漏洞 | 有漏洞 | 是 | CodeQL Source覆盖不全,优化难度一般 | |
没有漏洞 | 没有漏洞 | 否 | 黑盒不存在误报 | |
真没有 | 有漏洞 | 有漏洞 | 否 | 黑盒不存在误报 |
有漏洞 | 没有漏洞 | 是 | CodeQL Sanitizer覆盖不全,某些情况下可以接受,优化难度一般 | |
没有漏洞 | 有漏洞 | 否 | 黑盒不存在误报 | |
没有漏洞 | 没有漏洞 | 是 | 正向结果 |
若是仅仅依赖白盒扫描器的话,我们可以把规则写细致一点,宁缺毋滥,提高准确率,降低人工成本,但是可能会牺牲覆盖率。
若是同时使用黑盒扫描器的话,我们可以把规则放宽一点,牺牲准确率,提高覆盖率,但是可能会牺牲准确率,可以自行选择是否需要人工校验非高可信的事件。
仁者见仁,公司的环境不同最佳方案就不同。
五、概括一下
CodeQL的扫描结果通过中转脚本发送给黑盒扫描器,例如XRay,
若CodeQL产生的告警,同时在黑盒扫描器中扫描出漏洞,则可以将这个事件定义的可信程度定义为:高;
若CodeQL产生的告警,在黑盒扫描器中未扫描出漏洞,则可以将这个事件定义的可信程度定义为:中。
高可信的事件,直接发送到漏洞运营平台生成漏洞工单,其他的事件,记录在漏洞运营系统的白盒扫描模块,等待安全工程师二次确认。
在黑盒扫描器环节最好还是自研,因为在这个流程中关键参数已经被标记了,无需再尝试所有的参数,而XRay无法限定待扫描的参数,所以会发送更多的请求包。