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

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

[复制链接]
发表于 2004-5-31 00:23:03 | 显示全部楼层 |阅读模式
发布日期:2001-11-27& @+ F  r  v+ e8 m0 C  F
文章内容:
. O; m6 j8 r8 M. r7 _9 u--------------------------------------------------------------------------------
) E, @0 A6 Z0 x- X/ M% N# x
4 l1 r- }# T! z' v7 d$ [作者:san(小许) san@nsfocus.com
9 F1 E8 X- g" U' l4 N
+ M/ s6 V4 P/ X/ t: r) d--------------------------------------------------------------------------------
* P* `7 A+ u" [' H; v- U& @( {0 z$ J4 `3 r' j; v. E4 g: N( [
前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以
8 L$ x7 R* X6 v8 i+ S( R* A及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配
6 F, a8 y) b1 ~) c1 j5 U置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的9 r; F2 C- K- _3 N
过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的
  R4 e5 a. [+ f( h7 d7 _2 \: yphpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现% j! {/ p3 N" I
在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题, b6 w) t+ W  Q; h5 Y5 d- r& u
了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。
! D  g8 ^1 A" j. Q$ i
, \: M+ c* R% T3 m# v  L% j; A  o0 c3 j, t* J
1、编译的时候注意补上已知的漏洞
5 R6 f* ?- o: M% r+ d3 o! W
; ?. F) ?7 e, O0 m从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突0 i/ y/ s/ ]. L" K2 k) y7 M
破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源
2 u: b3 b- W! t( R码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件1 ^. o; {1 w$ {+ Y6 w4 E0 U
的第152行,也就是下面这行:
7 ]$ P# d; D' u' s0 K; R9 f0 q; z7 E: n3 D
if (extra_cmd != NULL) {
- a) Q) \' ^! l, _2 N6 P4 h
( ?+ a6 L6 d% Z5 }4 q$ p' k( z4 \后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php 6 L$ `+ Y( H! F* F8 s
那么我们就修补了这个漏洞。
& k4 T& j; ~9 a1 L) X' y. O5 k- S  N* T
/ @4 O# e0 i/ @' ?% X# q8 M4 B
2、修改php.ini配置文件 ) }$ S3 i2 @5 {& e/ ]
2 A1 F( N0 i% x0 f5 I% ]2 ]6 [
以php发行版的php.ini-dist为蓝本进行修改。 5 w) e6 T* W7 ^& C! Z: K$ o2 l
2 a. x% F7 t- b& V* a
1)Error handling and logging . e0 M+ p3 ~" _, _  \/ x% R
在Error handling and logging部分可以做一些设定。先找到:
' h0 Q" ~4 M' A/ ]  n. Rdisplay_errors = On 2 G8 y; |8 G  e- m$ Z. u
7 D$ ]+ G2 `0 Z% P
php缺省是打开错误信息显示的,我们把它改为:
5 M9 c1 _. A. ]1 O' k. I/ y5 d
; T4 O# ]9 s$ |$ c/ }1 y; A2 fdisplay_errors = Off % ]- d! {/ b% @: x

3 m& S/ j) n) x4 X% r5 j关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻+ n8 O4 H: W$ p
击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造
2 h/ ]  R: L& o: e% y+ e成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以
- C6 k* [2 }3 f4 k% U0 V下:
) `1 n7 R- u$ E' [6 W" E, a; K, Q$ o* C- r! k7 ?
log_errors = Off 8 Y1 w! N3 T/ }* i& @3 e

1 s3 t6 E9 `; ^; o$ [: H- [改为:
' O4 m" W3 S4 m  H4 u4 }log_errors = On   o! R3 Q/ b8 t; L/ j

# F" n" E. ]! G) U以及指定文件,找到下面这行: ; j. g- U$ s  ]/ K

4 M/ [" z9 L5 C* x9 F;error_log = filename % e; J7 a5 @1 Q7 F1 b) r1 N
! d. i$ ~* G+ Q% R0 O  H4 P3 @
去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log
2 u* h0 G3 o' L, F8 K$ \" {' ?- c2 f
  {8 N; m( b% c# _  \( merror_log = /usr/local/apache/logs/php_error.log
' d4 m1 W0 }! F- H  ~* ?
5 e# F/ I, c- }  R) D这样所有的错误都会写到php_error.log文件里。 2 ~$ x) r- x; I, H' w5 P
; E( {: h# c; d* h$ A" O$ o$ U
2)Safe Mode 7 y+ K. _$ J1 l7 K* Y, O8 \  }, a

' N# ~% j3 [/ D/ M, D+ Pphp的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在
  ?# \' h- t+ n2 ]( h, x- ~* f3 I% BSafe Mode部分找到:
7 H0 D  I* Z. y% b8 t- g) V0 z8 Q5 _: J- A2 z3 @8 V% d- r) [
safe_mode = Off
* Y' d  U) l( e3 x* m- n4 [+ y  i9 C3 z2 Q. W# w% e* j1 ^
改为: 5 ^. E) \( L% Y/ }. g& f2 Q# M6 m
+ e) ^" H* n. B/ d
safe_mode = On
- }6 e# i* g, ?9 T: a1 B8 ]$ C- G5 S4 U  J2 p
这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它4 P! p* e, p, H6 v; w& k: M3 D' r
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行4 u0 @* {5 o5 P) a+ N  ]
safe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下: & t. e+ L/ t2 l$ }+ J5 s
& Y. d9 `- i. v2 \3 r. |3 d( K
safe_mode_exec_dir =
" N+ e! e- H) Y5 b6 l) r( W# O
5 G, G+ c, ^! Q/ f指定要执行的程序的路径,如: 5 W2 S& `; M% l/ h

; r8 o9 J: f* e  Y- J; z/ R- z  W$ Qsafe_mode_exec_dir = /usr/local/php/exec 5 o% e1 \* S! }4 `0 Q
" q: o& ?3 N. a+ v# l! _1 \
然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行  U  S: v' o2 ]7 U, i% }
该目录里的程序。 5 X! L% }2 c0 I+ a/ g1 i! w
. l$ R6 ^' @) m: ?& Q- d
关于安全模式下受限函数的详细信息请查看php主站的说明:
* a8 A  x% E* z9 Y$ m0 K/ n% Z% e/ N" I3 w. ihttp://www.php.net/manual/en/features.safe-mode.php
  \' D2 W2 y7 f/ j8 M  }9 Q2 D& E2 @% J6 t. K- c8 M' ^
3)disable_functions , k# ~- O; C5 }* Y/ q* ^; e" x

3 w1 x+ S0 k$ ?/ u如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这/ h5 g0 d* [! O* d6 s
行:
% a# z4 j& B5 {& ^( V5 W
; n( u+ Z8 T8 t' v1 Cdisable_functions = ( s% G. O+ w. [& C9 p, h- k
( t. o# e5 ^) }6 D# e' y! t
在”=“后面加上要禁止的函数,多个函数用”,“隔开。 8 R3 o7 K8 a2 c9 d1 Y# z

; t  T0 F0 ]6 W3 X* x
9 R2 i7 o7 @+ O  K$ `2 W: l" K% b1 P3、修改httpd.conf % j! F  }- j+ U/ o! A

' d! s) N/ f5 @& c. @- t* v; V如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作
- ~- M1 t7 a: M$ r! U- u) S路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行: # g; i* \) x4 X! h

4 s  I* W) r0 E. B<Directory /usr/local/apache/htdocs>
* P3 T3 Z: s1 e2 D5 z6 Q# d* I( [, Fphp_admin_value open_basedir /usr/local/apache/htdocs
4 T! N( }" V) V, g* I</Directory> / d0 V# }& h3 ]3 e4 s
$ F3 I% S5 V4 Y; i  g# w9 u
这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打
( \$ R# k4 {+ J! I开的话会提示这样的错误: & F$ |: L% I; p3 L1 S" h

% |5 D$ N4 j+ n* I: _2 q. S1 AWarning: open_basedir restriction in effect. File is in wrong directory in - B' n4 x: ?4 `* x
/usr/local/apache/htdocs/open.php on line 4
6 s4 h: k# ?1 J1 p1 x0 Q$ z7 _) E* ]* S0 M
等等。 ! n7 b8 {$ r$ @% U9 D+ L' ]: R- b4 }
9 {& }" z5 o& U& a

: I4 {$ g! ]; B& j; F9 ?* b4、对php代码进行编译 ; Z& W1 c+ t* G+ n2 w
' M( I$ @" U6 f" \
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和. ?, |5 o/ W, i  i9 ^# w
ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就
& y7 V. {  i9 i5 k" L, I可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统
: @8 [; ^; _* U6 O1 ?3 O" ?
7 h" n- H( \$ T+ [! A& g
4 w- }* o8 s0 T7 {4 }: P7 DZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz * J1 J; C' `- V$ @
ZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz / d: [1 e, X5 Q/ s2 Y: e
ZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz 3 W2 m6 B0 w) r0 m, u
ZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip 1 W: g: C4 c. i5 ?: P- ?& ~* b8 i

6 f4 P" f* h3 b. \  N优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里8 k  {  O+ V. @; x: {4 W
的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句) {5 }) w, E5 B$ t9 v7 N* n( v+ T. S7 d

5 D; t! O" F  E2 Q6 G) A3 W  J/ k1 z* n. o
zend_optimizer.optimization_level=15 8 X3 S0 q% @/ s: t  f( w
zend_extension="/usr/local/lib/ZendOptimizer.so" 3 u/ Q; @; d+ a- Q! X% L3 d8 ~
* Z  [) y, Y& ]' W0 `# C2 s
就可以了。用phpinfo()看到Zend图标左边有下面文字:
& b: |: Y8 x$ \4 T# o1 }
9 x+ s2 z$ r8 A: X! h8 i1 Pwith Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies , K$ Y$ V0 U, `) Z+ _% h

0 |. a; E5 Q; d3 f% n3 l5 ~" g4 H那么,优化器已经挂接成功了。
7 ?$ H8 _+ ~9 k7 H, C% O
3 C% `4 U  U9 m# _% H! T( e! M但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设
3 c0 Z' y0 M$ q0 r" v# {! L计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。
! E& P% S& t9 v
4 _$ S% L* r% a1 Pphp脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进2 N2 v6 h' z! S; V! t  p
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如+ L( \! V& w* E4 R) x6 E  y9 T
mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。
3 x( V: R5 j6 _' E6 T! V/ j9 Z; t" ?: T+ z) [% I5 O
% N3 j, x9 k, {, y1 _5 l8 u: _3 C
5、文件及目录的权限设置 6 w" N0 `+ s; p* c

  J& s! q8 u2 Cweb目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
) ]7 z# ^, F. z6 |' h. w攻击者可以修改主页文件,所以web目录的权限一定要设置好。
9 u2 G) X/ Q3 _# ~/ K
* H6 c! ?5 d8 Y! |: z- q还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属
3 ?% t0 c! d: ~/ y6 @主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的
) i) S) g5 b* H' [7 S错误: # v' ^; l6 e( B$ {( O* I/ A
8 [6 X8 K  K* T9 B+ H" \
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not ) F! V7 ~: r1 ]; M' Q3 V
allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php * N0 x& t5 ~/ W9 Q" P4 [5 s
on line 3
2 v0 g8 l/ I0 T% c$ J" M& U# a& H5 G" `( b
这样我们能防止许多系统文件被读,比如:/etc/passwd等。 * M, M! q5 `7 h/ f
上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。 " m2 f2 ?' m. E2 g+ u, N$ s+ y

8 Q3 U! u/ I7 ]3 X$ a# C
2 N# q4 S5 z0 r2 |* l6、mysql的启动权限设置
0 n0 y* R: K7 c3 u6 z! J3 i; h$ Q
mysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等
5 N  p$ e5 ^* ]$ ], Y系统启动脚本里加上一句: * o0 }1 G5 i* V2 M2 I- W' T
" V9 u( x  o! r  }9 }) R3 f) e4 _
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start"
7 C. s/ T+ @+ Z  W! I% x5 h% E! e" `% W% h2 N
这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 ! Y) G7 O4 D2 r6 v
6 S  {/ R! l4 I# j1 Q
. R/ K( [! r9 w) l1 t* ~
7、日志文件及上传目录的审核及
3 ]6 \/ i! U1 u" [( b* A% l3 c5 v( d; M6 e( R1 D/ ]+ z1 d
查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且
- S2 Y7 g: [8 p6 z) Q* `5 J2 q也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非5 ]+ {  ?. \0 S! p6 C
法的文件,比如执行脚本等。 $ O1 g( w% |0 l% a2 q
& t5 k, _- d$ K

) u8 R: m% O1 x" x4 g8、操作系统自身的补丁 4 E* E9 X3 F& ]& W9 r- V" ~

  r# F1 G- v( v2 g2 _一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。 2 u7 E/ U& i5 F& c: T5 D

1 H6 w7 g& D: I$ V0 s
+ p. h' x, [5 q$ @! x经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,6 u1 j0 ^0 a: [
即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。
7 W) r$ o0 A# j  }# b4 x7 U如果您还有更古怪,更变态的配置方法,希望能一起分享分享;)
% W) \8 j& t9 L2 T0 b2 Z# }5 }2 z) [
) f* P9 c3 V2 r( L
参考资料: + T! X3 T+ q9 H! P
PHP Manual
' {, p8 H# H( ^8 S8 q! bhttp://www.zend.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-20 03:21 , Processed in 0.036545 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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