@Adminxe
![](https://www.adminxe.com/wp-content/uploads/2019/12/com.jpg)
0x01 漏洞背景
在WebLogic官方发布的10月份安全补丁中,包含了由Venustech ADLab提交的CVE-2019-2890的修复。该漏洞通过T3协议发送恶意的反序列化数据绕过了Weblogic的黑名单,成功反序列化执行任意命令。通过官方公告可知,该漏洞的利用条件是需要认证。
![](https://www.adminxe.com/wp-content/uploads/2020/01/1-2-1024x114.png)
0x02 影响范围
- Weblogic 10.3.6.0.0
- Weblogic 12.1.3.0.0
- Weblogic 12.2.1.3.0
0x03 漏洞分析
下面以10.3.6.0作为分析版本。问题出现在PersistentContext
类上,通过查看继承关系我们知道PersistentContext
类实现了序列化接口Serializable
。
![](https://www.adminxe.com/wp-content/uploads/2020/01/2-2.png)
PersistentContext类继承关系
我们来看看它的readObject
方法,将ObjectInputStream
类对象var1
传入readSubject
方法。
![](https://www.adminxe.com/wp-content/uploads/2020/01/3-2-1024x411.png)
readObject方法
跟进readSubject
方法发现,会先从var1
中读取反序列化数据当中的对象数据。然后调用EncryptionUtil.decrypt
方法进行解密,最后解密后的数据被用于反序列化为对象。
![](https://www.adminxe.com/wp-content/uploads/2020/01/4-2-1024x376.png)
readSubject方法
至此我们知道PersistenContext
序列化数据中还携带了其他对象反序列化后的加密数据。如果我们在序列化PersistentContext
时,将恶意对象反序列化数据先加密,然后writeObject
,就可以让其携带恶意对象,绕过Weblogic黑名单进行反序列化了。
0x04 漏洞利用
根据以上思路,我们编写一个携带恶意对象的PersistenContext
类。只需修改下原来代码中的writeSubject
方法为如下,其中Poc.getObject()
就是我们的恶意对象。
![](https://www.adminxe.com/wp-content/uploads/2020/01/5-2-1024x405.png)
修改writeSubject方法代码
在进行序列化之前我们要处理四个问题。第一个问题是创建PersistenContext对象报错。
![](https://www.adminxe.com/wp-content/uploads/2020/01/6-1-1024x96.png)
创建PersistenContext对象报错信息
这是因为PersistenContext
初始化时调用了SecurityServiceManager.isKernelIdentity()
进行内核身份判断。isKernelIdentity
方法无论如何都会抛出一个NotSupportedException
异常,导致我们序列化被终止。
![](https://www.adminxe.com/wp-content/uploads/2020/01/7-2-1024x103.png)
SecurityServiceManager.isKernelIdentity()方法
我们可以将其注释掉
![](https://www.adminxe.com/wp-content/uploads/2020/01/8-2-1024x309.png)
PersistenContext构造方法要修改的代码
第二个问题是反序列化PersistenContext类会出现卡死现象。这是因为PersistenContext
等相关的类都会有一个AuthenticatedSubject
静态对象要初始化。
![](https://www.adminxe.com/wp-content/uploads/2020/01/9-2-1024x86.png)
静态AuthenticatedSubject内核id对象
初始化时会进入到如下代码。
![](https://www.adminxe.com/wp-content/uploads/2020/01/10-1-1024x490.png)
导致卡死的代码段
我们需要ceClient
变量为true
,否则会一直进循环执行ceSubjectManagerLock.wait()
进行等待,无法序列化!而ceClient
是从系统属性com.bea.core.internal.client
获取的,所以在序列化之前需要将该属性设置为true
。
![](https://www.adminxe.com/wp-content/uploads/2020/01/11-2-1024x18.png)
ceClient变量的赋值
第三个问题是恶意对象没有被加密。这是因为在调用EncryptionUtil.encrypt
方法加密时,会根据Kernel.isServer()
为true
时才会进行加密,否则返回原数据。
因此加密之前需要调用KernelStatus.setIsServer(true)
设置状态为true
。
![](https://www.adminxe.com/wp-content/uploads/2020/01/12-1-1024x97.png)
加密时的判断
第四个问题,加密时需要SerializedSystemIni.dat
文件。 我们需要目标服务器weblogic当前使用域下该文件放到我们poc的根目录。这也是官方将这个漏洞划分为需要认证的原因。
![](https://www.adminxe.com/wp-content/uploads/2020/01/13-1-1024x328.png)
加密时需要SerializedSystemIni.dat文件
解决完这四个问题,就可以将PersistenContext
对象反序列化为文件了。最后通过t3协议发送反序列化数据给Weblogic,即可执行任意命令。
![](https://www.adminxe.com/wp-content/uploads/2020/01/14-1024x277.png)
序列化PersistenContext对象为文件
![](https://www.adminxe.com/wp-content/uploads/2020/01/15-1024x545.png)
漏洞利用演示
0x05 补丁分析
通过对比,发现最新补丁在反序列化时,使用WSFilteringObjectInputStream
对要反序列化的对象进行过滤。
![](https://www.adminxe.com/wp-content/uploads/2020/01/16-1024x371.png)
补丁修复处
WSFilteringObjectInputStream
实现了Weblogic下的过滤接口 FilteringObjectInputStream
。在其resolveClass
方法中,检查要反序列化的类是不是Subject
的子类,不是则会抛出一个非法类异常,反序列化终止!
![](https://www.adminxe.com/wp-content/uploads/2020/01/17-1024x460.png)
补丁修复的方式
0x06 分析总结
这个漏洞需要满足以下两个条件,才能触发成功,较为鸡肋。
- Weblogic开启t3协议
- 可以获取到
SerializedSystemIni.dat
文件
但是在实际环境中,如果部署在weblogic的站点存在任意文件下载
或者任意文件读取
,那么配合上该漏洞即可执行任意命令。