晚餐吃撑了,瞄下代码消化消化。最近Php0day群里的兄弟都在讨论dede洞多,赶紧下了套,用editplus搜索了几个关键字,果然发现些问题。(话说平时写代码也喜欢用editplus,小巧方便多年习惯)) u$ O& h1 ?- h6 k; U0 D$ E' l0 J
0 U$ l3 m# Y1 q
出现漏洞的两个文件为:
7 w$ H q( }0 Z- z% N! ~9 bInclude/payment/alipay.php
* u0 Z: S' G' g( w* h( F9 r. f: fInclude/payment/yeepay.php
6 @. L- A1 R) j漏洞均出现在respond方法里,估计这两个文件是临时工写的。
3 S4 _' P; O3 a# b8 @# a
8 Q1 M, X( b- w- f5 y) JInclude/payment/alipay.php
" b, Y( V7 t; f2 {' z, E& V; |6 z4 t& c; k' t! C( \/ h. ^# f
......
( U# U5 r) |" j9 S8 ?6 q function respond()
- l) j! Q" E7 }: ?0 U {
8 d& a& j' ~/ j2 h& X3 t+ Q1 M if (!empty($_POST))
+ F( o( N2 l# Z4 U {
' \! k$ l0 ^$ r/ J! q3 e foreach($_POST as $key => $data)& W( `9 j$ G( c, k. Z. g. w
{8 Y3 S2 h' X: w z- K
$_GET[$key] = $data;* k9 j# ~- s- y; Q7 o* M7 [
}: _2 F' Z* M0 `( r) U
}
) c) I, D2 G1 }: _! l E5 R9 p" U/ _* { /* 引入配置文件 */
8 G4 m, p. W! y; b1 K require_once DEDEDATA.'/payment/'.$_GET['code'].'.php';8 Y3 ~4 M2 I$ B2 P$ D, Y
......
, y9 M1 h2 L) i' T T. p, {
% J5 E4 |# b" [. }: ]
' d: w) ~- A s0 l, U2 ~大概在133行左右,$_GET[‘code’]没有经过任何判断和过滤。3 Q1 v4 L8 @) x+ d, q
, h: R! l/ b: W) }# j+ g9 }4 u+ m
Include/payment/yeepay.php
# ?5 I# M# y; D! ^/ }
4 {9 A+ |. h H9 x: r7 v O
( \2 p) ~; R- Y0 g9 A9 z0 h* ^' h9 k# F) N6 H" |
......$ K: C" N9 I. y& m7 c+ q
function respond()) Z& k% I$ s: [
{
( l8 L0 a) u( N2 l- x( H/ h l0 h0 f2 u+ d7 m& I
/* 引入配置文件 */" l; V4 j( e' o+ i/ F4 }' j' p
require_once DEDEDATA.'/payment/'.$_REQUEST['code'].'.php';2 k4 W6 L8 i- ^( B, b* M
- k, h2 V- @2 S
$p1_MerId = trim($payment['yp_account']);% o4 {7 x: N& v3 T: `* ?' k4 |5 j2 Q
$merchantKey = trim($payment['yp_key']);3 B0 `( m5 G2 [% U
...... 2 h5 _& N6 m; V! W: R
8 \* q1 ?8 P5 ?3 ~, B: [. k7 J
; m; ?5 v( h( F, z7 v
! q, K& P# ^9 {5 N, y& z9 ~ w6 Z; {- n# s/ w# Q
大概在145行左右,$_REQUEST['code']没有经过任何判断和过滤。4 T3 f, F: }+ k+ s/ ]) n) b8 Z
' w4 _0 a" i0 f0 N* W
这两个方法在plus/carbuyaction.php文件调用。
. k& K, F* F" e3 z- @, D* B# f0 s. O2 p( K& J7 K1 m/ q8 A* z
plus/carbuyaction.php6 v7 g' H' N; D
0 l# U, _( w" @1 |
......
8 a, R) b a s1 _} else if ($dopost == 'return') {
3 w; {2 ^: y8 Z1 d0 ^ $write_list = array('alipay', 'bank', 'cod', 'yeepay');
# J9 Y/ a4 N, j9 p( b if (in_array($code, $write_list))5 W3 h& F R8 D5 C! w" X! Y
{# A+ V! j/ @- r i8 d
require_once DEDEINC.'/payment/'.$code.'.php';
4 I% I5 s% b5 i5 C! A: f+ [ B $pay = new $code;
. R( g. @, t2 b3 [ $msg=$pay->respond();3 j, Y3 `& b: r% v2 b! H: F( H
ShowMsg($msg, "javascript:;", 0, 3000);9 D1 J( V$ b1 `; s7 N5 ]' p
exit(); ( R& b( a) d3 O- t
} else {% S2 F8 n/ A" g4 I: q: D' [
exit('Error:File Type Can\'t Recognized!'); Q0 x' G5 P: M2 q6 F8 v
}
8 T" M% k1 ~, p0 h4 p6 B# \" n}' M2 ? v5 E9 N( v3 ^% ?
...... $ z& x$ ~$ a6 b! h
8 O& H5 _, X4 \6 u m6 m6 E: e& y$ } W* z* ~5 C0 b
9 g+ q4 v: H5 p ~1 O, Z+ N& R8 X" P
. G# D0 \. r, @# _- m+ ^ O
# t4 ]! g1 y6 [! u/ \
% S; e$ R9 F* t$ N* F大概在334行,当$dopost等于return的时候就开始进入过程了。熟悉dedecms朋友都知道在include/common.inc.php使用了一种类似register_globals的机制。
4 g7 E& f- |9 n# O2 C0 Y所以$_GET['code']或$_REQUEST['code']会变成$code,而$code是经过判断的,值必须在$write_list数组以内这样才能继续后面的流程调用respond方法触发漏洞。这样的话貌似就无法控制$_GET['code']为任意值了。
( W. r/ m( _; _* N5 b% ^4 ^9 F
" c+ v- F9 S0 i d. k0 P6 ?" H* B回到include/common.inc.php来看看他的机制。
( A( ~+ t* }7 l6 X8 [/ I: W% v+ B0 V* H" K
8 h7 M% B6 Y0 {' [6 }) Z2 z5 [% @
) }1 M, O8 |5 O2 T. C, D......
" k- B5 V2 ^% K* ~* rforeach(Array('_GET','_POST','_COOKIE') as $_request)3 }' S0 J& `) ^! m, \1 H
{
8 ]: Q2 }( o& N @& v4 N* U foreach($$_request as $_k => $_v) $ I( f: k/ e/ z2 |
{
) z5 P8 d9 ^2 j9 l7 P9 C if($_k == 'nvarname') ${$_k} = $_v;
# H. h5 y8 H2 a+ O0 E. } else ${$_k} = _RunMagicQuotes($_v);
2 d5 L% `$ E/ b }
# e( s, B8 \7 w- D% u}
+ F' h$ B3 X. R...... & j3 E) `6 i* }5 X: o& C" i
大概在79行,可以看到他是从$_GET,$_POST,$_COOKIE这三个全局变量里取值的。嘿嘿,细心点就发现了吧。从他这个优先机制来讲他是先从get再从post再从cookie也就是说最终$code会是以$_COOKIE[‘code’]的值为准,而我们要控制的是$_GET[‘code’]或$_REQUEST['code']只须要$code的值在$write_list数组以内就行了。Exp:http://www.php0day.com/plus/carb ... amp;code=../../tags上面的Exp是包含根目录下的tags.php文件包含其他后缀请自行构造截断,使用exp测试时须要自己添加一个code等于alipay或yeepay的cookie。暴路径:
( \: h: t& ]% A3 X3 S" W( ~8 k由于bank和cod这两个文件并没有respond方法,所以如果code等于bank或者cod时将会暴错泄露路径。注:请勿非法测试,产生后果与本人无关。 |