ora-29471:Oracle 11g DBMS_SQL Security Changes

Oracle 11g 引入了针对 DBMS_SQL 包的安全改进,包括增加游标编号的不可预测性、限制无效游标的访问及增强权限验证等措施,有效缓解了“游标窃取”和“游标注入”攻击。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 "Oracle 11g DBMS_SQL Security Changes"


Late last year I published a paper describing a new class of vulnerability in Oracle I called "cursor snarfing". This involves causing an exception to occur in a PL/SQL package that uses DBMS_SQL and cursors but fails to close them in exception handling code. An attacker can then steal or snarf this cursor and potentially use it to compromise the security of the server outside of any application logic. Then in February this year I published a paper on "Cursor Injection" that showed how an attacker with only CREATE SESSION privileges could fully exploit any SQL injection flaw to execute entirely arbitrary DDL SQL - for example GRANT DBA TO PUBLIC. This is achieved by creating a cursor with DBMS_SQL and parsing the DDL statement. The cursor is then injected into the attack vector using the DBMS_SQL.EXECUTE function where it is executed with the privileges of the definer of the vulnerable code.

For Oracle 11g, Oracle has introduced some security changes to the DBMS_SQL package to help mitigate the risk of the problems presented in the two papers.

Firstly, cursors (which are referenced just by a number) are no longer created predictably. In 10gr2 and earlier the 1st cursor had a number of 1, the 2nd had a number of 2 and so on. When closed the number would be free to be used again. The point is it was trivial to guess or brute force the number and a cursor's value would typically be between 1 and 300 . 11g no longer generates cursor numbers so predictably - indeed they seem much more random:

1240272433
313122561
2112412728

These are three example cursors created via DBMS_SQL.OPEN_CURSOR. I haven't yet looked to see just how random these numbers and they may or may not be predictable [*] but regardless this is an excellent step forward.

The next improvement has been to shut off access to DBMS_SQL if someone passes an invalid cursor to one of the DBMS_SQL functions or procedures. This is also true of DBMS_SYS_SQL. Thus if I try to inject

dbms_sql.execute(1234567)

and 1234567 is invalid then I'll get an access denied:

ORA-29471: DBMS_SQL access denied
ORA-06512: at "SYS.DBMS_SYS_SQL", line 1528
ORA-06512: at line 1

The only way I can get access to DBMS_SQL again is by logging off and logging back on. The only function that can be called multiple times with impunity is the OPEN_CURSOR function. * Therein potentially lies a weakness. If the random number generator used when a cursor is created is weak then the ability of an attacker to quickly generate a large of cursors and get their values means that an attack could take place by prediciting the next value to be generated. A lot of good work has been done in the area of predicting PRNGs. [See my colleague Chris Anley's paper and Michal Zalewski's work like stompy.]

Further, a hidden parameter "_dbms_sql_security_level", which is turned on by default affects the OPEN_CURSOR function. A new addition to DBMS_SQL in 11g is the ability to specifiy a security level when opening the cursor:

curs = dbms_sql.open_cursor(level);

level can be 0, 1, or 2. 0 turns off security checking in DBMS_SQL but can only be specified if "_dbms_sql_security_level" is turned off. Opening the cursor with a level of 1 requires the executing/binding and parsing user IDs to be the same. Level 2 is more strict and requires id and roles are the same for all operations like binds, describes, executes, fetches etc.

A third change to DBMS_SQL is checking the user ID executing the query and the user ID of the person that parsed the query. If the two don't match an error is generated:

ORA-29470: Effective userid or roles are not the same as when cursor was parsed
ORA-06512: at "SYS.DBMS_SQL", line 1501
ORA-06512: at "SYS.DBMS_SQL", line 1506

Thus, if someone parses their attack query and then injects into the vector their SQL will not be executed.

As is, these three changes put a stop to the abuse that DBMS_SQL was susceptible to. Good work, Oracle. These changes show that someone over there's paid these problems serious attention.



<think>我们遇到了ORA-00942错误,这意味着“表或视图不存在”。当我们尝试将执行权限授予DBMS_CRYPTO包时,通常是因为这个包不在当前用户的模式下(它属于SYS用户),所以我们需要使用SYS用户来授权,或者使用SYSDBA权限。 解决方案: 1. 使用SYS用户(或具有DBA权限的用户)执行授权命令。 2. 确保包名称正确,并且当前数据库版本支持DBMS_CRYPTO包(Oracle 10g及以上版本通常都有)。 具体步骤: 以SYS用户(或DBA用户)登录,执行: GRANT EXECUTE ON SYS.DBMS_CRYPTO TO 你的用户名; 注意:如果当前用户已经是SYS,则不需要指定SYS,但通常我们不会在SYS用户下创建应用对象。 另外,如果希望所有用户都可以使用,可以授予PUBLIC: GRANT EXECUTE ON SYS.DBMS_CRYPTO TO PUBLIC; 但是,出于安全考虑,通常只授予需要使用的用户。 如果仍然遇到问题,可以检查DBMS_CRYPTO包是否存在: SELECT owner, object_name, object_type FROM all_objects WHERE object_name = 'DBMS_CRYPTO'; 如果查询不到,可能是数据库版本不支持(如Oracle 9i)或安装问题。 修正后的授权语句: GRANT EXECUTE ON SYS.DBMS_CRYPTO TO 你的用户名; 请将“你的用户名”替换为实际需要授权的用户名。 示例: GRANT EXECUTE ON SYS.DBMS_CRYPTO TO SCOTT; 然后,重新执行创建解密函数的操作。 另外,如果之前创建函数时已经报错,可能需要先删除之前创建失败的函数(如果存在): DROP FUNCTION decrypt_id_card; 然后重新创建。 总结错误原因:权限授予时没有指定包的所有者(SYS),或者当前用户没有访问SYS对象的权限。 注意:在Oracle中,默认情况下,DBMS_CRYPTO包的所有者是SYS,所以需要指定SYS.DBMS_CRYPTO。 如果使用DBA用户(如SYSTEM)执行授权,同样需要指定SYS.DBMS_CRYPTO,因为该包属于SYS。 因此,正确的授权命令是: GRANT EXECUTE ON SYS.DBMS_CRYPTO TO 目标用户名;</think>### ORA-00942错误分析与解决方案 **错误原因分析**: ORA-00942错误表示"表或视图不存在",但在授权场景下通常有3种可能原因: 1. **权限不足**:当前用户没有`GRANT ANY OBJECT PRIVILEGE`权限 2. **对象路径错误**:未指定`DBMS_CRYPTO`的所属schema 3. **对象不存在**:数据库未安装`DBMS_CRYPTO`包(常见于精简版Oracle--- ### 完整解决方案 #### 步骤1:使用SYSDBA连接 ```sql CONNECT / AS SYSDBA; ``` #### 步骤2:验证包存在性 ```sql SELECT owner, object_name, object_type FROM dba_objects WHERE object_name = 'DBMS_CRYPTO'; -- 正常应返回SYS.DBMS_CRYPTO ``` #### 步骤3:正确授权语法 ```sql -- 授权单个用户 GRANT EXECUTE ON SYS.DBMS_CRYPTO TO <你的用户名>; -- 授权所有用户(生产环境慎用) GRANT EXECUTE ON SYS.DBMS_CRYPTO TO PUBLIC; ``` #### 步骤4:补充依赖权限 ```sql GRANT EXECUTE ON SYS.UTL_I18N TO <你的用户名>; GRANT EXECUTE ON SYS.UTL_RAW TO <你的用户名>; ``` #### 步骤5:验证权限 ```sql SELECT * FROM dba_tab_privs WHERE grantee = '<你的用户名>' AND table_name = 'DBMS_CRYPTO'; ``` --- ### 特殊情况处理 **情况1:对象不存在(无返回结果)** ```sql -- 检查Oracle版本 SELECT * FROM v$version; -- 若为Oracle XE等精简版,需手动安装 @?/rdbms/admin/dbmsobtk.sql @?/rdbms/admin/prvtobtk.plb ``` **情况2:权限不足错误** ```sql -- 提升当前用户权限 GRANT GRANT ANY OBJECT PRIVILEGE TO <你的用户名>; ``` **情况3:12c+多租户环境** ```sql ALTER SESSION SET CONTAINER = CDB$ROOT; GRANT EXECUTE ON SYS.DBMS_CRYPTO TO <你的用户名> CONTAINER=ALL; ``` --- ### 最终验证 ```sql -- 创建测试函数 CREATE OR REPLACE FUNCTION test_crypto RETURN VARCHAR2 IS BEGIN RETURN DBMS_CRYPTO.RANDOMBYTES(4); END; / -- 执行测试 SELECT test_crypto() FROM dual; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值