批量运营CodeQL Cli扫描结果(简易版)
背景&目标
CodeQL Cli
适合批量做扫描,但是扫描结果并不适合直接做批量的运营,仅适合一些实锤的问题,对于一些还需要人工处理判断的结果就不太适合了(要看源码、调用上下文);如果使用VSCode
插件来做,也只是单条规则扫单个/多个数据库,结果倒是很友好,点点点就能读代码来分析了,所以这种用法不适合批量的query
扫描。
如果付费的话自然是可以解决了,可以在CI/CD
中集成,就方便多了 -。- 但是对于个人使用者来说不太现实,所以我就想用一个简单的办法来实现这个目的
CodeQL cli
批量扫描结束后,导入数据库+历史query
结果,直接在vscode
里运营结果,流程为:
1 | CI/CD 扫描 ---> 结果(数据库+扫描结果) ---> 导入VSCode运营 |
目标拆解
- 批量导入数据库,而不是通过
GUI
点点点导入 - 导入扫描结果,历史
query
不要清理,为的是把cli
的扫描结果导入对应目录之后可以直接在CodeQL
的query history
中看到
工作流程
批量导入数据库
查看日志,猜测是类似的做法,解析某个配置文件,然后导入,所以要么修改文件,要么直接把数据库目录copy
过去就行
1 | Initializing database manager. |
存储位置
1 | /** |
导出信息就能看到了,所以直接改数据库就能添加多个数据库了
/home/muhe/.config/Code/User/workspaceStorage/693bdf324f8bd69cec87e06d65e8d000/state.vscdb
1 | { |
尝试直接修改这个数据库 就可以批量导入了,不需要挨个点点点了 :)
导入扫描结果
query-history
扫描结果的导入是有个json文件描述的
1 | Reading query history |
我这里随意跑了两个Query,查看这个文件可以看到这两次记录:
1 | { |
所以把query结果按照这个格式填进去就行了。
配置文件中需要的CodeQL cli信息获取
1 | ❯ tree -L 1 . |
经过测试,运营只需要扫描结果就行,其他的可以忽略
- Evaluator Log 相关可以不要
- DIL 也可以不要,可以用于query调优啥的,我们只运营结果就不考虑了
FYI: 其他的文件(log、dil等)是为了下面菜单中展示的功能做的:
批量query & 导入结果分析
一般来说,我们会使用到开源的规则以及自己写的规则,如果有一定的积累的话,自己的规则可以搞成一个qlpack,方便后面对新目标的快速分析或者批量查找问题。
通用规则/开源规则
第一种情况,可以利用下面的命令,批量跑特定的规则集
1 | # muhe @ muhe-NUC11PAHi5 in ~/Tools/vscode-codeql-starter/ql/cpp/ql/src/codeql-suites on git:codeql-cli/latest o [18:53:36] |
比如我们尝试使用cpp-security-and-quality.qls
这个规则集跑老版本的XNU作为演示
1 | codeql database run-queries --ram=16384 --threads=12 XNU-revision-2018-October-28--14-31-48 --min-disk-free=1024 -v ~/Tools/vscode-codeql-starter/ql/cpp/ql/src/codeql-suites/cpp-security-and-quality.qls |
FYI: 可以使用 codeql resolve queries ~/Tools/vscode-codeql-starter/ql/cpp/ql/src/codeql-suites/cpp-security-and-quality.qls --format=text
获取这个规则集包含了哪些query
特有规则
第二种就使用规则仓库中PICO的pack就行,或者直接指定一个qls扫,就是类似的做法了,比如可以自己搞一个qlpack:
1 | codeql database run-queries --ram=16384 --threads=8 --min-disk-free=1024 -- [database] [qlpack] |
结果处理
对于这种跑query的方式,如果不指定输出,默认结果会放在数据库的 results
目录下,比如:
所以可以写个脚本
- 修改
state.vscdb
,批量把codeql db
导入 - 修改
query-history
文件,把扫描结果导入
最终效果
最终实现的效果如下 :)
FYI: 两个关键文件的路径不同平台下大同小异:
1 | if 'macOS' in current_platform: |