8

一种新型的OLAP DML 注入攻击 | WooYun知识库

 6 years ago
source link:
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一种新型的OLAP DML 注入攻击

对于使用了DBMS_AWOLAP_TABLE或任何OLAP*函数Oracle OLAP应用程序来说,都将面临着一种新型的注入威胁。归根结底,这是由于SQLOLAP DML之间的语法差异所导致的。最终结果就是,攻击者可以利用这一点,以较高的权限来执行任意的SQL操作。

0x01 导言


联机分析处理(OLAP)通常用来查询多维数据。在Oracle中,可以创建分析工作区(Analytic Workspace)来存储待分析的数据、计算公式和模型等计算对象以及执行分析的各种程序。这里的计算对象及程序都是使用OLAP DML编写的。需要注意的是,OLAP DML不同于SQL,因为它们具有不同的语法。

举例来说,在SQL中,--用于单行注释,/**/用于多行注释。而OLAP DML中的注释则是用双引号"来表示。一个分号(;)可以用于分隔单行上的各个OLAP DML命令,而一条命令被拆分为两行的时候,则使用单个减号作为续行符。

OLAP DML可以从SQL中执行,但是需要借助于接收OLAP DML的接口。这包括DBMS_AWPL/SQL包OLAP_TABLE函数以及其他OLAP函数(比如OLAP_CONDITIONOLAP_EXPRESSION)。

另外,还有许多OLAP DML命令和函数以及一些SQL命令系列也可以从OLAP DML来执行。

0x02 OLAP DML注入攻击


本文介绍的新型注入攻击,主要出现在用户的输入被传递给OLAP函数DBMS_AW包的时候。即使该输入对于SQL来说是合法的,甚至使用的是约束变量,这种风险依然存在。基本上,攻击者可以将任意SQL语句嵌入到一条OLAP DML语句中,并以较高的权限执行之。

下面给出一个实际例子。DROP_AW_ELIST_ALL是Oracle提供的一个存储过程,相应代码如下所示:

enter image description hereenter image description here

在这里我们可以看到,DBMS_ASSERT是用来确保在"MYSCHEMA"和"AWNAME"这两个用户提供的参数中没有嵌入式的SQL的。一旦通过了验证,它们就会被传递给存储过程DBMS_AW.EXECUTE,并执行OLAP DML命令"AW ATTACH"。

但是我们仍然能够向这个调用中“夹带”进任意的OLAP DML命令,方法是用双引号括住一个伪造的AWNAME,并在分号后面加上另外的命令。在下面的例子中,我们执行OLAP DML命令SQL PROCEDURE的时候,会顺带执行一个PL/SQL的存储过程,就本例来说就是DBMS_OUTPUT.PUT_LINE

enter image description here

请注意上面输出中的SYS。

另外的一个实例是在DBMS_AW.AW_ATTACH这个存储过程中发现的。实际上,DBMS_AW的大多数存储过程和函数都有此安全漏洞。DBMS_AW.AW_ATTACH在取得AW名称后,会将其传递给GEN_DBNAME()GEN_DBNAME()函数会利用DBMS_ASSERT.QUALIFIED_SQL_NAME()对这个AW名称进行检查,以验证输入的合法性。

同样,这里攻击者也能夹带任意OLAP DML,并从这里执行SQL

enter image description here

在上面的攻击中,通过使用双引号,攻击者就可以绕过DBMS_ASSERT.QUALIFIED_SQL_NAME的输入验证了。不要忘了,OLAP DML也会看到这个双引号,并将其视为一个注释符。然后,攻击者可以提供一个连字符,这样就能够将OLAP DML命令AW ATTACH分为两行。再后面是一个分号,这样攻击者就能够执行其后的OLAP DML命令(在本例中就是调用SQL PROCEDURE)了,然后以双引号结束。这样一来,用户的输入不但绕过了DBMS_ASSERT.QUALIFIED_SQL_NAMEOLAPDML还会将其视为一个注释符号。

当处理OLAP_TABLE函数时,如果有任何用户输入被传递给了第三个参数,其本来就是要接收一个OLAP DML命令,或者是传递给了第四个参数LIMIT_MAP,那么攻击者就能够执行任意的OLAP DML了。

下面我们以一个专门设计的例子来进行说明。下面中的前几行代码,只是为展示这个安全问题而做了一些简单的设置工作:

enter image description here

在这里,我们想在视图中使用OLAP_TABLE,并从一个名为XLNAME的分析工作区变量中读入LIMIT_MAP。即使用户没有写AW的权限,他们仍然能够修改自己私有的副本。这个私有的副本可以用于AW对象的访问。因此,如果用户DAVID连接并发送下列内容,他就能够重写XLNAME,从而直接影响OLAP_TABLE的参数LIMIT_MAP。利用关键字PREDMLCMDDAVID就可以执行任意的OLAP DML命令了。

enter image description here

需要注意的是,上面SYS_CONTEXT('USERENV','CURRENT_USER')函数的输出为DAVID。这表明,OLAP DML及其后来的SQL命令都是以当前用户的身份来执行的,而不是以该视图的属主的身份来执行的。为了利用这一点来获得更高的权限,用户DAVID需要将这个视图传递给一个具有定义者权限的PL/SQL包或能够操作任意数据表的存储过程。实际的例子有很多,但是为了便于说明,我们专门设计的例子涉及¬SELECT_FROM_TABLE,这里存储过程的属主为SYS:

enter image description here

0x03 小结


如果开发人员在PL/SQL包中使用了DBMS_AW,存储过程或函数使用了定义者权限,并且用户的输入被传递给DBMS_AW,那么,即使输入内容通过了SQL级别的验证,或者即使使用了约束变量,攻击者仍然能够执行任意OLAP DML命令,并且是以PL/SQL包属主的身份从任意的SQL中执行。同样的,如果开发人员在用到定义者权限的PL/SQL包中使用了OLAP_TABLE或任何其他OLAP函数,那么攻击者就可以利用用户输入来发动类似的攻击。如果OLAP_TABLE被用于视图中,并且该视图可以像上面例子中那样允许随后加以处理,同时可以通过PL/SQL包来访问该视图的话,那么同样也会遭受类似的注入攻击。

OLAP应用程序的开发人员必须对所有的用户输入进行仔细检查,以确保用户输入中没有“夹带”任何OLAP DML命令。为此,通常需要拒绝任何含有连字符、双引号或分号的内容,当然,这还要考虑到具体应用程序的特殊情况。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK