尝试CodeQL自动化分析2025 SUCTF SU_Solon
J1rrY WEB安全 850浏览 · 2025-02-15 09:36

本篇文章尝试通过CodeQL对触发JDBC的可能解进行探究,也是初学CodeQL进行练手的一道题目 SU_Solon

这是一道非常明确的Hession反序列化的题目

什么是Hession反序列化

Hessian是一个轻量级的remoting onhttp工具,是一个轻量级的Java序列化/反序列化框架,使用简单的方法提供了RMI的功能。 相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。

RPC协议的一次远程通信过程如下

客户端发起请求,并按照RPC协议格式填充信息

填充完毕后将二进制格式文件转化为流,通过传输协议进行传输

服务端接收到流后,将其转换为二进制格式文件,并按照RPC协议格式获取请求的信息并进行处理

处理完毕后将结果按照RPC协议格式写入二进制格式文件中并返回 Hession反序列化是基于Field机制的反序列化是通过特殊的native(方法或反射(最后也是使用了native方式)直接对Field进行赋值操作的机制,而不是通过getter、setter方式对属性赋值

序列化实现

Hession反序列化和原生反序列化的区别

最显著的区别在于Hession反序列化过程中所需要的类可以不实现反序列化接口,这往往扩展了我们的视角

一句化概括就是 hessian 序列化对象不用实现Serializable接口 也就是我们编写QL语句时其实不用刻意考虑其实现 instanceof TypeSerializable

但是值得注意的是Hession反序列化同时也存在相应的限制 (请参考su18师傅的博客:https://su18.org/post/hessian/)

kick-off chain 起始方法只能为 hashCode/equals/compareTo 方法;

利用链中调用的成员变量不能为 transient 修饰;

所有的调用不依赖类中 readObject 的逻辑,也不依赖 getter/setter 的逻辑 这几个限制也导致了很多 Java 原生反序列化利用链在 Hessian 中无法使用,甚至 ysoserial 中一些明明是 hashCode/equals/compareTo 触发的链子都不能直接拿来用

触发toString

图片加载失败


这道题直接就触发了任意类的toString方法作为入口点

图片加载失败
可以注意到本身依赖包含了fastjson 1.2.83h2数据库 而fastjson最常见在原生反序列化的利用点就是Fastjson的原生链其中JSONArray/JSONObject类的toString方法可以转化成触发任意类的getter方法

而H2数据的JDBC打法最常见的就是通过H2数据库进行初始化时执行一段SQL脚本实现RCE

这里初始化指定poc.sql执行

可以实现执行任意命令达到RCE的效果

触发任意类的getter实现JDBC连接(编写QL语句)

现在我们的问题转换成了 getter方法如何去触发JDBC链接 一般而言触发JDBC时通过

实现发起一个JDBC链接 这里我们有两种实现方案 全局污点分析TaintTracking2构造查询谓词 相对而言构建查询谓词的方法比较简单 这里我们直接通过构建查询谓词的方式实现 数据流的传递 没有对数据流实现过滤

我们可以通过其getASupertype*()递归超类实现一个覆盖式的寻找 保证结果的全面性 直接通过虚构查询静态调用目标和动态调度目标 这里我更加偏向通过实现Method作为查询子集 Callable 父类是 Method (普通的方法)和 Constructor (类的构造方法) 其实用Callable方法也是可以的

图片加载失败
发现有14种查询结果(这里感谢一下F10wers13eiCheng师傅通过trap导入实现构造数据库的方式 太酷了)

UnpooledDataSource

网上大师傅们的文章都是通过UnpooledDataSourcegetConnection方法实现触发JDBC链接
图片加载失败


实现了getter到JDBC的转换 也就是我们查询结果的第13个
图片加载失败
本地起一个http服务器放我们的恶意sql文件

python -m http.server 8888
图片加载失败


但是应该注意这里存在 SecurityManager 限制

图片加载失败


在网上搜搜就有答案 直接关闭SecurityManager就可以了

图片加载失败


System.setSecurityManager(null);

生成反序列化对象

图片加载失败
直接就可以实现弹出计算器

JdbcDataSource

除此之外我们可以尝试寻找其他的触发点
图片加载失败
这里我们以JdbcDataSource验证我们通过CodeQL找到的对不对

图片加载失败
图片加载失败
这里是可以触发到JDBC连接的 但是非常遗憾的是在Hession反序列化过程中 org.h2.jdbcx.JdbcDataSource 在其中的黑名单中
图片加载失败
黑名单列表

导致我们不能直接利用 JdbcDataSource建立连接
图片加载失败
org.h2.jdbcx全限定类名前缀被过滤了

因此我们重新编写一下QL语句

我们接着筛选

图片加载失败


DataSourceWrapper

这就是个包装类 本质上是触发任意实现DataSource的接口的getConnection()方法
图片加载失败


是可以包装 UnpooledDataSource/JdbcDataSource但是和直接触发UnpooledDataSource/JdbcDataSourcegetConnection没有本质区别
图片加载失败


DataSourceProxy

和DataSourceWrapper效果一致

尝试触发UnixPrintService的getter实现执行任意命令

参考:https://y4tacker.github.io/2022/03/21/year/2022/3/2022%E8%99%8E%E7%AC%A6CTF-Java%E9%83%A8%E5%88%86/ 作为JDK低版本 肯定优先考虑一下UnixPrintService触发getter实现命令注入
图片加载失败
但是还是在sofa-hession黑名单中 不考虑

总结

这里我们尝试通过编写CodeQL实现快速寻找到我们所期望的hession调用链,对于黑名单没有覆盖的类进行了一个简单的探索

1 条评论
某人
表情
可输入 255
Paxsizy
2025-08-07 02:56 0 回复
请问一下师傅,本题的jar包是否要反编译成java文件,再把依赖都拉进去,一起构建成codeql数据库