CodeQl Usage Tricks
前言
codeql大流行的时代,如何学会使用codeql变得由于重要。学习其中tricks,能够更好的方便进行代码审计工作。本文会从自动化build数据库,codeql的debug等角度帮助大家进一步了解codeql这款神器。
数据库build日志
build-tarcer.log
看CodeQL的database的日志,可以发现很多有用的信息。
文件build-tracer.log中
Loading extra JVM options from SEMMLE_JAVA_TOOL_OPTIONS instead of in-process variable.Passing through -javaagent:D:\codeql\codeql\java\tools/codeql-java-agent.jar=ignore-project,java to underlying JVM.
可以发现CodeQL应用了Java的agent技术,将codeql-java-agent.jar文件加载到构建程序中。
[T 11:42:48 19660] Passing through -Xbootclasspath/a:D:\codeql\codeql\java\tools/codeql-java-agent.jar to underlying JVM. [T 11:42:48 19660] Intercepted JVM creation with extra hidden args: ['-javaagent:D:\codeql\codeql\java\tools/codeql-java-agent.jar=ignore-project,java' '-Xbootclasspath/a:D:\codeql\codeql\java\tools/codeql-java-agent.jar'] (result: 1, 0).
通过codeql-java-agent.jar传递给底层JVM之后,使用CodeQL自带的Java.exe程序拦截带有额外隐藏参数的JVM,也就是codeql-java-agent.jar=ignore-project,java’ ‘-Xbootclasspath/a:D:\codeql\codeql\java\tools/codeql-java-agent.jar。
有兴趣可以继续看看jar里面的代码,本人还没有看出个所以然来,就不写具体的分析过程了。
CodeQL Action
可以说CodeQL使用最六的一批人肯定是CodeQL的官方,为了可以学习到CodeQL的隐藏技巧,学习其Action的使用变得非常有必要了。
使用GitHub官方的CodeQL Action分析Java应用时,如果使用了javafx,创建数据库时会失败的。解决办法在,最开始的时候就设置action环境,添加javafx。完整的代码参考codeql.yml
在执行分析ql查询,可以发现codeql的action使用一条命令就可以批量的进行ql查询, 不能发现关键在java-queries-builtin.qls
文件,但其实codeql的仓库里是没有这个文件的。
codeql database run-queries --ram=5923 --threads=2 /home/runner/work/_temp/codeql_databases/java --min-disk-free=1024 -v /home/runner/work/_temp/codeql_databases/java-queries-builtin.qls
询问GitHub官方人员之后,给出的答案是使用代码生成的文件。code link
const querySuitePath = `${databasePath}-queries-${type}.qls`;
fs.writeFileSync(querySuitePath, querySuiteContents);
但看完代码之后,我本地也没环境去调试,生成这段代码,事情就变得复杂了起来。回头我转身想想,这个文件在GitHub action中,肯定是可以使用upload artifact传出来。于是乎我在codeql.yml文件添加了几行就非常简单的获取到这个文件。
- name: Upload a Build Artifact
id: upload-build-artifact
uses: actions/[email protected]
with:
# Artifact name
name: # optional, default is artifact
java-queries-builtin.qls
# A file, directory or wildcard pattern that describes what to upload
path:
/home/runner/work/_temp/codeql_databases/java-queries-builtin.qls
# The desired behavior if no files are found using the provided path.
然后就可以在action执行完成之后,在Summary中下载到。比例本人在自己的SPATool仓库下载https://github.com/SummerSec/SPATool/suites/5809018842/artifacts/194366370
打开文件之后可以发现,codeql-action查询仓库是否存在漏洞都是使用了CWE目录下的ql文件,这些文件我们都是可以直接在codeql仓库获取到,我们只需要将文件的路径替换一下就可以本地绝对路径即可。
使用vscode的全部替换模式,.*0.0.9\/
- query: D:\codeql\vscode-codeql-starter\ql\java\ql\src\
,再将\/
替换成\
即可。
批量查询命令
codeql database run-queries --ram=5932 --threads=2 SPATool --min-disk-free=1024 -v java-queries-builtin.qls
导出查询的结果命令
codeql database interpret-results --threads=2 --format=sarif-latest -v --output=../results/java.sarif --no-sarif-add-snippets --print-diagnostics-summary --print-metrics-summary --sarif-group-rules-by-pack --sarif-add-query-help java-queries-builtin.qls
CodeQL debug
codeql-debug项目在很早之前,本人在很早之前就关注了。之前没太研究其作用,最近突然发现pwntester大佬也star该项目了,我变得重新重视其作用。研究之后发现其就是为了找到database中的所有的source和sink点,目的就是为了在使用ql查询之后没有找到任何的漏洞,我们可以使用这个项目肉眼人工的进行寻找漏洞。
使用自己的项目SPATool查询之后的效果如下:
如何集成到GitHub的action呢?
这个问题原作者其实已经解决了,但由于时间久远,原作者的项目一直没有更新,导致出现了一些问题。通过本地debug调试本人针对Java的部分ql规则进行改进解决问题,其主要诞生这些问题的所在均是codeql的库更新,原有的一些规则没了,更新到最新的规则即可。
本人已经将最新的Java部分的规则提交pr到原作者的项目,但截至写文章为止作者还没合并规则。建议使用我本人的项目SummerSec/codeql-debug,如果在本地使用的话需要改一下process.py文件。
在56行将dbpath
设置为需要查询数据库绝对路径,60行将codeql_executable
设置为codeql的执行文件的绝对路径。
将129注释掉,将qlf
变量设置为 dependencies.ql的绝对路径
运行设置参数第一个java 第二个和第三个由于设置成硬编码的方式,随便写就行。
集成到action就不需要改这些,在原本的action中添加这几行代码即可。完整的yml参考codeql-debug.yml
这里的action触发方式采用的是手动触发,手动触发之后在执行结束之后可以在Summary下载结果。比例说本人在SPATool项目执行结果Summary link
CodeQL with SCA
突然看到楼兰师傅写的CodeQL 结合Maven实现SCA文章,这里给出我的解决方案,这里记录一下。SCA Software Composition Analysis,软件成分分析,第三方组件安全检查。
import java
import semmle.code.java.DependencyCounts
predicate jarDependencyCount(int total, string entity) {
exists(JarFile targetJar, string jarStem |
jarStem = targetJar.getStem() and
jarStem != "rt"
|
total =
sum(RefType r, RefType dep, int num |
r.fromSource() and
not dep.fromSource() and
dep.getFile().getParentContainer*() = targetJar and
numDepends(r, dep, num)
|
num
) and
entity = jarStem
)
}
from string name, int ndeps
where jarDependencyCount(ndeps, name)
select name, ndeps order by ndeps desc
运行下面命令就会得到dependencies.bqrs
文件
codeql database run-queries --search-path --threads 0 --rerun {database_path} {dependencies.ql}
在运行下面命令就会得到下面图片内容,输出格式有多种方式可选。
codeql bqrs decode --no-titles --format text --output dependencies.txt dependencies.bqrs
tricks
First
这条命令也是在CodeQL的action中学到,可以发现在一个完整的环境中,我们可以使用这条命令直接获取到类似上面的java-queries-builtin.qls文件,毕竟直接给出了绝对路径。
codeql resolve queries java-code-scanning.qls --format=text
second
codeql批量查询的方式,其实除了将所有的ql的绝对路径写入qls文件中,可以使用下面这种方式,这种方式是在codeql-debug中学到的。
qls文件里面写ql所在的文件夹,可以是相对的路径也可以是绝对路径。然后仅仅只需要将ql文件放入文件夹下面即可,codeql会自动递归搜索并执行查询该文件夹下面的所有ql文件。
参考
https://github.com/zbazztian/codeql-debug