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

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

[复制链接]
发表于 2004-5-31 00:23:03 | 显示全部楼层 |阅读模式
发布日期:2001-11-274 Q+ @; W& V5 R# |
文章内容:/ F6 ?/ A0 d: Z- H9 [% j
--------------------------------------------------------------------------------7 N7 J* r& c9 w1 Q: ~- V% {
9 ^9 \! b& X3 j4 e$ m
作者:san(小许) san@nsfocus.com ( l, g( K0 n1 N) v, H" F8 ]

/ e- e6 c8 H* R1 p. T( f: H/ c6 [6 H--------------------------------------------------------------------------------
1 f; ?" s) H5 \1 @4 q- e& ~1 f3 f: F: v, m% g! h& `; [- z+ U
前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以6 J6 L2 D. |% q5 p! R2 P
及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配8 g( L: z% R; S# C2 Z* M
置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的
( q4 R- f0 b& j( x) I$ r; A! R过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的+ c+ M3 h( i/ M; R( M' w
phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现
8 K' e2 b6 o7 `: s+ e4 Q在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题
# _. d# U9 I0 N" j* t! d; O了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。 + g! d8 K  F1 q/ b9 j
/ ?5 q( O! c: f* k# \4 |- O/ S4 t6 \
8 ^8 t8 q9 l: E. j: [1 R+ I
1、编译的时候注意补上已知的漏洞 1 h" v6 c7 f& o9 V: f& W) J! A- c0 ^

( D) Y3 ^: F/ D7 D) }" l. |从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突
, J6 ^0 X0 C/ v  U; p1 M破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源2 O( F2 f  ^$ d; E( R9 I
码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件9 k- v- W$ S! M) b4 q2 D3 z& u
的第152行,也就是下面这行: / I5 P& k6 V9 l# |

* ?. N6 c5 d) I. Nif (extra_cmd != NULL) {
; g9 B/ R9 A7 Z2 a- I3 Y
0 P: V5 }! v4 p后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php
& C4 X7 Y! ?7 H0 q/ J2 M那么我们就修补了这个漏洞。
' X" W% [" \( i4 n/ r9 m5 M* B4 h3 M! l2 ?$ V! \

2 z, Y+ a: c- m7 D; R, K2 S1 n' r9 _2、修改php.ini配置文件 4 s" u7 R- U+ U6 P" V

' |1 F7 c& [  f  D" p( Q以php发行版的php.ini-dist为蓝本进行修改。 ) R- s$ y+ N$ G/ ^7 Y4 W% }' b

+ B, T0 c( S! x' _0 T1)Error handling and logging ; @- M) i# J* C  Q4 H
在Error handling and logging部分可以做一些设定。先找到: & b7 O8 h, h- i' j
display_errors = On 5 U$ G4 v$ a+ g1 _0 m+ S
6 w: X! \6 k$ z- Q+ |9 B6 d
php缺省是打开错误信息显示的,我们把它改为:
- k# n/ o% i' Z6 Q4 N7 T7 [2 V/ a9 D- ^6 L' ?; {& H
display_errors = Off & h' Z9 |8 s: H9 g8 R* Y0 |1 O1 a
" S. l. N" E( Y
关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻
: W- F/ {: L% t& I; E击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造
  x6 h3 V, K2 h- d- M8 \7 A成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以
) l- {4 D( E% M  m& n4 K7 u, \  s下:
+ n9 m* @. l4 z6 a: C8 t$ V4 l1 j; A8 }3 A
log_errors = Off 3 T7 i4 b8 T6 E
8 J& P! A7 u2 T- V8 x( U9 A1 g
改为:
, ~. \+ h8 u% l. [6 Z( {4 O: clog_errors = On
$ J% [. N- s  Q$ u2 s. Q; p% r& d8 \6 g& ~
以及指定文件,找到下面这行: 8 K/ z4 g0 |! y5 `" k
1 @+ s8 L* l7 P  S% m
;error_log = filename
6 p) Q( s) z2 D& m( O5 r1 ?
8 R7 D( y& O9 t7 r' {3 h去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log
$ p# T/ J  g1 R  u) A/ h# c8 ?9 }7 p, _6 T4 _
error_log = /usr/local/apache/logs/php_error.log
* [6 H% C8 `( [% Q) Y6 U. z
# N, Q0 f7 M$ y4 K! F1 x这样所有的错误都会写到php_error.log文件里。 2 N9 h& }% ~7 I$ |" l

2 B9 x4 f  P' U; v) ^  c2)Safe Mode
, ]+ H' q6 n+ z  i4 ~  O! ]. E' S& P0 z- u9 v# }( W* U
php的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在
1 ^+ u' x6 S' m* k. i, xSafe Mode部分找到:
# o& l+ Y7 q* b: C
, p# h0 u4 h( g  Q7 u- Ysafe_mode = Off 5 ^# o# N% o  X
3 g' x% C+ Q* S8 K0 A9 {6 K8 U; e
改为:
( z+ N& ~6 g' C4 f! B0 t* y
- [! A  w; S4 k+ zsafe_mode = On
7 n6 o$ U- p9 |- j; g- W
% B8 }" f! \- I! Y- n( Q这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它$ d" U" Y4 l& m7 F) J% }
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行  k0 Z" w4 q8 R
safe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下: 0 Y6 v: @9 t6 j8 ~/ D
% q. D! s7 d& T! }: e# I5 x( d+ ^
safe_mode_exec_dir =
$ s0 Q. b) d* i7 |% T6 ^! F- @2 w3 s: B1 l0 C. H5 u& v; R1 y
指定要执行的程序的路径,如:
. A: \, q+ G% G4 ~! N1 b
$ s& J6 {/ r7 B# O5 Y9 ^  hsafe_mode_exec_dir = /usr/local/php/exec 9 h$ o  C0 V; l' r. }7 g  |) j, Z

+ Z7 p- M* C7 ^4 `% I9 G然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行
1 E$ ^+ Y5 S8 `; L5 O该目录里的程序。 : s* b& Y; s  [  i
" {; ^* K8 |' b- U9 T" P
关于安全模式下受限函数的详细信息请查看php主站的说明: 7 w8 H* C* F& j; a- R4 j' |0 [* Y
http://www.php.net/manual/en/features.safe-mode.php 1 j' {- w) a' p% ?
# @/ v5 V6 Z3 O
3)disable_functions 6 O8 W: J& G0 H4 X% _% ]& e

& ^8 }1 S) _- T( f  t& s# m如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这
) ]% S1 I# e9 V5 f" e; `' y行:
* ]  |$ e& C. o: L% }" S3 b* B
  O# l9 g( O  F% Q) xdisable_functions = - v" u8 a1 V4 G& e& b

1 ?8 Q) F9 X# _  X: ^在”=“后面加上要禁止的函数,多个函数用”,“隔开。 * L9 B, L6 R' |! I+ z& |8 O; |
4 D; j4 ]0 ~1 v9 g0 c
% |6 k* G% ?* L. v1 d
3、修改httpd.conf 7 E' j, ?( [, a7 Y

3 K- ^% w# d+ z3 Y4 r7 m6 H' q' n如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作$ d0 p- T  p4 C, o" @) A
路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行:
0 S0 @; b* p# u  ?% e- e! M
  R- \( S' V8 \<Directory /usr/local/apache/htdocs> ! f0 \6 A- {( e5 T" g/ n
php_admin_value open_basedir /usr/local/apache/htdocs 8 @% G& z- v- s8 Q  d1 }6 z/ v+ Q9 B
</Directory> 6 u; ^- J( V8 [, i3 V
9 Z' w# w$ }+ X' ^" S1 t
这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打
% q" G1 M/ ]! Z开的话会提示这样的错误: : i5 ^9 P7 ?! R, ]: M, b4 r
+ X+ _) r: O8 ~1 w8 B( o% S1 f
Warning: open_basedir restriction in effect. File is in wrong directory in " e5 d6 w4 N: c8 Q8 S' J) Z) f
/usr/local/apache/htdocs/open.php on line 4 $ R# d- F" O" N
* \' Y' H9 r9 q; _; ^
等等。
; c) v8 D4 s# S+ f9 X- u& S% ^1 H, Z' N# i$ R

6 j  C# _* ]: z6 u4、对php代码进行编译
  [6 P+ Y$ T5 t  a- {* b5 V0 i: x/ {1 X# l2 j* `6 V' d& T! w
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和
# [' s. H# d: s- J- ?ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就$ j( t' q+ U$ M  w% d* I3 E
可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统; e$ S. `% e, Q: C$ J% a

/ P# Z9 h1 e6 L: O; A9 e6 _, z" h  }" {3 Z2 ~$ b$ {) t5 C% c
ZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz
: @7 Q, t# ^# Y5 w) c7 kZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
4 _! R6 G; C( p6 ~" O8 mZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz
/ b- A9 o! V$ M5 ]$ l2 X9 v& mZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip & ^: m! [0 U: W# o) b: G. n7 t. r

2 V9 @# O$ j( t4 T! I) r: a0 R优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里6 R% t! l7 X) C( R7 x8 x- m
的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句
/ x- U5 h" |8 K+ F) C; h
+ z5 L, X& }- \1 ?+ v1 w8 T, ^# u1 @1 I+ ?4 n
zend_optimizer.optimization_level=15
" P1 i, t* \! j/ Bzend_extension="/usr/local/lib/ZendOptimizer.so" ; `# g) ~7 Q0 R6 J
/ |0 f% Y: s' Z. a" \# D, }
就可以了。用phpinfo()看到Zend图标左边有下面文字:
: C! A" G4 W( b, d. J% {- Z% q0 Y. G* f) n( i+ a/ ?
with Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies 1 i; s6 s& W3 m9 t, ^
& v2 w9 T5 U4 N  m$ C2 `
那么,优化器已经挂接成功了。
/ z6 H0 r7 M5 d( V0 Y0 K: g: M6 w7 ^
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设
' E, M2 A5 B2 q+ t! a2 W- g) _) F8 @) P计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。 ' Q  S6 b& n4 H) H  C
; W3 O9 Q% h! n! q( `1 u" V
php脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进
% Y: T( f& _* s% o+ K一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如
! n4 a8 v& m" n. q' t( |mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。
* {: J1 G' j) \8 f6 {* O8 w, P
1 R/ N" O$ {* T# P( `. z2 _
, n1 i2 N& N. j! v5、文件及目录的权限设置
6 r8 d* _# e7 c4 @. j# O& X
$ f# k& p- N7 ^% s' mweb目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
% Y. w# z* E. l( S攻击者可以修改主页文件,所以web目录的权限一定要设置好。 ( @- Y5 U: Z; x" t; \+ I) L
7 W" C! {: l+ [! E
还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属3 h, t3 V4 G) I% k
主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的
$ f$ \, F9 x* U* p( \! f错误:
" C3 K) \$ f, }
& D; V  }& y+ m  f$ U2 PWarning: SAFE MODE Restriction in effect. The script whose uid is 500 is not
3 d! i$ t* z, n5 C, W5 }( |$ _allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php
. |6 y; `  S+ x( _on line 3
! h* T% M& }3 |, g
. Q: O8 c- s1 Z6 l这样我们能防止许多系统文件被读,比如:/etc/passwd等。
# h: g6 U4 U( e, A上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。 $ b: _$ l& h2 m+ E! D* N7 Y$ w

3 i* M8 Q8 R0 l) l+ k. l/ W5 G6 x/ j
6、mysql的启动权限设置 $ B/ Y3 y/ a2 m6 ~9 c/ L7 ]+ D
; S& L8 w1 J- @6 j$ W
mysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等; J- m0 `7 `9 _* z) D- M
系统启动脚本里加上一句:
2 Q/ |& j" U1 [" o* @3 w, V% i9 m! `2 e+ l
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start" + g2 W* `; D0 _" {3 {

2 [2 v! M% G7 Q6 V* _5 {1 R! \这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 1 D$ c$ t' R4 E

8 ]+ |, }0 b- s5 m( ?8 Q
1 u  X& V! [5 P3 g6 Z: }7、日志文件及上传目录的审核及 8 H& L: A( U/ t

2 o( l* c3 q5 N& h' N5 ~" Y' J查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且4 |9 ?  v5 n5 |2 ~$ I. I. e
也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非
: X! f  D# K. u法的文件,比如执行脚本等。
9 o4 U# k# N* @: W+ K! F+ ~1 u
0 L" j: ]0 z: p. e( N
+ k- ^1 }& Z2 U8、操作系统自身的补丁 & I' @% w9 R$ l' A: M7 p2 d

( x6 x2 @( q3 h# a+ M; C一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。
5 f9 y, D5 r# T; ]: u3 G
9 N; I. I4 Q% k" A% ~; l& x9 ~
% Y& y5 F/ G; o4 Q0 D4 M! t经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,
6 ]; ~8 E( O: F% W6 D' y! [即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。   x1 s. Y3 h$ k" I; N
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;)
9 ]3 [4 `; S% E6 j8 Q9 ]- v$ u) z  f$ n9 P

/ a" {/ n' j3 O5 V. [' }7 c: a# }; b4 D参考资料: # R0 \+ _# P$ L
PHP Manual ! k' Q$ T; S6 r
http://www.zend.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-8 23:30 , Processed in 0.035787 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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