找回密码
 注册
搜索
查看: 4643|回复: 0

[转载]通过对php一些服务器端特性的配置加强php的安全

[复制链接]
发表于 2004-5-31 00:23:03 | 显示全部楼层 |阅读模式
发布日期:2001-11-277 l! G$ o0 E0 }% x* P% x3 ~
文章内容:
0 O) b3 _4 A: U, p- d--------------------------------------------------------------------------------
* y; R; z; f) M1 R
) `. U4 M* b' n3 \. u% N: o作者:san(小许) san@nsfocus.com
* N1 y5 K& j0 U! U& ]& g2 q
9 Z# u" l' c: j" c% x--------------------------------------------------------------------------------
0 H6 |& h* M7 d2 O% v+ f/ R2 L/ c
前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以/ l0 j+ ~+ z$ c5 m' d( `
及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配
( f0 _8 `2 [0 a8 Y置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的
  Z  n  j% @7 O. E  D9 S过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的5 \2 J* C' i/ B5 J- I8 T+ `' h7 {
phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现8 m2 I& Z  @/ v: ^$ N9 R8 l
在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题" p  i" \% X$ Z/ d! B. ]
了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。
+ q0 H  g! i5 {) s
2 b7 c- O% F$ S! D$ O) _4 [% s3 _" \: G& W# G- R" L  d
1、编译的时候注意补上已知的漏洞 * G, X; c" y9 x/ T

# h& [: W- c- S+ F5 S从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突
0 A8 l6 p& Z2 Y; n  {2 s6 x* A; k& t! Z破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源) Y! r; c1 ^" N
码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件& F2 U" a" ?9 k* h& a3 A3 M; k
的第152行,也就是下面这行: * i0 n# _1 H2 ^

! w! W) \% T; F( i3 Cif (extra_cmd != NULL) {
7 Q0 }. R& a7 E
8 d# R$ }' j- s- g4 J* I; X5 H后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php
' Y+ H* d% t' m4 F那么我们就修补了这个漏洞。
& x: ^. o' U( [$ @& l# y* w0 l# A! N! P4 ^, j/ N

, H1 S3 ]' M7 x2 k0 v8 F" q2、修改php.ini配置文件
% s0 j" |4 a& R( B: h$ _  J! o% Y; p$ {/ ]4 m
以php发行版的php.ini-dist为蓝本进行修改。 6 A( K/ E/ m- g  q$ @$ D
9 z/ F+ V2 T" p
1)Error handling and logging
9 p1 C- Z- I/ w2 c0 u% J6 ^在Error handling and logging部分可以做一些设定。先找到: 1 I8 P; W2 l3 Z. j$ A! k
display_errors = On
7 S, t+ n" J+ U' \' M. S; G$ w- |# `+ T, ?
php缺省是打开错误信息显示的,我们把它改为: : n6 X" \; T. k  z, _

5 U, e% h8 u: c8 y& odisplay_errors = Off
* P3 ^+ o0 C# F, {* P. h) k3 ~0 B0 ?/ U: i. b
关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻0 W4 E! t% D, _" r$ w
击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造) P3 \9 O+ T& i+ k0 S( a
成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以* Z, n& c+ G0 r7 d4 R+ Y9 r
下: ' }- J6 K  w+ d0 \# E

$ h6 y8 p( `! O0 Y$ R! `log_errors = Off " q: c  X0 ^/ S& ^
" \" s4 N. Z3 J% `( j
改为: , y7 b: J. \$ L  G( U, p& c4 y$ R
log_errors = On # Y( ?7 F; V5 D/ E9 I

0 D% }& Z0 v& h1 ]以及指定文件,找到下面这行: 9 a  V" x: k5 r- M: k1 D. L# k

- M4 U  t1 K, N) W$ }3 z$ I;error_log = filename 4 j, n5 e; x5 z/ y
8 ?0 t2 q! J3 q0 M
去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log 0 s, L6 a6 T' R. V: [- X( c# U

+ g! o9 C6 e; a: P7 H9 herror_log = /usr/local/apache/logs/php_error.log
! r; j7 Z' N7 |/ L# c. b% ^4 z
) D) ]! s/ F0 D  F5 ~, Z7 d这样所有的错误都会写到php_error.log文件里。
7 `+ t' t5 b" d2 d% v- \  m  R6 X- \9 b
2)Safe Mode
; N4 h  z- v; ?+ E
8 e8 |/ C% t0 s: X# {. R6 Jphp的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在
& M: L" `/ B/ YSafe Mode部分找到: ) i: e+ t8 a3 s0 p3 K; N+ i6 G
) L! s8 P- U; E  b: i
safe_mode = Off
2 R3 m! S- t+ K" ?! g# _2 t$ A, H. ?8 Q4 I  S1 Z
改为:
1 ]8 E5 J8 L, [3 n/ k
. ]  s/ \) R( z9 r8 K: l) {safe_mode = On 1 J. V, s- s: ?+ L: Q: H

0 D" R& B% S( K: I+ P9 h4 r这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它
' h6 z; |" D9 [+ ]的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行
$ g1 d. p0 ?3 Z# g7 H6 f* ysafe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下: " ^, U& A& t* [, L8 |2 {3 f" N
, F/ B/ V4 N! Z) T& N
safe_mode_exec_dir =
: t( E6 I2 U! _8 u; r
0 o. C+ t# p, _1 w5 A3 [指定要执行的程序的路径,如: 4 v) r# c" l9 L+ v

2 x, K! y/ s" j/ Q5 H+ P. k$ ]safe_mode_exec_dir = /usr/local/php/exec + Q( {6 Q8 F3 R' K% D/ ^0 z) x6 r
; y6 ~9 @' E2 t$ Y7 i" H
然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行# f, Z$ b; c& g0 e
该目录里的程序。 % k: @4 s) k8 v2 a! \

! X, v, N: ?2 y) ^0 Z( i0 W3 N关于安全模式下受限函数的详细信息请查看php主站的说明:
& I  O, q6 r+ K# B% m$ i5 j4 k- Phttp://www.php.net/manual/en/features.safe-mode.php / V! L5 C2 M9 D$ m

$ c8 X4 R% }& E8 V+ A. U- j3)disable_functions
* `$ c1 p. A9 n: G+ q9 k5 z4 {1 A, t1 d' ]+ b
如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这
. S9 C/ [& L3 F" p) f' j- |4 i8 u行: ' m6 ]6 F' v9 p

% Y1 H& f8 k  }, y0 f; bdisable_functions = 4 @) o5 j; F1 B+ n6 Y$ j) r
  R0 Q2 @! \9 {* `0 L+ Q
在”=“后面加上要禁止的函数,多个函数用”,“隔开。
# D% f  `2 _3 _
. ?7 N. i0 N# w, F: F% o8 s+ {- X" N2 [/ E, r! E3 y9 K5 Q
3、修改httpd.conf 3 n2 x: `# y# R3 Z2 Q- ]8 D: Q
4 P: m! m. P* n& P& B0 O7 O
如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作6 G. J+ E! R% U& B+ a
路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行:
0 H5 L$ o# I- U7 F( v( l+ V* Z( w  _7 E, B/ m2 A" P; L
<Directory /usr/local/apache/htdocs>   e/ K4 l8 k4 l7 p  g+ Z' o
php_admin_value open_basedir /usr/local/apache/htdocs
  ]* S$ I5 |) Y0 j: C</Directory>
( o3 o9 ?  o5 ]! e; e9 |
. x% O, e& O9 v这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打( g' j' c8 D# w! P# O
开的话会提示这样的错误: & z* U; @  V0 L& w  P! y

  f7 h& _+ c9 P' e* hWarning: open_basedir restriction in effect. File is in wrong directory in
$ D$ |" F# v9 f! C) F* ~/usr/local/apache/htdocs/open.php on line 4 7 G+ |0 |9 w8 ?. _- M$ X

' ^% o) J9 A+ k等等。
8 m4 N# ^% a% t: ]1 n+ B) A
; l4 G: X8 P5 t7 T6 Z( P, D' x3 {2 I2 n' s$ I
4、对php代码进行编译 " t; ]* P# b4 h' ]
4 ^' q2 R! o3 n( W6 C
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和5 ^" P1 \9 E  b9 o
ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就
7 n# o9 `+ t; V8 G1 O/ O! G( H. n# A可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统" V! M2 V' m' G* t  p9 _

# C2 P, {0 k' f  ]6 E; t+ |! J4 {3 i5 M6 o4 w- f
ZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz
* I: `9 a3 [# D; P0 H8 ?! M" m) k0 aZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz 8 k) w& T. r. N
ZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz
1 f" m- Q- e2 Q* Z6 z) G" ZZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip
, ~* G" r/ M( r! I
, l4 Y1 K1 f5 l) s0 `+ c优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里
/ F; x) u0 n" N1 s, _( M1 Q: G的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句
+ A. Z7 ~/ r: a+ r$ f5 W( Q7 V: r6 ^9 V6 w8 s9 m3 D

! t2 I# B  A7 q8 V3 v2 O0 f  `& tzend_optimizer.optimization_level=15 ) I. a5 A+ P& n! ?5 |6 i
zend_extension="/usr/local/lib/ZendOptimizer.so" " [# W$ V9 a5 H% ?+ q
6 X/ d# E! U# `  v4 z, L+ y* W
就可以了。用phpinfo()看到Zend图标左边有下面文字:
/ a+ w/ K2 m: B. p) ~3 M4 h
4 y& n6 ]% |1 E% e  Zwith Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies ; |4 _2 d9 m+ V& s. P  {7 i+ l

, j( t$ b' @, o那么,优化器已经挂接成功了。 : v* |4 v" e/ q1 F6 V8 y
# z/ P" K, @8 ^1 t
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设
0 _* ?$ G# _4 [$ p计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。
, g7 b  ]9 F7 S. H" a, c4 N9 N& r+ E: ]
php脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进* D6 M- @4 z2 }( g# _
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如4 \+ t" j+ E# L# ]' Q0 D5 h
mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。
' Q( s( g# _0 a/ R
( M/ H6 R2 P: c: Q7 y, i- p2 K2 O! U# w6 v
5、文件及目录的权限设置
, ]2 t* x) N; H6 f/ \$ p7 p% n3 C# y4 V* N1 r0 @  v: g
web目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
* ~0 E+ l3 Y: d* H( R' {: N攻击者可以修改主页文件,所以web目录的权限一定要设置好。 ; @; W/ r. g( s) x/ ?& y) h
! I! m& ]5 x, z- L# K  `  R
还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属+ l6 K% J# m5 |& c7 I" ^& N
主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的, a* R  V" G; F; p; U0 t* ~: X
错误: 0 M1 I9 ~/ ?2 Z6 Q
& l7 Z0 C' ]; ]- u) O3 a( |5 y
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not
+ M- _/ K9 i  p% R8 H8 B1 {allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php / g4 \  c6 h  t4 b/ \* H
on line 3 ! D. s- l0 x" S( O4 ~: Z+ j* H; [

& y4 D: w7 @  i5 I/ _5 ]这样我们能防止许多系统文件被读,比如:/etc/passwd等。
5 y  ]* b# I6 A3 n  \0 l3 ?9 i: r上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。
  y# {6 b  y+ Z* A9 Q1 x% \% q1 F/ m+ O. J/ E# f" T% A5 b# ]
% U4 Y( S0 L: N6 H8 m* ?
6、mysql的启动权限设置 8 x2 X0 W/ ]0 Z3 N* S+ b# w: p) p2 A- q4 y
7 T+ W* G1 L8 x5 s6 }! W# K. N
mysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等- E  I( ^8 p2 o5 J
系统启动脚本里加上一句:
$ c) b/ H2 c/ p3 ^5 m; y
2 @* Z+ \5 J- Isu mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start" : c. y: M6 M: C4 v* T
% C- I( Q2 N5 @. S& U# |% u2 W
这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 7 V9 p. _$ g5 e$ C7 s: D/ c
! I8 y# w/ `. b6 l. z% z2 s
& g0 P' E6 ^7 ^9 D5 T8 _6 x
7、日志文件及上传目录的审核及 * A' W' d; J2 y1 d! z% h
. A( `0 x, G( p1 D
查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且
" u% J3 n2 c2 d也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非
8 {9 w& ?$ A" c0 E& V( R法的文件,比如执行脚本等。
5 J, b+ B* R- \. u3 n5 v! {" f2 B' ~" X  U

# p, {9 K4 \. |( ^8、操作系统自身的补丁 * E, v# M3 a; S4 P
, o: X) a% w" o4 i8 f- Z
一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。 7 T! q* R* |! e) F6 Q: [. Y
; M) n( B1 R3 K; B
% z, Z1 k! {# f$ j3 M9 m/ \
经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,& G+ X0 }" n9 j- c
即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 # v! ^* I- j- t! j
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;)
& B. F- l1 m" Q
/ t4 z0 h0 Y; I! [; b1 D, T+ e, A+ V# \( v; E
参考资料:
  Z) F8 g# c% j/ ^* V  \PHP Manual
  v0 s1 B! B" W% Y7 jhttp://www.zend.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2025-9-30 09:05 , Processed in 0.035250 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表