背景描述

因为

一、概述

CodeQL根据扫描结果中的Source构造出入口URL,并标记漏洞参数,然后通过中转程序转发到黑盒扫描工具进行二次验证,用来增加扫描结果的可信度,不同等级的可信度做不同的处理,针对高可信的漏洞可以自动进入漏洞运营的环节。

如下以CodeQL与黑盒扫描器XRay为例,简单描述一下整个过程。

二、逻辑流程

image.png

三、代码示例

1、CodeQL构造Source的访问URL

在CodeQL中根据source所在位置构造出入口URL
image.png
组装参数部分
1、String类型的参数,直接拼接到URL里面;
2、DTO类型的参数,跟进并获取所有的字段,拼接到url里面。
image.png
独立运行时示例如下
image.png

2、入口程序运行CodeQL查询

如下,根据传入的CodeQL数据库跟QL文件,运行CodeQL查询,然后提取查询结果
image.png

3、中转程序构造请求包发送到XRay

在中转程序中可以组装出完整的URL,并装载Cookie的信息,发送HTTP请求到XRay

  1. proxies = {"http":"http://127.0.0.1:7777",
  2. "https":"https://127.0.0.1:7777"}
  3. requests.get(url, headers=headers, cookies=cookies, proxies=proxies)

4、XRay黑盒扫描并发送到webhook

  1. xray_windows_amd64.exe webscan --listen 127.0.0.1:7777 --plugins xss --webhook-output http://127.0.0.1:5000/webhook

会以POST方式JSON格式发送漏洞信息,示例如下
image.png

5、webhook示例

如下以在控制台中打印自定义的漏洞信息为例。

  1. from flask import Flask, request
  2. import requests
  3. app = Flask(__name__)
  4. @app.route('/webhook', methods=['POST'])
  5. def xray_webhook():
  6. if 'vuln_class' not in vuln:
  7. return 'ok'
  8. data = request.json['data']['detail']
  9. url = data['addr']
  10. param = data['extra']['param']['key']
  11. payload = data['payload']
  12. print('\n受影响URL\n{}\n受影响参数\n{}={}\n'.format(url, param, payload))
  13. return 'ok'
  14. if __name__ == '__main__':
  15. app.run()

运行程序,默认监听5000端口
image.png

6、最终的输出

image.png

四、测试结果

测试了多个项目,并从以下维度进行分析。
本文更关注CodeQL,因此此处假设黑盒不存在误报,而且一般来说只要不是太垃圾的黑盒扫描器,只要请求包到位了误报还是极少的。

是否有漏洞 CodeQL认为 黑盒认为 是否出现过此情景 原因
真有 有漏洞 有漏洞 是 正向结果
有漏洞 没有漏洞 是 CodeQL 最后一步参数构造的问题,某些参数的值必须属于某个数值集合,否则代码流程中断,较难优化
没有漏洞 有漏洞 是 CodeQL Source覆盖不全,优化难度一般
没有漏洞 没有漏洞 否 黑盒不存在误报
真没有 有漏洞 有漏洞 否 黑盒不存在误报
有漏洞 没有漏洞 是 CodeQL Sanitizer覆盖不全,某些情况下可以接受,优化难度一般
没有漏洞 有漏洞 否 黑盒不存在误报
没有漏洞 没有漏洞 是 正向结果

若是仅仅依赖白盒扫描器的话,我们可以把规则写细致一点,宁缺毋滥,提高准确率,降低人工成本,但是可能会牺牲覆盖率。
若是同时使用黑盒扫描器的话,我们可以把规则放宽一点,牺牲准确率,提高覆盖率,但是可能会牺牲准确率,可以自行选择是否需要人工校验非高可信的事件。

仁者见仁,公司的环境不同最佳方案就不同。

image.png

五、概括一下

CodeQL的扫描结果通过中转脚本发送给黑盒扫描器,例如XRay,
若CodeQL产生的告警,同时在黑盒扫描器中扫描出漏洞,则可以将这个事件定义的可信程度定义为:高;
若CodeQL产生的告警,在黑盒扫描器中未扫描出漏洞,则可以将这个事件定义的可信程度定义为:中。

高可信的事件,直接发送到漏洞运营平台生成漏洞工单,其他的事件,记录在漏洞运营系统的白盒扫描模块,等待安全工程师二次确认。

在黑盒扫描器环节最好还是自研,因为在这个流程中关键参数已经被标记了,无需再尝试所有的参数,而XRay无法限定待扫描的参数,所以会发送更多的请求包。