前言
最近在学习hessian反序列化注意到了这一道题目,拿来学习一下。不是Maven项目,打原生JDK。
这题是Apache Dubbo Hessian2 异常处理时反序列化(CVE-2021-43297)可以调用tostring链导致XStream - CVE-2021-21346 (x-stream.github.io)的后续执行
1 | Rdn$RdnEntry#compareTo-> |
但是javax.swing.MultiUIDefaults是package-private类,只能在javax.swing.中使用,而且Hessian2拿到了构造器,但是没有setAccessable,newInstance就没有权限。
BCEL ClassLoader
因此需要找一个MultiUIDeafaults的替代类,这里的UIDeafaults是继承Hashtable的,所以需要从toString到HashTable.get。别人用CodeQL找到了这样一个类(以后学习一下CodeQL吧,感觉挺好用的)。sun.security.pkcs.PKCS9Attributes
来看到这个类
1 | package sun.security.pkcs; |
toString方法调用了getAttribute方法,而getAttribute方法又调用了attributes的get方法,attributes又是hashtable这样链子就拼上了。
1 | PKCS9Attributes.toString |
这个sun.swing.SwingLazyValue#createValue
方法可以触发任意类的静态和public方法
然后看到com.sun.org.apache.bcel.internal.util.JavaWrapper
方法。
1 | package com.sun.org.apache.bcel.internal.util; |
他的_main
方法会触发runMain
方法,在runMain
方法中会加载一个类,并且找到该类中的_main
方法通过invoke去执行它,那么我们只需要创建一个恶意类,其中带一个方法名叫_main
然后让他加载那么就可以执行命令。
1 | package hessian; |
在初始化JavaWrapper时会对loader进行赋值,赋值为com.sun.org.apache.bcel.internal.util.ClassLoader
BCEL Classloader在 JDK < 8u251之前是在rt.jar里面。
同时在Tomcat中也会存在相关的依赖
tomcat7org.apache.tomcat.dbcp.dbcp.BasicDataSource
tomcat8及其以后
org.apache.tomcat.dbcp.dbcp2.BasicDataSource
而在
rt.jar!/com/sun/org/apache/bcel/internal/util/
包下,有Classloader
这么一个类,可以实现加载字节码并初始化一个类的功能,该类也是个Classloader(继承了原生的Classloader类)重写了loadClass()
方法
Java安全之BCEL ClassLoader - Zh1z3ven - 博客园 (cnblogs.com)
com.sun.org.apache.bcel.internal.util.ClassLoader
类的注释可以得知
替换JVM的标准类装入器。您可以将它与JavaWrapper结合使用,以便在请求时动态地修改/创建类。
这个类装入器以一种独特的格式识别特殊请求,也就是说,当被请求的类的名称包含$$BCEL$$
时,它会用该名称调用createClass()方法($$BCEL$$
之前的所有内容都被认为是包名)。
首先会判断类名是否以$$BCEL$$
开头,之后调用createClass()
方法拿到一个JavaClass
对象最终通过defineClass()
加载字节码还原类。
1 | JavaClass evil = Repository.lookupClass(shell.class); |
POC
1 | import hessian.shell; |
调用堆栈
1 | start:1007, ProcessBuilder (java.lang) |
后记
看到还有两种方法JNDI和加载so文件,其实感觉本质都是加载文件进去。这两种没复现成功。
0ctf2022 hessian-only-jdk writeup jdk原生链 - 先知社区 (aliyun.com)
Hessian反序列化 - Zer0peach can’t think
0ctf/tctf 2022 hessian only jdk 复现和学习 - KingBridge - 博客园 (cnblogs.com)
与 CVE-2021-43297 相关的两道题目 (harmless.blue)
Java安全之BCEL ClassLoader - Zh1z3ven - 博客园 (cnblogs.com)
[TCTF2022 Hessian-onlyJdk - Boogiepop Doesn’t Laugh (boogipop.com)](https://boogipop.com/2023/03/29/TCTF2022 _ Hessian-onlyJdk/)