利用链寻找利器 CodeQL:如何精准定位二次反序列化漏洞
字数 1418 2025-08-30 06:50:35
CodeQL精准定位二次反序列化漏洞指南
一、CodeQL简介
CodeQL是由GitHub开发的静态代码分析工具,用于发现代码中的安全漏洞、缺陷和编码规范问题。主要特点包括:
- 多语言支持:支持Java、C/C++、Go、Python、Ruby、Node.js、PHP、Rust等多种编程语言
- 自动化分析:可自动分析代码库,无需人工干预
- 自定义规则:允许用户创建和共享自定义分析规则
- GitHub集成:可直接在GitHub代码仓库中运行分析
二、二次反序列化漏洞查找场景
利用场景
已知可以调用getter方法,需要查找可能触发二次反序列化的调用链。
分析思路
- 首先识别所有符合条件的getter方法
- 在这些getter方法中查找包含
readObject调用的方法 - 分析这些方法的调用链,确认是否存在二次反序列化漏洞
三、使用CodeQL查找getter方法
getter方法特征
根据Fastjson等反序列化库的逻辑,getter方法通常具有以下特征:
- 以"get"开头
- 第四个字母必须大写
- 无参数
- public访问权限
CodeQL查询实现
from Method m
where
m.getName().indexOf("get") = 0 and // 方法名以"get"开头
m.getName().length() > 3 and // 方法名长度大于3
m.isPublic() and // 公共方法
m.fromSource() and // 源代码中的方法
m.hasNoParameters() // 无参数方法
select m
查询条件解析:
getName().indexOf("get") = 0:检查方法名是否以"get"开头getName().length() > 3:确保方法名不只是"get"isPublic():检查方法是否为publicfromSource():确保是源代码中的方法hasNoParameters():检查方法是否无参数
四、识别二次反序列化逻辑
二次反序列化特征
在getter方法中,如果调用了readObject方法,则可能存在二次反序列化漏洞。例如:
SignedObject.getObject()RMIConnector.findRMIServerJRMP()
CodeQL查询实现
from MethodAccess access
where
access.getMethod().getName() = "readObject" and // 调用了readObject方法
access.getEnclosingCallable().getName().indexOf("get") = 0 // 调用位于getter方法中
select access
查询解析:
MethodAccess:表示方法调用getMethod():获取被调用的方法getEnclosingCallable():获取包含此调用的方法(父方法)- 组合条件查找getter方法中的
readObject调用
五、POC构造示例
示例分析
假设发现getContent方法中存在二次反序列化逻辑:
getContent方法位于父类Message中- 返回
ByteSequence对象 ByteSequence构造函数接受byte[]参数且为public
构造思路
- 控制
getContent方法的返回值 - 构造恶意的
ByteSequence对象 - 触发反序列化链
六、实际应用建议
- 结果验证:CodeQL查询结果需要人工验证,确认是否真正存在漏洞
- 上下文分析:检查getter方法的调用链是否可控
- 组合利用:结合其他漏洞利用技术(如Fastjson、Jackson等反序列化漏洞)
- 规则优化:可根据具体项目调整查询条件,提高精确度
七、进阶技巧
- 调用链追踪:使用CodeQL的
DataFlow库追踪数据流,确认参数是否可控 - 污点分析:标记不受信任的输入源,分析其传播路径
- 自定义规则:针对特定框架(如Fastjson)编写专用检测规则
- 结果排序:根据方法调用深度、参数可控性等因素对结果排序
通过以上方法,可以系统性地使用CodeQL定位潜在的二次反序列化漏洞,提高代码审计效率。