文章目录
1. 环境
下载以下资源:
- 命令行工具(主程序):https://github.com/github/codeql-cli-binaries;
- 官方提供的库和查询语句:https://github.com/github/codeql;
- VS Code 插件CodeQL,并配置好codeql目录。
其它资源可按需下载:
- 单独的Go库:https://github.com/github/codeql-go
注意库和查询语句(codeql)这个目录和codeql.exe是同级关系, 我按照文档的例子放在了codeql-repo里:
>ls -l
...
drwxrwx---+ 1 starr None 0 Apr 13 11:28 codeql-repo
-rwxrwx---+ 1 starr None 204656 Mar 11 15:54 codeql.exe
...
执行codeql resolve languages
可以查看当前支持哪些语言。
2. CodeQL for VS Code
vsc工作空间
- 下载官方提供的vsc工作空间:vscode-codeql-starter;
- 根据工作空间的README指示,下载 官方提供的qll库到工作空间的ql,Go语言需要单独下载。
codeql-custom-queries-<language>
目录用来存放要执行的ql查询脚本,每种语言的目录下都要有qlpack.yml,指定依赖的qll。
以后要分析的数据库,都扔到这里面就可以了。
单元测试
CodeQL插件会连带下载testing插件,测试目标是工作空间里以-tests
结尾的文件夹。
设置里的Running Queries: Debug开关可以启用日志,分析性能。
CodeQL packs
About CodeQL packs — CodeQL (github.com)
CodeQL packs contain queries, library files, query suites, and metadata.
两种CodeQL packs:
- query packs,用来运行;
- library packs,用来被query packs调用。
Ctrl+shift+p, 可以install下载依赖,或者download下载别人的packs。
3. CodeQL CLI
参考自CodeQL CLI文档。
3.1 Using the CodeQL CLI
数据库
文档分解释型和编译型两种语言来讲解。
解释性语言需要指定源码目录(–source-root);
编译型语言需要我们指定编译命令(–command),也可以不指定而是依赖autobuilder 。
也可以从LGTM获取一些开源项目的CodeQL数据库。
CodeQL使用extractor来从源码提取信息,存入数据库。创建数据库时有两个参数用来自定义extractor:
--extractor-option
--extractor-options-file
至于分析,一般用vscode就可以了,如果要导出报告(比如sarifv2.1.0格式)的话可以学一下这套命令:
codeql database analyze ...
Query suite
可以理解为批处理,保存为.qls后缀文件。
测试
刚刚说过,以-tests
结尾的文件夹是用来测试的,它其实也属于QL pack,里面除了qlpack.yml,还有两部分:
- query-tests 目录,里面有很多qlref文件指定了要测试的ql;
- library-tests 目录,顾名思义,保存了一些库文件。
3.2 CodeQL CLI reference
QL packs
文档把CodeQL packs和QL Packs分开了,但两者应该没有多大区别:
CodeQL packs contain queries, library files, query suites, and metadata.
QL Packs: QL packs are used to organize the files used in CodeQL analysis. They contain queries, library files, query suites, and important metadata.
每种语言都有4个QL Pack:
ql/<language>/ql/lib
ql/<language>/ql/src
ql/<language>/ql/test
ql/<language>/upgrades
4. 语法
4.1 CodeQL queries
语法结构:
/**
*
* Query metadata
*
*/
import /* ... CodeQL libraries or modules ... */
/* ... Optional, define CodeQL classes and predicates ... */
from /* ... variable declarations ... */
where /* ... logical formula ... */
select /* ... expressions ... */
一些好习惯
- .ql开头写metadata,比如官方课程里的@kind path-problem;
- 给每个.ql配一个.qhelp帮助文件, 有点像html文件,可参考仓库文档;
- select输出信息要易读;
- 提供location信息;
- predicate里每个变量都做一下限制;
- 不确定类型时使用getAQlClass(),但最终版别用;
- 不要递归;
- Fold predicates(参考文档)。
建议给ql文件配上
Creating path queries,如何用特定模板输出数据流路径。
Path queries
这得开个专题。
4.2 QL tutorials
QL tutorials — CodeQL (github.com)
这里提供了4个游戏,有时间再玩吧。
5. Guides
这一章对各个语言进行了讲解。
6. Reference
Formulas
Quantified formulas, 用来引入临时变量,exists, forall, forex
。
…
7. Demo
测试环境:Ubuntu 18.04
测试工程:tinyhttpd 0.1.0
把Makefile里的-lsocket
去掉,在tinyhttpd目录下创建codeql数据库:
codeql database create ./tinyhttpd_codeql_db --language=cpp -c "make -f Makefile"
可以用vscode远程打开tinyhttpd_codeql_db目录,也可以用以下命令将目录打包后拷回windows的vscode-codeql-starter工作空间研究:
$ codeql database bundle -o tinyhttpd_codeql_db.zip tinyhttpd_codeql_db/
Creating bundle metadata for /home/starr/Documents/CProject/tinyhttpd-0.1.0/tinyhttpd_codeql_db...
Creating zip file at /home/starr/Documents/CProject/tinyhttpd-0.1.0/tinyhttpd_codeql_db.zip.
用vscode打开工作空间
执行命令CodeQL: Install Pack Dependencies
,安装cpp这个codeql pack的依赖。
新建一个tinyhttpd.ql:
import cpp # 来自codeql库
from FunctionCall fc
select fc.getTarget().getQualifiedName(), fc
右键,CodeQL: Run Query。
于是获取了所有的函数调用信息。
8. 参考资料
CodeQL U-Boot Challenge (C/C++) | GitHub Learning Lab
CodeQL documentation (github.com)
QL language reference — CodeQL (github.com)
CodeQL standard libraries (github.com)
Get Involved | GitHub Security Lab
Capture the flag | GitHub Security Lab
C/C++源码扫描系列- codeql 篇 - 先知社区 (aliyun.com)
利用CodeQL分析并挖掘Log4j漏洞 - 先知社区 (aliyun.com)