引言
在Oracle官方最新发布的January 2024补丁中,修复了一个基于Weblogic T3\IIOP协议的远程命令执行漏洞CVE-2024-20931,该漏洞是笔者在2023年10月提交给Oracle,原理上属于CVE-2023-21839补丁的绕过,其中涉及到一个JNDI的新攻击面,在这里分享出来。
漏洞分析
CVE-2023-21839概述
当Weblogic通过T3\IIOP进行绑定的远程对象实现了OpaqueReference接口,那么在对该对象进行lookup时,会调用这个对象的getReferent函数进行查询。
而碰巧有一个名为ForeignOpaqueReference的对象,它的getReferent函数在进行远程对象查询的时候,会再次发起JNDI查询,从而造成了JNDI注入
利用步骤大致分为三步(关键步骤均用红框进行了标记),
- 建立一个恶意ForeignOpaqueReference对象,并将remoteJNDIName设置为远程恶意JNDI服务。
- 通过T3\IIOP协议在WLS上绑定该恶意对象。
- 通过lookup查询该恶意对象,触发ForeignOpaqueReference.getReferent的调用,从而造成恶意JNDI注入。
CVE-2023-21839补丁分析
Oracle官方于January 2023对该漏洞进行了修复,补丁内容分为两部分,
第一部分,限制了绑定ForeignOpaqueReference对象时对jndiEnvironment中providerURL的设置,
第二部分对loopup的JNDI链接的协议也做了比较严格的限制,
直观上去看,想继续通过ForeignOpaqueReference去做JNDI注入的路已经被堵死了。
CVE-2024-20931的挖掘
经过一定的分析,可以感觉到,现在有三条路是可能走的通的,
第一条路,寻找别的实现OpaqueReference接口的类的getReferent寻求突破(比较有意思的是ForeignOpaqueReference在两个package链接下都有,且代码有一些细微的差别),
这条路有一定的可行性,但是要分析的类太多了,所以我没有做太深入的分享。
第二条路,尝试绕过补丁中的JNDIUtils.isValidJndiScheme函数,
做了一定的努力,最终未能成功。
第三条路,就是如果在java.naming.provider.url为空的情况下,做一下危险操作,
因为别的env还是可以控制的,所以或许能在指定java.naming.factory.initial进行初始化的时候,创造可能性,非常幸运的是,WLS提供了不少的InitialContextFactory,而恰恰就有一个AQjmsInitialContextFactory在初始化的时候,需要通过JNDI去获取远程的DataSource,
通过AQjmsInitialContextFactory初始化发起的JNDI注入,就成功达成一种二次JNDI注入,实现了远程的RCE。
总结
这个漏洞相比于之前的JNDI注入,不是在lookup这个JNDI注入的关键函数上寻求突破,而是把关注点侧重于Context的初始化阶段,从而绕过了上一个漏洞的补丁,个人感觉还是比较有意思的一个漏洞,Oracle在后续的补丁中又对java.naming.factory.initial的设置做了验签处理,毫无疑问,还是有一些jndiEnvironment可以进行设置的,至于能不能去找到新的绕过,则需要更深一步的研究。