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

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

[复制链接]
发表于 2004-5-31 00:23:03 | 显示全部楼层 |阅读模式
发布日期:2001-11-27; ], h0 }1 g# }- q8 O: {. a
文章内容:
5 L: \( l+ Z4 `, D+ y0 @8 M--------------------------------------------------------------------------------% L+ G( v; R( Y2 @4 T$ L$ Z  r3 Z
9 H+ e. ]2 [- [9 P5 F2 a  E
作者:san(小许) san@nsfocus.com 3 I/ |7 z9 A# O) [1 y- u
1 {# Z$ F$ g% w0 _, t
--------------------------------------------------------------------------------. X. w& C( f  b# j
: A$ u- N; W  V$ q
前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以
: ?7 j2 T" W& W0 Z' f及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配$ |. ?8 V+ W) ~4 V
置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的2 E7 M. {! L$ O8 c$ I; |
过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的
0 ]" V, p9 _0 |3 I$ a" `# {4 ?phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现+ T& Q0 o, w& U
在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题
' ?3 F6 P$ K& g9 X! J+ z+ e( ^( s了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。 & |3 L1 Y  C9 ?) o
; I  `' D9 s; ^3 U+ `% J
) V" R0 \6 V& n+ l, y
1、编译的时候注意补上已知的漏洞
, c6 g; [0 D( C( h
8 v8 ?8 C5 p1 k, A' _+ N# h6 y( Z( Z, q3 J从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突
4 M1 u) |: E" o& J. W) Q; z5 i4 V破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源2 G' v  l" |8 X: K1 H% c
码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件# @5 A$ d! k" n+ I
的第152行,也就是下面这行:
; |" ^* Q: R% B& z2 R: R5 @2 `0 x* _8 n& z5 a! D
if (extra_cmd != NULL) { - s3 g% J! g, M, N+ w+ F4 q& {; l

# M# E3 g; _( G% K后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php
: V3 L; d( _, r那么我们就修补了这个漏洞。
: d* Q% Q" l" B5 C' ]( ?( t8 w: W" l
  J3 S$ h% F5 O& e7 p% \
' n5 u5 w- L# S4 @2、修改php.ini配置文件
$ s( r* M3 V' n+ T( U
. f+ P' y, e% N; F3 D: \0 [9 B6 x" j$ d以php发行版的php.ini-dist为蓝本进行修改。 6 W; K0 t5 q3 A( i

' s( G: \2 K% `1)Error handling and logging
: u2 H& l* ~4 L6 f在Error handling and logging部分可以做一些设定。先找到: 3 u* q1 ]& @; Z. x
display_errors = On
3 O* T# \! E7 _) ?( l4 A8 K: J/ i
) |  n6 ?* N$ t9 `1 Iphp缺省是打开错误信息显示的,我们把它改为: 0 z$ |& S+ e7 ?! ~% n; F
$ p+ o# i# j1 T1 P% V
display_errors = Off
( E* D; A4 m  I& t" @; l( W: g  g
* k8 ^  Q) {1 D. d6 W( w  m关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻4 h' [8 J; {; ]0 Y2 ~7 f# O
击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造# W5 Y2 T5 d: X6 D9 ?
成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以5 v! G6 r! p! m& H* N
下:
4 {5 l! t  D# ^3 X
% U) ~2 f- P2 D, F2 Ylog_errors = Off
5 y1 t+ \7 F+ ~! ~  q& J/ g/ Y* ~" Q, Y" ^
改为:
9 S! f! ]. c2 G3 R7 w6 ~% [log_errors = On ; T5 Q. S9 ?4 ~/ H' q3 f

. v/ m( V' N2 E5 h( X: a8 u以及指定文件,找到下面这行:
+ s1 \$ I! N0 f  n7 Y* y4 G; U0 D, s- W$ c- l2 p
;error_log = filename / _7 v9 r' L7 g4 a$ h8 S% e
  u  \, ], r4 o
去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log
" }+ u" d& h8 Q! F3 h  s
! A  o8 O/ c$ h0 F6 {$ gerror_log = /usr/local/apache/logs/php_error.log - ?: p+ u5 l$ {! W" i; a

5 ^+ o' m+ ^/ h) }+ }这样所有的错误都会写到php_error.log文件里。 . _* h0 b7 C- f  A

' M+ ?# |7 u! f9 k; D$ J2)Safe Mode ; d$ m6 B( R! f" A0 j: x

, ^$ {1 y6 i% a) E4 F( xphp的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在9 ?8 m2 t/ z( L8 j# |- O
Safe Mode部分找到: # D+ r5 |7 Q2 @# g) s' I+ g
; S* j% J0 F; r+ R5 A# ]4 D
safe_mode = Off
* N0 e) @: a. V. v+ l
, m6 R/ Z4 o; ?3 f& Q- b6 Q6 j, O7 }( X改为: 7 k5 Q8 `( x4 v0 D& a
, R8 H" D6 h5 o8 t) v
safe_mode = On
% t6 Y: r+ a2 n' H& b0 p
6 [; y+ d5 a, i/ Q这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它
. c" a# w( W* y+ ^" D5 D! Z0 O- g: X的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行3 ?) K6 x' }9 {# ]# p8 l% B, p& v* l
safe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下:
3 X* I8 A: j: N: P. Y) q) P7 I9 u, _' s$ j
& @' T- r; J* o0 Bsafe_mode_exec_dir =
( e+ Q2 L  A" b2 N
" [6 o+ n' H( A! a7 b指定要执行的程序的路径,如: . i' y; a: I$ n! E* ?7 A

  L. {% V- s+ u9 ]0 Y) J2 n# ksafe_mode_exec_dir = /usr/local/php/exec
4 n5 Z. E3 P7 k# W! N4 k' T1 e! k, `5 K9 B) S6 ?- ?( G
然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行" g3 }3 F3 Y0 ], V) e; f
该目录里的程序。 " V. W- c; }# D6 ^. g$ T) m% |: B
; I$ M4 h4 ^# _* u- |1 S
关于安全模式下受限函数的详细信息请查看php主站的说明:
" Y7 G( X  ^# `% z- M: X; \http://www.php.net/manual/en/features.safe-mode.php 4 t  k: P7 ^: g) O" H- ^* D

: h1 I9 \* z" l  {6 |& [( U3)disable_functions
3 z& O$ l3 p$ k) K. m7 ?# ?& [9 X3 e2 ^& \5 Y- k
如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这
4 U3 T5 N2 x; y& ^& ]- G% ~行:
! N+ V) S: X6 R  y( n9 e( Q2 \5 z5 F+ |7 |
disable_functions = ; S* o/ L: a3 g4 s' q
$ R8 e3 v9 M3 k7 R2 P( W: }
在”=“后面加上要禁止的函数,多个函数用”,“隔开。 ; G2 r7 y' ]' U0 |5 e+ N& A, J. J# A

# I7 X2 |' A/ F: ]& g' j3 L. X' y/ M4 X6 \  U
3、修改httpd.conf 8 M  Q1 b# R' A* Z* Z6 S1 ~0 h( J

) l9 D6 U8 Y, x' L: f如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作' w9 }8 ~# f/ t6 C  e3 p# X
路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行: / }( h2 O% s  F$ W$ B
7 G0 }4 P" x3 ]4 f2 m
<Directory /usr/local/apache/htdocs> # u( ]: V4 [% Z" k3 Q2 [5 t  t- ?
php_admin_value open_basedir /usr/local/apache/htdocs 5 z. W2 i. h# j2 I
</Directory>
0 r' a2 i& N# e
# f9 J4 ~; Q0 b+ X' l% p这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打/ u+ B7 D% C2 H0 r4 z
开的话会提示这样的错误: 8 h# R4 e0 b& p) k& b$ O2 A  m

  L+ f+ o0 @& T9 GWarning: open_basedir restriction in effect. File is in wrong directory in
( b3 B1 h: l# y% r; B6 c/usr/local/apache/htdocs/open.php on line 4 9 c: h: V( Y) x5 J3 y/ O) ]

& l! n2 Z! c$ u& t( V8 N等等。
) r: D" _5 r+ T& b4 Z2 B6 ]  M6 s' N, u5 R2 t4 K! a0 d7 c

0 q' j7 u1 L7 b- [4 Y8 [4、对php代码进行编译
- I9 w0 h  _8 ^/ K. m) B' G5 X" V0 l5 D1 k( t" [
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和& m; V0 C+ c6 K& G; v% M
ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就* Q( b$ f- R4 ]. u5 T9 [: j1 F
可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统
/ c' K7 R8 O' \; k
/ C: m; a9 t$ g  K1 ]* h# A" \  W6 j7 v! r) y3 q- x
ZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz
: C  E4 V* ^# ]ZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz $ u( r; L- e' i8 x3 ^
ZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz
" i$ i1 _: Q" Y. e) C- CZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip ) k; y! d8 \2 C& k7 e# W- m! N

, t: G7 Z/ H, u- X3 N( I优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里# y0 Y6 x% A8 i- p4 z8 o( b7 d
的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句* H9 s- j% ^7 |" O

2 \' R9 Y, d$ Y. _! C+ U6 J9 ?, M
% o$ G$ j3 e! B, `1 _zend_optimizer.optimization_level=15
& e0 @, [/ F; Q  Mzend_extension="/usr/local/lib/ZendOptimizer.so"
0 ~6 W5 I8 {7 d5 C& r: Q6 T1 P, I
6 g5 \% o, u, Y7 j- _就可以了。用phpinfo()看到Zend图标左边有下面文字:
7 g- s% Z7 \% _1 @8 v
9 V; Y+ F$ Q* b* h; z9 v$ Bwith Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies
8 d& R* I% U/ k2 R2 o% g% z8 I6 U1 I9 m8 a/ h7 m, d+ J
那么,优化器已经挂接成功了。
7 v2 ?: f( O( K; }1 u& b+ K+ ^- [: v
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设5 v! D/ F) I  k" ?9 w
计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。 # `! S& L. Z8 ^$ }' ~( _

+ x- c* `- v) ?) lphp脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进' S# A8 X0 k  }4 |3 v/ g# ?
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如4 M3 B0 d. W/ H  o  a- n
mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。 8 d' t0 a# U* {. c* A9 y

1 B& F* W3 L$ A& d/ C/ s! X: r) \- v+ L
5、文件及目录的权限设置 * Y" A& T! |" c3 w

) U2 j. D) z$ `  w! l; Cweb目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
4 J6 M# M: I/ [' ?, \$ }攻击者可以修改主页文件,所以web目录的权限一定要设置好。
6 U; {" _$ j9 w/ T3 i* d8 z5 M; |- ~# r: Y
还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属
  E9 F; G1 \1 k5 P主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的
4 E* f$ ^7 D$ i" L, R错误: - J6 M+ Z- ], l$ B2 X; z

6 s' l8 m" _& mWarning: SAFE MODE Restriction in effect. The script whose uid is 500 is not . j; W" Q# h  M
allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php
8 E" T7 C6 ~& i3 w; N; q) B; ~( hon line 3
5 h5 f$ H9 E) G% b
: s1 i8 i4 I' Y6 W# l* |& m. z这样我们能防止许多系统文件被读,比如:/etc/passwd等。 ; H* F$ L# j; N+ u2 E+ [6 A
上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。
% c) X* H! @4 I5 R( j
/ |8 f+ @6 J& _5 @' N* b6 d
3 R( U; z# X/ ?5 d% G, Y% f" h6、mysql的启动权限设置 ' d1 x7 S1 U+ {
( X' X% F5 \, ^/ x, k( F
mysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等) O: v3 x& A$ Y- j: d  U6 B
系统启动脚本里加上一句: * o. @! q) V9 t
1 U  O4 E; B) Q- e4 _/ L
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start" . }& E; F* n" P. Q7 l9 Q
3 l, p0 Q6 n1 s$ f* Y* \
这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 ) w7 `8 |! K; y
0 i+ K1 d' @( W

0 H' P0 @0 r6 ]- t; ?7、日志文件及上传目录的审核及 2 u: j2 x8 t% s6 k8 v8 x! C: m
0 e7 r$ j6 ]% E' F+ b- ]' d& A" k
查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且
9 y" C; L0 z* c$ R( C/ w) O9 j也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非
% k$ x7 P: P/ A5 c: [法的文件,比如执行脚本等。
! V/ l' z) w; Q3 P5 c! L: V$ W6 y) i& ?% R, f# _' X

' Y0 S7 K, a: e9 z9 \8、操作系统自身的补丁
4 c: k' b2 p" m  j7 P( s- ^6 O% p7 a" ^9 `$ w: Y  @$ V4 l! o' o
一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。 2 F6 x. o( |- B: Y, L4 k

/ {& P) s6 y9 r2 T
+ z# J! x, V4 i  B经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,% a5 v. ^- ?) e
即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 2 u  p' x$ R1 K$ e; F  e
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;)
: x4 r3 j0 l& D4 U$ d: M, X
& [9 e6 }3 C. @5 z' t' b" u9 ~: l) m% I- Q8 A* x
参考资料:
; e5 E; z% p; p6 y$ O5 L( }PHP Manual
0 H+ @+ I5 e9 t$ P5 {5 ]  hhttp://www.zend.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 10:24 , Processed in 0.017701 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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