【技术分享】如何高效地捡漏反序列化利用链?

admin 2022年1月6日03:50:23评论158 views字数 7453阅读24分50秒阅读模式

【技术分享】如何高效地捡漏反序列化利用链?




前言



之前在文章如何高效地挖掘Java反序列化利用链中提到了我是如何高效挖掘利用链的,这其中提到了工具tabby

目前,tabby开源也有一段时间了,这段时间里有不少小伙伴问我如何在实际环境中更好地使用它?

为此,本文将介绍我是如何利用tabby捡漏XStream CVE-2021-39147 && CVE-2021-39148

 




材料准备



跟之前那篇文章提到的一样,我们先对JDK生成代码属性图

# 生成图缓存文件java -Xmx8g -jar build/libs/tabby-1.1.0-RELEASE.jar --isJDKOnly# 导入Neo4j图数据java -Xmx8g -jar build/libs/tabby-1.1.0-RELEASE.jar --isSaveOnly

 




背景介绍



XStream自1.4.16版本的修复之后,有师傅在TSRC提交了CVE-2021-29505(PS: TSRC yyds)

该链跟之前我们在1.4.15版本时候挖的利用链都不太一样,它重新找到了一个新的触发toString的对象。这条链之前应该有师傅分析过了,就不细说了,这里直接贴一下调用链。

javax.naming.ldap.Rdn$RdnEntry#compareTo com.sun.org.apache.xpath.internal.objects.XString#equal com.sun.xml.internal.ws.api.message.Packet#toString com.sun.xml.internal.ws.message.saaj.SAAJMessage#copycom.sun.xml.internal.ws.message.saaj.SAAJMessage#getAttachmentscom.sun.xml.internal.ws.message.saaj.SAAJMessage$SAAJAttachmentSet#<init>com.sun.xml.internal.messaging.saaj.soap.ver1_1.Message1_1Impl#getAttachmentscom.sun.xml.internal.messaging.saaj.soap.ver1_1.Message1_1Impl#initializeAllAttachmentscom.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimePullMultipart#getCountcom.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimePullMultipart#parsecom.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimePullMultipart#parseAllcom.sun.xml.internal.org.jvnet.mimepull.MIMEMessage#getAttachmentscom.sun.xml.internal.org.jvnet.mimepull.MIMEMessage#parseAll com.sun.xml.internal.org.jvnet.mimepull.MIMEMessage#makeProgress com.sun.org.apache.xml.internal.security.keys.storage.implementations.KeyStoreResolver$KeyStoreIterator#hasNext com.sun.org.apache.xml.internal.security.keys.storage.implementations.KeyStoreResolver$KeyStoreIterator#findNextCertcom.sun.jndi.toolkit.dir.LazySearchEnumerationImpl#nextElementcom.sun.jndi.toolkit.dir.LazySearchEnumerationImpl#findNextMatchcom.sun.jndi.rmi.registry.BindingEnumeration#nextsun.rmi.registry.RegistryImpl_Stub#lookup


这里接过toString函数的是com.sun.xml.internal.ws.api.message.Packet,并且最后以com.sun.jndi.rmi.registry.BindingEnumeration#next触发lookup函数

【技术分享】如何高效地捡漏反序列化利用链?

这里红框框的地方ctx被设置为sun.rmi.registry.RegistryImpl_Stub来对外发起RMI连接。

这里另外说一下,其实CVE-2021-29505的利用链可以简化为

sun.rmi.registry.RegistryImpl_Stub#readObjectsun.rmi.server.UnicastRef#readExternal# trigger rmi connect

有兴趣的小伙伴可以看RMI绕过相关的文章,除了RegistryImpl_Stub,另外还有link

回到主题,通过29505这条链我们可以对外发起RMI连接,并且他是完全绕过16版本的黑名单的。

为此,XStream的官方出了17版本的黑名单补丁,这里来看一下17版本下所有的黑名单

黑名单字符对象

this.denyTypes(new String[] {        "java.beans.EventHandler",        "java.lang.ProcessBuilder",        "javax.imageio.ImageIO$ContainsFilter",        "jdk.nashorn.internal.objects.NativeString",        "com.sun.corba.se.impl.activation.ServerTableEntry",        "com.sun.tools.javac.processing.JavacProcessingEnvironment$NameProcessIterator",        "sun.awt.datatransfer.DataTransferer$IndexOrderComparator",              "sun.swing.SwingLazyValue" });

黑名单正则

GETTER_SETTER_REFLECTION = Pattern.compile(".*\$GetterSetterReflection");PRIVILEGED_GETTER = Pattern.compile(".*\$PrivilegedGetter");LAZY_ENUMERATORS = Pattern.compile(".*\.Lazy(?:Search)?Enumeration.*");LAZY_ITERATORS = Pattern.compile(".*\$LazyIterator");JAXWS_ITERATORS = Pattern.compile(".*\$ServiceNameIterator");JAVAFX_OBSERVABLE_LIST__ = Pattern.compile("javafx\.collections\.ObservableList\$.*");JAVAX_CRYPTO = Pattern.compile("javax\.crypto\..*");JAVA_RMI = Pattern.compile("(?:java|sun)\.rmi\..*");BCEL_CL = Pattern.compile(".*\.bcel\..*\.util\.ClassLoader");

黑名单继承对象

this.denyTypeHierarchy(InputStream.class);this.denyTypeHierarchyDynamically("java.nio.channels.Channel");this.denyTypeHierarchyDynamically("javax.activation.DataSource");this.denyTypeHierarchyDynamically("javax.sql.rowset.BaseRowSet");

从上面列举的黑名单,我们可以知道17版本的补丁对29505这条链的几个对象进行了黑名单处理。

Pattern.compile("(?:java|sun)\.rmi\..*");  ==拉黑==>  sun.rmi.registry.RegistryImpl_Stub, sun.rmi.server.UnicastRef
Pattern.compile(".*\.Lazy(?:Search)?Enumeration.*");==拉黑==> com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl

到这里我们可以发现,对于29505这条利用链,如下部分利用链仍然是可用的

javax.naming.ldap.Rdn$RdnEntry#compareTo com.sun.org.apache.xpath.internal.objects.XString#equal com.sun.xml.internal.ws.api.message.Packet#toString com.sun.xml.internal.ws.message.saaj.SAAJMessage#copycom.sun.xml.internal.ws.message.saaj.SAAJMessage#getAttachmentscom.sun.xml.internal.ws.message.saaj.SAAJMessage$SAAJAttachmentSet#<init>com.sun.xml.internal.messaging.saaj.soap.ver1_1.Message1_1Impl#getAttachmentscom.sun.xml.internal.messaging.saaj.soap.ver1_1.Message1_1Impl#initializeAllAttachmentscom.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimePullMultipart#getCountcom.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimePullMultipart#parsecom.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimePullMultipart#parseAllcom.sun.xml.internal.org.jvnet.mimepull.MIMEMessage#getAttachmentscom.sun.xml.internal.org.jvnet.mimepull.MIMEMessage#parseAll com.sun.xml.internal.org.jvnet.mimepull.MIMEMessage#makeProgress com.sun.org.apache.xml.internal.security.keys.storage.implementations.KeyStoreResolver$KeyStoreIterator#hasNext com.sun.org.apache.xml.internal.security.keys.storage.implementations.KeyStoreResolver$KeyStoreIterator#findNextCert

如果能找到从findNextCert函数开始的其他端点,我们仍然能对17版本的补丁进行绕过。

答案当然是肯定的,必然存在一些其他的端点,但是人工去挖掘会特别耗时,那么为了高效捡漏,我们当然不能人工去做这件事。这里我们的tabby就要登场了。

 




高效捡漏



这里我们先来分析一下findNextCert函数

【技术分享】如何高效地捡漏反序列化利用链?

从这里看,我们可以利用类属性aliases和keyStore来进行后续利用链的挖掘。

这里以aliases举例,之前29505利用链就是依靠LazySearchEnumerationImpl#nextElement开始找到的rmi的sink函数。那么,我们现在重新找一个新的,就需要满足如下条件:

1.对象实现了java.util.Enumeration接口
2.从该对象的nextElement函数开始,最终能到达一个触发恶意行为的sink函数
3.从nextElement函数开始到sink函数,路径上不能出现前面黑名单涉及的对象

如果能满足上述条件,那么我们就挖到了能绕过17版本补丁的新利用链。接下来的工作就交给tabby来做了。

首先,我们需要根据上述的条件,描述出具体的查询语句。先来限制一下source函数

match (source:Method {NAME:"nextElement"})                    <-[:HAS]-(cls:Class)-[:INTERFACE|EXTENDS*]                    ->(cls1:Class {NAME:"java.util.Enumeration"})match (source)-[:CALL]->(m1:Method)

source函数为nextElement,并且实现了java.util.Enumeration接口

再来限制sink函数

match (sink:Method {IS_SINK:true, VUL:"JNDI"})

这里就限制当前sink函数最终能达成JNDI注入的效果。

最后,我们再来限制一下路径上不能出现的黑名单对象

call apoc.algo.allSimplePaths(sink, m1, "<CALL|ALIAS", 8) yield path where none(n in nodes(path) where n.CLASSNAME in ["java.beans.EventHandler","java.lang.ProcessBuilder","javax.imageio.ImageIO$ContainsFilter","jdk.nashorn.internal.objects.NativeString","com.sun.corba.se.impl.activation.ServerTableEntry","com.sun.tools.javac.processing.JavacProcessingEnvironment$NameProcessIterator","sun.awt.datatransfer.DataTransferer$IndexOrderComparator","sun.swing.SwingLazyValue","com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl","sun.rmi.registry.RegistryImpl_Stub",
"com.sun.jndi.dns.BindingEnumeration","com.sun.jndi.cosnaming.CNBindingEnumeration","com.sun.jndi.toolkit.dir.HierMemDirCtx$FlatBindings","com.sun.jndi.ldap.LdapReferralException"])return source,path limit 50

这里第9行上的黑名单是后续人工排除后添加的(不可行或构造过于麻烦)。

把上面的3个部分合起来后查询最终能得到如下3条利用链。

【技术分享】如何高效地捡漏反序列化利用链?

分别是一下对象

1.com.sun.jndi.ldap.LdapSearchEnumeration 对应 CVE-2021-39147
2.com.sun.jndi.ldap.LdapBindingEnumeration 对应 CVE-2021-39145 (CVE-2021-39151用的也是这个)
3.com.sun.jndi.toolkit.dir.ContextEnumerator 对应 CVE-2021-39148

他们分别最终将调用sink函数NamingManager.getContextDirectoryManager.getObjectInstance

这两个sink函数是JNDI处理Reference的函数,通过这两个函数可以在特定JDK版本下载入外部的任意代码,也可以在tomcat下执行el表达式,具体可以看JNDI关于Reference的知识。

 




补丁修复



XStream 1.4.18版本开始将默认开启白名单模式,只允许几个基础类型的进行还原。

【技术分享】如何高效地捡漏反序列化利用链?

但是这里想不明白的是为何将之前的黑名单处理直接删除了,这意味着未来XStream的安全性将依靠开发者对于反序列化风险的认识。

此外,后续版本绕过默认白名单还是存在可能性的,但是估计没办法像现在这样能造成那么大的危害了吧。

 




总结



本文讲述了我是如何通过tabby来捡漏利用链的,这里欢迎师傅们给tabby提pr或issue。

另外,这里还有一件趣事,由于国内过于积极提交利用链,XStream官方无奈之下默认开启白名单的方式来解决后续可能的绕过。嗯,手动狗头。

【技术分享】如何高效地捡漏反序列化利用链?【技术分享】如何高效地捡漏反序列化利用链?


- 结尾 -
精彩推荐
【技术分享】A-Journey-into-Synology-NAS-系列——群晖NAS介绍
【技术分享】忆——Weblogic CVE-2016-0638反序列化漏洞
学习不足为奇,但让AI聪明的遗忘却是个问题
福利锦囊 | 带你提前锁定830安全客官网焕新大事件!
【技术分享】如何高效地捡漏反序列化利用链?
戳“阅读原文”查看更多内容

本文始发于微信公众号(安全客):【技术分享】如何高效地捡漏反序列化利用链?

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月6日03:50:23
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【技术分享】如何高效地捡漏反序列化利用链?https://cn-sec.com/archives/505068.html

发表评论

匿名网友 填写信息