oracle延时约束的问题

本文探讨了SQL中约束的概念,特别是not null约束的deferrable属性如何影响数据表的索引选择。通过实例展示了当约束设为可延时验证时,即使存在not null约束,某些索引也可能不会被使用。

约束可以是deferrable或not deferrable(默认)。
可延时约束在创建后可以修改成约束延时检查
deferrable表示该约束是可延迟验证的. 它有两个选项:
Initially immediate(默认): 立即验证, 执行完一个sql后就进行验证;
Initially deferred: 延迟验证
下面的例子是摘自oracle编程艺术

create table t(x int constraint x_not_null not null deferrable,y int constraint y_not_null not null, z varchar2(20));
SQL> insert into t select rownum,rownum,rpad('x',20,'x') from all_users;

32 rows created.

SQL> commit;

Commit complete.

SQL> explain plan for select count(*) from t;

Explained.

SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2966233522

-------------------------------------------------------------------
| Id  | Operation      | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      | 1 | 3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      | 1 |        |      |
|   2 |   TABLE ACCESS FULL| T    |    32 | 3   (0)| 00:00:01 |
-------------------------------------------------------------------

Note

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
-----
   - dynamic sampling used for this statement (level=2)

13 rows selected.

SQL> create index idx_x on t(x);

Index created.

SQL> explain plan for select count(*) from t;

Explained.

SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2966233522

-------------------------------------------------------------------
| Id  | Operation      | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      | 1 | 3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      | 1 |        |      |
|   2 |   TABLE ACCESS FULL| T    |    32 | 3   (0)| 00:00:01 |
-------------------------------------------------------------------

Note

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
-----
   - dynamic sampling used for this statement (level=2)

13 rows selected.

SQL> create index idx_y on t(y);

Index created.

SQL> explain plan for select count(*) from t;

Explained.

SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 4266017364

------------------------------------------------------------------
| Id  | Operation    | Name  | Rows  | Cost (%CPU)| Time     |
------------------------------------------------------------------
|   0 | SELECT STATEMENT |   |     1 |     1   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE  |   |     1 |        |      |
|   2 |   INDEX FULL SCAN| IDX_Y |    32 |     1   (0)| 00:00:01 |
------------------------------------------------------------------

Note

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
-----
   - dynamic sampling used for this statement (level=2)

13 rows selected.

可以看到x上的索引没有被使用到,因为指定了这个not null的约束是可以延时的,也就是说这个列中能保存空值,所以无法使用x上的索引
设置约束为延时约束
SQL> set constraint x_not_null deferred;

<think>我们正在回答用户的问题:比较MySQL、Oracle和SQLServer在SQL注入方式上的差异根据用户提供的引用内容以及之前对话中提到的引用,我们可以总结如下:引用[1]提到:Oracle和PostgreSQL的实现较为复杂(在XML或自定义函数方面),而MicrosoftSQLServer较为直观,MySQL受限于Windows环境和文件操作权限。这说明在利用特定功能(如文件操作、自定义函数等)进行注入时,不同数据库有不同限制。引用[2]提到:延时函数在各数据库中的不同:SQLServer的waitfordelay、Oracle的DBMS_LOCK.SLEEP等,说明时间盲注时使用的函数不同。引用[3]提到:Oracle的客户端工具sql*plus的使用习惯可能与MySQL命令行不同,但这不影响注入方式,仅影响手动注入时的操作。引用[4]:展示了一个Oracle中分页查询的例子,这说明了在分页查询中利用rownum进行注入时需要注意的细节(比如需要给rownum起别名)。结合这些引用以及我们所知的其他知识,我们按数据库类型比较SQL注入方式的差异:1.注释方式差异:-MySQL:可以使用`#`、`--`(注意后面有空格)或`/**/`-Oracle:只支持`--`和`/**/`,且要求更严格(有时需要空格)-SQLServer:支持`--`和`/**/`2.字符串连接符:-MySQL:使用空格或`CONCAT()`函数-Oracle:使用`||`或`CONCAT()`(但CONCAT只支持两个参数)-SQLServer:使用`+`3.信息获取:-MySQL:系统表`information_schema.tables`等-Oracle:系统视图如`all_tables`、`all_tab_columns`等-SQLServer:系统表如`sysobjects`、`syscolumns`等或信息模式视图`INFORMATION_SCHEMA.TABLES`4.盲注技术中的差异:-布尔盲注:MySQL:可以利用条件判断语句(如`IF`)但通常在WHERE子句中直接用条件Oracle:可以使用`CASE`语句或`DECODE`函数SQLServer:可以使用`IIF`或`CASE`-时间盲注:MySQL:`SLEEP()`、`BENCHMARK()`Oracle:`DBMS_LOCK.SLEEP()`SQLServer:`WAITFORDELAY`5.利用文件操作:-MySQL:通过`LOAD_FILE()`读取文件,`INTOOUTFILE`写文件,但需要权限-Oracle:使用`UTL_FILE`包读写文件,但需要配置目录对象-SQLServer:使用`OPENROWSET`读取文件,`xp_cmdshell`执行系统命令(可写文件)6.执行系统命令:-MySQL:通常不能直接执行系统命令,除非通过UDF(用户自定义函数)扩展,但需要FILE权限和共享库-Oracle:可以通过`DBMS_SCHEDULER`或`Java`存储过程执行命令-SQLServer:通过`xp_cmdshell`执行系统命令7.分页查询(用于盲注或数据提取):-MySQL:`LIMIToffset,count`-Oracle:使用`ROWNUM`和子查询(如用户引用[4]所示)-SQLServer:使用`OFFSET`和`FETCHNEXT`(2012版本及以上)或`TOP`和子查询8.错误信息利用:-MySQL:错误信息可能包含路径或部分查询结构-Oracle:错误信息通常较为详细,可能包含行号、列名等-SQLServer:错误信息可能返回完整查询结构9.堆叠查询(StackedQuery)支持:-MySQL:默认情况下,PHP的mysqli扩展不支持堆叠查询(但PDO可以),因此堆叠注入在MySQL中可能受限-Oracle:不支持堆叠查询-SQLServer:支持堆叠查询(例如:`SELECT1;SELECT2;`)10.XML利用(如引用[1]提到):-Oracle和PostgreSQL的XML操作相对复杂,而SQLServer较为直观,MySQL也有XML函数但相对简单。11.权限差异:-MySQL:权限设置相对简单,需要高权限(如FILE权限)才能进行文件操作。-Oracle:权限模型复杂,通常需要DBA角色或特定包的执行权限。-SQLServer:权限与Windows域整合,通常以服务账户权限运行,如果以高权限运行则攻击者可能获得系统控制权。这些差异使得攻击者在针对不同数据库时需要调整注入策略。例如,在时间盲注中,延时函数的名称各不相同;在利用文件操作时,需要的权限和函数也不同。因此,在进行SQL注入攻击时,攻击者通常需要先判断数据库类型,然后再选择对应的注入方式。我们应将这些差异整理成一个表格,以清晰对比:|特性|MySQL|Oracle|SQLServer||------------------|----------------------------------------|---------------------------------------|---------------------------------------||注释符|`#`,`--`,`/**/`|`--`,`/**/`|`--`,`/**/`||字符串连接|空格或`CONCAT()`|`||`或`CONCAT()`|`+`||系统表/视图|`information_schema`|`all_tables`,`all_tab_columns`|`sysobjects`,`syscolumns`或`INFORMATION_SCHEMA`||时间盲注函数|`SLEEP()`,`BENCHMARK()`|`DBMS_LOCK.SLEEP()`|`WAITFORDELAY`||文件读写|`LOAD_FILE()`,`INTOOUTFILE`(需权限)|`UTL_FILE`包(需目录对象)|`OPENROWSET`(读),`xp_cmdshell`(读写)||执行系统命令|需自定义UDF(困难)|使用`DBMS_SCHEDULER`或Java存储过程|`xp_cmdshell`||分页查询|`LIMIToffset,count`|`ROWNUM`和子查询|`OFFSETFETCHNEXT`或`TOP`||堆叠查询支持|受限(依赖于驱动)|不支持|支持||错误信息利用|可能暴露路径|详细,可能包含行号、列名|可能暴露完整查询结构|最后,根据引用[1]中的防御建议,无论使用哪种数据库,都应使用参数化查询(预编译语句)来防御SQL注入。我们将按照上述内容组织回答,并生成相关问题。</think> 以下是MySQL、Oracle和SQL Server三大数据库在SQL注入方式上的核心差异分析,结合技术实现、攻击手法和防护难点进行对比: --- ### 一、技术实现差异(基于数据库特性) #### 1. **MySQL**: - **文件操作限制**:受操作系统权限制约(如Linux文件路径限制) - **延时盲注**:使用 `SLEEP()` 或 `BENCHMARK()` 函数 - **信息获取**:依赖 `information_schema` 系统表 - **堆叠查询**:仅当驱动支持时生效(如PHP的PDO) ```sql SELECT * FROM users WHERE id='1'; SHOW TABLES--' ``` #### 2. **Oracle**: - **复杂性高**:需构造XML路径或自定义函数(如 `UTL_HTTP`) - **延时盲注**:调用 `DBMS_LOCK.SLEEP()` [^2] - **分页查询特殊限制**:`ROWNUM`需别名才能注入(如 `ron > 2`)[^4] - **客户端工具**:依赖SQL*Plus(命令行)或GUI工具[^3] ```sql SELECT * FROM (SELECT test.*,ROWNUM ron FROM test) WHERE ron>2 AND 1=utl_inaddr.get_host_name('payload') ``` #### 3. **SQL Server**: - **直观性高**:语法更贴近标准SQL(攻击者友好) - **系统命令执行**:利用 `xp_cmdshell` 执行OS命令 - **延时盲注**:`WAITFOR DELAY '0:0:5'`[^2] - **错误信息利用**:错误页面常暴露完整SQL结构 --- ### 二、攻击手法差异 | **场景** | MySQL | Oracle | SQL Server | |------------------|----------------------------------|---------------------------------|--------------------------| | **信息获取** | `UNION SELECT @@version` | `SELECT banner FROM v$version` | `SELECT @@version` | | **延时盲注** | `1' AND IF(1=1,SLEEP(5),0)-- ` | `1' AND DBMS_LOCK.SLEEP(5)=1--`| `1'; WAITFOR DELAY '0:0:5'--` | | **文件读取** | `LOAD_FILE('/etc/passwd')` | 需`UTL_FILE`包权限[^1] | `xp_readerrorlog` | | **命令执行** | 需UDF扩展(如`lib_mysqludf_sys`) | 通过Java存储过程 | `EXEC xp_cmdshell 'cmd'` | | **权限提升** | `FILE_priv`控制 | 依赖DBA角色授权 | `sysadmin`角色控制 | --- ### 三、防护难点对比 1. **MySQL**: - 默认禁用堆叠查询(需特定驱动) - 文件操作受OS权限强约束[^1] 2. **Oracle**: - 复杂功能(XML解析、Java扩展)增加攻击面[^1] - 系统包默认禁用(如`UTL_HTTP`) 3. **SQL Server**: - `xp_cmdshell`易被滥用(默认禁用但仍可激活) - 错误信息泄露风险更高 --- ### 总结 - **MySQL**:侧重文件/OS操作权限限制 - **Oracle**:利用复杂度高(XML/自定义函数)[^1] - **SQL Server**:攻击直观性高(OS命令执行风险突出) > **最佳防护建议**: > 统一使用**参数化查询**(如`PreparedStatement`),禁用动态SQL拼接。Oracle加固系统包权限,SQL Server关闭`xp_cmdshell`。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值