反射是大多数语言不可或缺的一部分。对象可以通过反射获得自己的类,类可以通过反射获得所有的方法(包括private),获得的方法可以被调用,总之,通过“反射”,我们可以给Java这样的静态语言增加动态的特性。什么是反射Java的反射是指在运行状态下,对于任何一个类,你都可以知道这个类的所有属性和方法,对于任何一个对象。基本形式publicvoidexecute(StringclassName,StringmethodName)throwsException{Classclazz=Class.forName(className);clazz.getMethod(methodName).invoke(clazz.newInstance());}在上面的例子中,我演示了反射中几个极其重要的方法:获取类的方法:forName实例化类对象的方法:newInstance获取函数的方法:getMethod执行函数的方法:invoke反射的作用:使Java动态化,修改已有的Object属性,动态生成对象,动态调用方法,在反序列化漏洞的应用中操作内部类和私有方法,自定义需要的对象,通过invoke调用除同名函数以外的函数,通过class类创建对象,引入objectsthatcannotbeserializedexamplesofsimplifiedjava-likereflection这里有一个Daydream的leader的例子,详细解释了反射。先写一个Person作为我们下面演示的原型类publicclassPerson{privateStringname;公共年龄;publicvoidact(){System.out.println("测试");}@OverridepublicStringtoString(){return"Persion{"+"name='"+name+'\''+",age="+age+'}';}publicStringgetName(){返回名称;}publicvoidsetName(Stringname){this.name=name;}publicintgetAge(){返回年龄;}publicvoidsetAge(intage){this.age=age;}publicPerson(){}publicPerson(Stringname,intage){this.name=name;这个。年龄=年龄;}}使用forName方法获取原型类Classc=Class.forName("Person");这里也写了一个基于ClassLoader的动态类加载方法this.getClass().getClassLoader().loadClass("Person");从原型类实例化对象,使用构造函数实例化Constructorconstructor=c.getConstructor(String.class,int.class);Personp1=(Person)constructor.newInstance("abc",22);下面我们来逐行分析构造函数constructor=c.getConstructor(String.class,int.class);这一行是获取原型类中重载的构造函数publicPerson(Stringname,intage){this.name=name;this.age=age;}将参数传递给构造函数并实例化一个对象Personp1=(Person)constructor.newInstance("abc",22);我们可以打印p1看看返回的结果【----求助网安学习,在以下所有学习资料中添加vx:yj009991,备注“没想到”就搞定了!】①网络安全学习成长路径思维导图②60+经典网络安全工具包③100+SRC漏洞分析报告④150+在线安全攻防实战技术电子书⑤最权威的CISSP认证考试指南+题库⑥1800多页CTF实战技能手册⑦网络安全公司最新面试题(含答案)合集⑧APP客户端安全检测指南(Android+IOS)获取类privateString名称中的属性;公共年龄;publicFieldageField=c.getField("age");ageField.set(p1,11);privateFieldnameField=c.getDeclaredField("name");nameField.setAccessible(true);nameField.set(p1,"xinyuan");获取类方法Methodactmethod=c.getMethod("act",String.class);actmethod.invoke(p1,"SKyMirror");getMethod类似于上面的get构造函数,第一个参数是函数名,第二个是参数invoke方法的类型一是传入对象,二是传入参数值使用URLDNS(反射)这个链是反射的简单应用利用URL类重写hashCode方法,使得执行hashCode时,exploit无法执行命令,但会请求DNS,所以用来验证是否存在反序列化漏洞。源码如下:可以看到当我们调用一次hashCode方法时,会针对传入的URL对象发起请求,也就是如果我们去DNSLOG申请地址,可以判断是否hashCode方法根据访问成功执行再判断是否执行逆序优化操作。URL类实现了java.io.Serializable,可以进行序列化操作。因此,这里可以验证一下我们上面的想法。链条这条链条也比较短,比较简单。它主要使用HashMap来执行hashCode方法。HashMap实现了Serializable,可以序列化。这里在反序列化的时候注意HashMap的readObject方法。下面我们继续hash方法。key参数可控,反序列化时生成key。使用put在HashMap中传入一个URL对象,在反序列化的时候可以调用这个方法,从而触发整个链条。需要注意一点,我们在序列化的时候,传入的put参数会修改传入的URL对象的hashCode值,因为hashCode值不等于-1,所以下面的方法不能正常触发,即无法触发DNS请求。同时在正常的put传参过程中会执行一个DNS请求,所以我们在put传参前修改hashCode的值(不是-1),传参后修改hashCode为-1,这样反序列化时可以正常执行。payload如下");classc=u.getClass();//在put方法传参前修改URL对象的hashCode值FieldhashcodeField=c.getDeclaredField("hashCode");hashcodeField.setAccessible(true);hashcodeField.set(u,123);hashMap.put(u,123);//修改URL对象的hashCode值为-1这里>>更多在线安全工具和学习资料,扫码免费:
