[Java安全]—fastjson漏洞利用

前言

文章会参考很多其他文章的内容,记个笔记。

FASTJSON

fastjson 组件是 阿里巴巴开发的序列化与 反序列化组件。

fastjson 组件 在反序列化不可信数据时会导致远程代码执行。

POJO

POJO是 Plain OrdinaryJava Object 的缩写 ,但是它通指没有使用 Entity Beans 的普通 java 对象,可以把 POJO 作为支持业务逻辑的协助类

用 来实现JAVA POJO对象 与JSON 字符串的互相转换,比如:

User user = new User();
user.setUserName("李四");
user.setAge(24);   
String userJson = JSON.toJSONString(user);

将其 序列化的结果为:

{"age":24,"userName":"李四"}

以上将对象转换为 JSON 字符串的操作 称之为 序列化 ,反之,将JSON字符串实例化成 JAVA POJO 对象的操作 即称之为 反序列化

Java 反序列化机制

简单介绍 序列化 和反序列化工具类:

ObjectInputStream和ObjectOutputStream

序列化
User user = new User();
user.setName("李四");
user.setSex("M");
ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(new File("User.txt")));
oo.writeObject(user);

反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("User.txt")));
User user1 = (User) ois.readObject();
System.out.println(user1.getName() + ":" + user1.getSex());

序列化需要调用ObjectOutputStream的writeObject方法,反序列化需要调用ObjectInputStream的readObject方法。

输出结果:

 也就是执行了以下:

User writeObject
User readObject
User readResolve
李四:M

fastjson 反序列化机制

添加依赖:

<dependencies>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.23</version>
    </dependency>
</dependencies>

案例1

标准POJO类定义如下,有userName和age两个属性,还有一些构造函数。

package fastjson;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class Student {
    private String name;
    private int age;

    public Student() {
        System.out.println("构造函数");
    }

    public String getName() {
        System.out.println("getName");
        return name;
    }

    public void setName(String name) {
        System.out.println("setName");
        this.name = name;
    }

    public int getAge() {
        System.out.println("getAge");
        return age;
    }

    public void setAge(int age) throws Exception{
        System.out.println("setAge");
        this.age = age;
    }
    public void setTest(int i){
        System.out.println("setTest");
    }
public static void test1() throws Exception {
    Student student = new Student();
    student.setAge(18);
    student.setName("snowy");
    System.out.println("====================");
    String jsonString1 = JSON.toJSONString(student);
    System.out.println("====================");
    String jsonString2 = JSON.toJSONString(student, SerializerFeature.WriteClassName);
    System.out.println(jsonString1);
    System.out.println(jsonString2);
}
public static void test2()throws Exception{
    String jsonString1 = "{\"age\":18,\"name\":\"snowy\"}\n";
    String jsonString2 = "{\"@type\":\"fastjson.Student\",\"age\":18,\"name\":\"snowy\"}\n";
    System.out.println(JSON.parse(jsonString1));
    System.out.println("======================");
    System.out.println(JSON.parse(jsonString2));
    System.out.println("======================");
    System.out.println(JSON.parseObject(jsonString1));
    System.out.println("======================");
    System.out.println(JSON.parseObject(jsonString2));
    System.out.println("======================");
}
    public static void main(String[] args) throws Exception {
        test1();
        //test2();
    }
}

结果:

 可以看到, 调用JSON.toJSONString 的话(也就是序列化了),会自动调用对应的 getter 

其次 若是加上  SerializerFeature.WriteClassName,则返回的内容除属性值外,还会加上@type 字段 指明当前类

实例2:

接下来 看看test 2,将 JSON字符串转换成对象。

String jsonString1 = "{\"age\":18,\"name\":\"snowy\"}\n";
String jsonString2 = "{\"@type\":\"fastjson.Student\",\"age\":18,\"name\":\"snowy\"}\n";
System.out.println(JSON.parse(jsonString1));
System.out.println("======================");
System.out.println(JSON.parse(jsonString2));
System.out.println("======================");
System.out.println(JSON.parseObject(jsonString1));
System.out.println("======================");
System.out.println(JSON.parseObject(jsonString2));
System.out.println("======================");

结果:

{"name":"snowy","age":18}
======================
构造函数
setAge
setName
fastjson.Student@4629104a
======================
{"name":"snowy","age":18}
======================
构造函数
setAge
setName
getAge
getName
{"name":"snowy","age":18}
======================

可以看到,不加上 @type 指明类时,时得不到类对象的。

当 加上  @type 字段 的字符串进行传唤后,不仅能得到类对象,  parse 会调用 对应的  setter,

而  parseObject 会调用两者  也就是 setter 和 getter

这个  @type 的方式 也叫做 autotype:

autotype 是 Fastjson 中的一个重要机制,粗略来说就是用于设置能否将 JSON 反序列化成对象。

set开头的方法要求:

  • 方法名长度大于4且以set开头,且第四个字母要是大写
  • 非静态方法
  • 返回类型为void或当前类
  • 参数个数为1个
  • get开头的方法要求:

方法名长度大于等于4

  • 非静态方法
  • 以get开头且第4个字母为大写
  • 无传入参数
  • 返回值类型继承自 Collection 或 Map 或 AtomicBoolean 或 AtomicInteger 或 AtomicLon
     

JdbcRowSetImpl链结合JNDI注入

fastjson<1.2.24

在上边  案例 1 中 自动调用 getter 时,应该可以联想到  Commons-Beanutils中动态调用 getter 的方法。

如 Commons-Beanutils 里   PropertyUtils.getProperty 传入 name,他会自动在前面加上 get,然后将 n 转为大写,即调用 getName。 所以,这里如果传入 outputProperties 时,他会自动调用getOutputProperties ,所以这里也可以用这种方式来调用关键的两个方法 :setDataSourceName()setAutoCommit()

public void setAutoCommit(boolean var1) throws SQLException {
    if (this.conn != null) {
        this.conn.setAutoCommit(var1);
    } else {
        this.conn = this.connect();
        this.conn.setAutoCommit(var1);
    }
}

如果 这里的 this.conn == null 会调用 本类的 this.connect()

private Connection connect() throws SQLException {
        if (this.conn != null) {
            return this.conn;
        } else if (this.getDataSourceName() != null) {
            try {
                InitialContext var1 = new InitialContext();
                DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
fastjson漏洞利用原理是基于fastjson反序列化漏洞。该漏洞利用fastjson在反序列化过程中的特定问题,使攻击者可以通过构造恶意的JSON数据来执行任意代码或导致拒绝服务攻击。 具体来说,fastjson在反序列化JSON字符串时,会将JSON字符串转换为Java对象。在这个转换过程中,fastjson会根据JSON字符串中的字段名和值来实例化对象,并将相应的值赋给对象的成员变量。然而,由于fastjson的设计缺陷,攻击者可以通过构造特定的JSON字符串来触发一些危险操作。 漏洞的原理是fastjson在处理反序列化时,默认情况下会自动调用对象的无参构造函数来创建对象。如果攻击者能够构造一个恶意的JSON字符串,并在其中指定一个带有恶意代码的类名,那么当fastjson反序列化时,会自动调用该类的无参构造函数,并执行其中的恶意代码。 攻击者还可以利用fastjson对于类型转换不严格的特性,通过构造特定的JSON字符串来实现类型绕过,即将一个恶意代码注入到一个看似安全的类型中,然后在反序列化时将其转换为具有执行权限的类型,从而实现代码执行。 由于fastjson的广泛使用和开源社区的贡献,fastjson漏洞利用成为了一种常见的攻击手段。因此,使用fastjson时,建议及时更新到最新版本,并采取其他安全措施,如禁用autotype特性、限制反序列化的目标类等,以减少漏洞的风险。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值