从WMCTF2023_ez_java_again开始的RMIConnector二次反序列化学习
字数 1312 2025-08-29 22:41:24

RMIConnector二次反序列化技术分析与实战

环境搭建

  1. 使用CTF复现计划提供的Docker环境:
    docker run -it -d -p 12345:8080 -e FLAG=flag{8382843b-d3e8-72fc-6625-ba5269953b23} lxxxin/wmctf2023_ezjavaagainrev
    
  2. 访问12345端口即可启动环境

漏洞分析

初始发现

  1. 通过抓包发现url参数,源代码中存在url1参数(已标记为废弃但有安全问题)
  2. 利用url1参数进行文件读取:
    /Imagefile?url1=file:///usr/local/tomcat/webapps/ROOT/WEB-INF/classes/com/ctf/help_me/%23java
    

反序列化过滤机制

过滤规则位于/WEB-INF/classes/config/serialkiller.xml,关键点:

  • 禁用了ChainedTransformerTrAXFilter等关键类
  • 基本封堵了CC1-6链
  • 但保留了InvokeTransformer和CC7链的入口点函数

RMIConnector二次反序列化技术

原理分析

  1. 核心类javax.management.remote.rmi.RMIConnector

  2. 关键调用链

    • findRMIServerJRMP方法:接受base64字符串,解密并进行反序列化(oin.readObject())
    • findRMIServer方法:当path以/stub/开头时调用findRMIServerJRMP
    • connect方法:在rmiServer=null时调用findRMIServer
  3. 利用条件

    • 构造JMXServiceURL和环境参数
    • 通过CC链调用RMIConnectorconnect方法

绕过黑名单的技术实现

  1. CC6调用RMIConnector

    • 传统方法使用TiedMapEntry传递参数
    • 但题目中TiedMapEntry被禁用
  2. CC7调用RMIConnector

    • 通过反射修改LazyMaphashMap1table数组
    • 获取并修改Node对象中的key
    • 调试过程可见key从1被替换为rmiConnector

Payload构造要点

  1. 不使用ChainedTransformer,直接组合CC7入口点和InvokeTransformer
  2. 解决Runtime不可序列化问题:
    • 采用RMI二次反序列化绕过
    • 或直接加载字节码

实战步骤

  1. 初始信息收集

    • 通过文件读取获取.class文件
    • 分析CmdServlet.class的反序列化逻辑
  2. 绕过过滤

    • 利用未过滤的InvokeTransformer和CC7入口点
    • 构造不依赖ChainedTransformer的调用链
  3. 二次反序列化触发

    • 构造合适的RMIConnector对象
    • 通过反射机制设置关键参数
    • 触发connect方法调用

参考资源

  1. RMIConnector二次反序列化技术分析
  2. Java反序列化漏洞实战
  3. CTF中的反序列化技巧

总结

RMIConnector二次反序列化技术提供了一种在严格过滤环境下实现RCE的有效途径,关键在于:

  1. 理解RMI连接机制和反序列化触发点
  2. 灵活组合未被过滤的Transformer类
  3. 掌握反射修改关键参数的技巧
  4. 合理设计二次反序列化的调用链

这种技术在CTF比赛和实际渗透测试中都有重要应用价值,特别是在传统反序列化链被封锁的情况下。

RMIConnector二次反序列化技术分析与实战 环境搭建 使用CTF复现计划提供的Docker环境: 访问12345端口即可启动环境 漏洞分析 初始发现 通过抓包发现 url 参数,源代码中存在 url1 参数(已标记为废弃但有安全问题) 利用 url1 参数进行文件读取: 反序列化过滤机制 过滤规则位于 /WEB-INF/classes/config/serialkiller.xml ,关键点: 禁用了 ChainedTransformer 、 TrAXFilter 等关键类 基本封堵了CC1-6链 但保留了 InvokeTransformer 和CC7链的入口点函数 RMIConnector二次反序列化技术 原理分析 核心类 : javax.management.remote.rmi.RMIConnector 关键调用链 : findRMIServerJRMP 方法:接受base64字符串,解密并进行反序列化( oin.readObject() ) findRMIServer 方法:当path以 /stub/ 开头时调用 findRMIServerJRMP connect 方法:在 rmiServer=null 时调用 findRMIServer 利用条件 : 构造 JMXServiceURL 和环境参数 通过CC链调用 RMIConnector 的 connect 方法 绕过黑名单的技术实现 CC6调用RMIConnector : 传统方法使用 TiedMapEntry 传递参数 但题目中 TiedMapEntry 被禁用 CC7调用RMIConnector : 通过反射修改 LazyMap 中 hashMap1 的 table 数组 获取并修改 Node 对象中的 key 值 调试过程可见 key 从1被替换为 rmiConnector Payload构造要点 不使用 ChainedTransformer ,直接组合CC7入口点和 InvokeTransformer 解决 Runtime 不可序列化问题: 采用RMI二次反序列化绕过 或直接加载字节码 实战步骤 初始信息收集 : 通过文件读取获取 .class 文件 分析 CmdServlet.class 的反序列化逻辑 绕过过滤 : 利用未过滤的 InvokeTransformer 和CC7入口点 构造不依赖 ChainedTransformer 的调用链 二次反序列化触发 : 构造合适的 RMIConnector 对象 通过反射机制设置关键参数 触发 connect 方法调用 参考资源 RMIConnector二次反序列化技术分析 Java反序列化漏洞实战 CTF中的反序列化技巧 总结 RMIConnector二次反序列化技术提供了一种在严格过滤环境下实现RCE的有效途径,关键在于: 理解RMI连接机制和反序列化触发点 灵活组合未被过滤的Transformer类 掌握反射修改关键参数的技巧 合理设计二次反序列化的调用链 这种技术在CTF比赛和实际渗透测试中都有重要应用价值,特别是在传统反序列化链被封锁的情况下。