0x01 前言
在上一篇文章中,我们已经了解了关于CodeQL的基本语法,从实际案例角度来体验了CodeQL在代码审计中的作用。从这篇文章开始,我们将开始真正打造基于CodeQL的自动化代码审计工具,由于这仅仅是来自于个人兴趣的研究,并非来自成熟项目,所以在文章中可能缺陷,各位大佬如果有更好的意见建议,请私信。
CodeQL的代码审计整体过程可以分成两个部分,如图1.1所示,分别是从源代码解析成CodeQL数据库和从数据库中查询出安全隐患。本次分享主要关注第二阶段的内容,假设我们已经有了CodeQL数据库之后,下一步基于数据库的自动化查询。

图1.1 CodeQL代码审计过程阶段
为什么我们最终结果得到的是安全隐患,而不是漏洞呢?这是因为CodeQL并不是万能的,它只能帮我们找到可能的安全隐患,而不能一定确认漏洞存在,这在后面的文章中会说到原因。
当前的自动化代码审计工具将采用python3开发,针对的目标语言是java,后续如果有时间,也会陆续支撑其他语言。目前代码还不是特别完善,后期后继续对代码进行优化,见github地址:
https://github.com/webraybtl/codeql
0x02 工具设计
基于CodeQL的自动化代码审计工具流程其实和传统的漏洞扫描工具相似,所以我们还是按照传统漏扫的思路来设计工具。关于第一阶段源码转化为数据库的部分在下一篇文章来详述,这里还是只关注第二阶段数据库查询的内容,如图2.1所示。

图2.1 自动化工具设计流程
其实从流程中可以看出,工具的主要功能是基于ql插件的遍历,对插件结果的格式化输出。首先需要解决的问题是关于ql插件来源的问题,在上一篇文章中,我们有提到CodeQL官方给我们提供了很多测试用的demo实例
https://github.com/github/codeql/tree/main/java/ql/src/experimental/Security/CWE。
官方按照CWE提供了多个不同类型的ql插件,部分插件是可以直接来用的,但是有的插件涉及到自定义qll库,需要进行一定的转化才能使用,如图2.2所以,FilePathInjection.ql脚本就是典型的有自定义库的脚本。

图2.2 使用了qll自定义库的ql脚本
在我们设计的自动化工具中,为了方便会只查询单个ql脚本,需要把ql脚本中调用的qll库进行转化。转化的方式是显示的把qll库中定义的类和谓词直接定义到ql脚本中,我已经把官方提供的全部脚本都转化了一遍,后续会将完整的代码分享到github。
为了方便统一的对结果进行格式化输出,我们期待每一个ql文件最终返回的结果都是统一格式,所以还需要对每个ql文件最终的返回结果进行约束,典型的demo如下所示。其中select后面的值是ql脚本最终返回的数据。
from DataFlow::PathNode source, DataFlow::PathNode sink, BeanShellInjectionConfig confwhere conf.hasFlowPath(source, sink)select source.toString(),source.getNode().getEnclosingCallable(),source.getNode().getEnclosingCallable().getFile().getAbsolutePath(),

最低0.47元/天 解锁文章
1920

被折叠的 条评论
为什么被折叠?



