X凌EKP是一款功能强大的企业协同办公平台,适用于各种规模的组织,旨在提高工作效率、促进团队协作,以及优化业务流程。它可以帮助组织更好地组织和管理工作,提高竞争力
情报披露X凌EKP存在未授权访问漏洞,可以读取resource目录下的所有文件,包括日志请求信息
V15等
spring.xml,存在匿名路径:/ui-ext/**
查看web.xml,对应的 Servlet 是 com.landray.kmss.web.servlet.RedirectServlet
经过一系列的 Filter 后请求到了RedirectServlet,跟进这个service方法
request.getContextPath()会获取项目名,然后替换成 “”,有的情况下Tomcat部署项目没有修改配置,带上了ekp的名字,这里会把它替换了
request.getRequestURI()获取的值为:/./ui-ext/./behavior,然后进行if判断,这里添加的/./刚好绕过判断,跟进this.redirect方法
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String url = request.getRequestURI().replaceFirst(request.getContextPath(), "");
if (!url.endsWith(".theme.css") || !url.startsWith("/ui-ext/") && !url.startsWith("//ui-ext/")) {
this.redirect(request, response);
} else {
ThemeUtil.service(request, response);
}
}
redirect和getFileName方法:
getFileName:把项目名替换成“”,然后再把this.requestPath替换成“”,最后拼接this.forwardPath
/./ui-ext/./behavior替换掉/ui-ext/-->/../behavior
拼接返回filename-->file:c:/landray/kmss/resource/ui-ext//../behavior
通过拼接的/../刚好可以穿越到resource命目录,接着就是一系列的判断,然后使用new URL(fileName)读取文件/目录
private void redirect(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String fileName = this.getFileName(request);
String fileNameLower = fileName.toLowerCase();
if (fileNameLower.indexOf("%c0") < 0 && fileNameLower.indexOf("%00") < 0) {
if (fileNameLower.indexOf(".ini") >= 0) {
throw new FileNotFoundException("ini文件不允许被访问");
} else {
if (!this.anonymous && UserUtil.getKMSSUser(request).isAnonymous()) {
response.sendRedirect(request.getContextPath() + "/login.jsp");
} else {
URLConnection conn = (new URL(fileName)).openConnection();
InputStream stream = null;
try {
stream = conn.getInputStream();
.......
读取文件
.......
} catch (FileNotFoundException var41) {
response.setStatus(404);
logger.error(fileName + "文件不存在", var41);
} catch (Exception var42) {
logger.error(request.getRequestURI(), var42);
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (Exception var38) {
logger.error("关闭流错误!", var38);
}
}
}
}
} else {
throw new IOException("路径包含非法字符");
}
}
`
getFileName方法
private String getFileName(HttpServletRequest request) {
String req = request.getRequestURI().replaceFirst(request.getContextPath(), "");
req = req.replaceFirst(this.requestPath, "");
return this.forwardPath + req;
}
this.requestPath和this.forwardPath值如下:
同样的,因为Spring MVC默认会将多个斜杠(“/”)视为一个斜杠(“/”)来处理,也可以使用//ui-ext/这种方式进行绕过
联系官方打补丁