48

WebLogic WLS核心组件RCE分析(CVE-2020-2551)

 4 years ago
source link: https://lucifaer.com/2020/02/25/WebLogic WLS核心组件RCE分析(CVE-2020-2551)/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

看完了CORBA后再来看这个洞,很多东西才能理解的比较深刻….

0x01 漏洞概述

3U3QRvM.jpg!web

Weblogic官方在1月补丁中修复了CVE-2020-2551漏洞,该漏洞位于 WLS 核心组件中,允许远程攻击者通过 iiop 进行网络请求,从而攻击Weblogic服务器,最终远程攻击者可以利用该漏洞完全接管Weblogic服务器。

从通告中我们能看到漏洞发生在 WLS 的核心组件,所以给了我们一个思路去分析该漏洞,只需要从接受并解析 iiop 请求点入手进行分析即可。

0x02 漏洞分析

分析该漏洞应该从两方面来进行:

Context.bind()

本文也将从这两个方面进行分析。分析到最后其实会发现 iiop 只是触发方式,关键的触发点还是由于Weblogic应用本身的处理逻辑,也就是说本质上是个应用漏洞而非协议漏洞。

2.1 Context的生成以及bind的流程

无论利用 rmi-iiop 的方式去写客户端,还是写服务端,都需要在编写具体逻辑前获取 Conetext 对象,也就是如下的代码:

new InitialContext();

如果研究过CORBA通信过程的话,就能理解这一部分是获取 Naming Service 的过程,对于客户端来说是获取其中存在的IOR引用以供后面的rpc流程使用;对于服务端来说,用于完成对象注册。这里来跟进一下Context的生成过程,方便后续理解Weblogic的解析逻辑。

buMfYf3.jpg!web

这里有个很重要的参数 environment ,在该参数中可以设置 Context 的静态变量来指定 Context 的初始化参数,包括 JNDI_FACTORYPROVIDER_URL 。这些初始化参数在后续的流程中有极其重要的作用。

a2INfmu.jpg!web

当在 environment 中设置了 Context.INITIAL_CONTEXT_FACTORY 后会尝试获取该 Context factory

7fe6nii.jpg!webFBzqaqF.jpg!web

这里会根据设定的 Context.INITIAL_CONTEXT_FACTORY ,反射获取工厂类,之后调用 getInitialContext() 方法。首先看一下在JDK中原生以及在Weblogic中所拓展出的工厂类到底有哪些:

7JJZ32Q.jpg!web

这里我们简单的看一下 WLInitialContextFactory 这个Weblogic拓展的工厂类:

BR3IZzn.jpg!web

rIRZ3qJ.jpg!web

v6VRbme.jpg!web

这里跟进看一下 getORBReference() 方法:

Ebe2imb.jpg!web

这里和CORBA的写法是一样的:

VjEfUrI.jpg!web

都是初始化 orb 获取 Naming Service 的过程,如果想要了解详细的过程,可以研究一下上一篇讲CORBA的文章。

在获取了 Context 后,接着来看一下其绑定流程,此流程在 bind() 函数中有所体现:

b6NJJbZ.jpg!web

熟悉CORBA的同学肯定一眼就能看出这里完成的是生成IOR,同时设定corba协议中的数据类型与java类型交互的约定为 tk_value ,并设定请求的 op 或者叫做 operationbind_any 。这里不仅仅设定了服务端对注册请求的处理方式( bind_any 的处理流程),同时设定了后面反序列化的方式( tk_value )。

2.2 Weblogic解析流程

在了解了Context的生成及 bind() 流程后,接着来看一下Weblogic的解析流程。Weblogic默认在7001端口接收 iiop 请求,所有的请求都是交由 weblogic.rmi.cluster.ClusterableServerRef#invoke 来处理的:

J3qyaiU.jpg!web

handleRequest 中的流程较为长,我只截关键处理点:

YrymymF.jpg!web

直接跟进 var2.invoke() ,具体的实现方法在 weblogic.rmi.cluster.ClusterableServerRef#invoke

6ZjaIzE.jpg!web

zQBVBbr.jpg!web

这里首先会判断请求是否为 objectMethods 中已经存在的类型,当不存在时将会调用 delegate.invoke() 来处理,由于我们在发送注册请求时的请求类型为 bind_any() 并不在 objectMethods 中,所以会触发 delegate.invoke() ,具体的实现类为 weblogic.corba.cos.naming._NamingContextAnyImplBase#_invoke

iQFRr2b.jpg!web

因为我们当前的请求类型为 bind_any() ,其所对应的 var5 为0,所以会进入两个关键的流程:

WNameHelper.read()
var2.read_any()

UNzMVzI.jpg!web

ZBjauiZ.jpg!web

WNameHelper.read() 主要负责提取IOR中的信息(id、kind)用于之后注册到 orb 的流程中。

而反序列化的触发点在 var2.read_any() 中:

3aqqeii.jpg!web

在上一节中,已经说过在 bind() 流程中发起注册请求时,会构造一个 Any 类,并将交互类型设置为 tk_value 也就是 this.read_TypeCode() 。继续跟进:

NZf6RjQ.jpg!web

VNJVJv2.jpg!web

这里会根据 TCKind 来分派具体的处理流程, tk_value 对应29:

a6RR32I.jpg!web

接下来就是之前CORBA文章中所提到过的反序列化流程:

7bQJ3eI.jpg!web

CDRInputStream 跳转到JDK原生反序列化:

6Zri2qZ.jpg!web

至此分析结束。

0x03 利用研究

根据0x02中的分析,可以梳理出攻击需要的两个元素:

bind_any()
Any

攻击效果如下:

fayAvq3.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK