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

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

[复制链接]
发表于 2004-5-31 00:23:03 | 显示全部楼层 |阅读模式
发布日期:2001-11-27( F" S# K- c: K$ j0 Y' Z
文章内容:) N+ F5 P  u5 A% ~: O  I
--------------------------------------------------------------------------------
! [. _! J$ R) h! y; Q- f4 V' y- u# o$ P, B
作者:san(小许) san@nsfocus.com
8 n% M' h& v) t; e# b/ I
+ ]% g: Y, b; n7 Z--------------------------------------------------------------------------------+ |* a$ F' w. V. W. ]( A
1 T8 ]; H; B8 h7 ^
前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以
) C% ~# z& D, S: B& M: K3 m6 j及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配- _) Q3 _' z* ]6 x5 C
置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的9 c5 _' {6 l$ R0 P  A" A
过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的
8 n/ L. f/ `, S" ]( o! \( [phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现
: d1 H  k* ]8 k4 v" p! \$ q! `在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题
( K7 c- Q0 I, ^' d8 V- V& X了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。 3 w- q$ Y1 V8 j: u

. C2 j: i" ]  i$ v* f6 ?' a6 t( ?; C6 p& c  u& q, m& X3 {
1、编译的时候注意补上已知的漏洞
# G7 y$ ]& l, w4 w5 d$ h+ y5 B6 V- T! o+ C/ k" z
从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突1 ^5 p( |1 R/ c. x
破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源
  a% v' E9 ?& s1 Y2 D码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件& l9 e( E+ z  }8 V9 ]! C$ X2 K( a
的第152行,也就是下面这行:
4 t/ q: A2 D) n/ p( _. h4 s3 x2 Y4 c( z8 E% [1 T
if (extra_cmd != NULL) { & x( {  H, q2 x& ]: q1 h

- E" P) \& V+ Q, F后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php
# Z6 _$ d0 w& L- ?6 N& X- Z那么我们就修补了这个漏洞。
; d; ~' c: p+ Y$ C, Q
# [1 G( Z' g, ~2 }8 h# K) M# [  E' i% r$ {- \
2、修改php.ini配置文件 + S+ i* R& `; j+ F) K: |+ e8 d* L

# l8 y$ z! d3 t以php发行版的php.ini-dist为蓝本进行修改。 . @3 K* O7 }- s/ Y1 N

  ^& o/ L9 j$ h. `' @: x8 K& E; M1)Error handling and logging 1 o  b0 H4 Y3 j! t2 C$ O
在Error handling and logging部分可以做一些设定。先找到:
" H4 f: d* m9 R# _. o+ Ydisplay_errors = On & B8 u0 A" K3 s
  c# G& z( k0 t7 D% {) S- V7 c1 A
php缺省是打开错误信息显示的,我们把它改为:
0 [# ]5 h9 y" m9 l$ K3 \- u' t
" a0 ?$ W# S& f2 f; t; g4 p9 p% o! _7 Tdisplay_errors = Off
! I8 {9 J* p: M
  J6 U6 o" d& ?9 R- b( Q关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻
; ~4 f' @' U1 @' I, k, ]击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造' {: a7 f/ E* [- L2 d
成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以% c- [% _$ C9 e( g4 m2 d
下: & g9 U2 o( t0 A: \
  o) ^0 Y3 `: H; @$ f
log_errors = Off ) k8 o+ n# |" [0 U* j6 Y4 q

& ]. O( y- h" j; O9 @: S0 D+ Q改为: * p0 y* C' ^( P7 H( J. e  [
log_errors = On 0 ~' o; z; G3 b- S
; g4 _5 B# c/ t5 I5 F; T$ e+ N" c
以及指定文件,找到下面这行:
, b" T2 H* k& H: y
" J( J; e+ _9 M! Z7 o;error_log = filename
) B% J7 U" X4 G8 ]* i( r$ U( F: f0 ?! ?; N! R
去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log % Y/ E) U$ {  H' h% A" @

5 }6 Z. B) c6 q- L, i0 G' lerror_log = /usr/local/apache/logs/php_error.log 5 B6 @8 V4 V- v+ P2 @1 I4 g' U9 }
# U2 {4 m- M) @' `/ o: T1 p& m* F
这样所有的错误都会写到php_error.log文件里。
* n8 P7 N8 N9 Q. i; h$ ?& ]2 ]: O" i% ^6 ?: Z' t, W# C# A
2)Safe Mode ! y! q' b+ M; e$ O% v; f) t6 x

/ o0 x) f, h9 p6 L- R  j; r& ^' ?php的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在
( U6 c6 S  A" d( i- C" _, W( w) B8 m. fSafe Mode部分找到: 6 {( n4 M; v: h2 D' w& v* {- M" C: Q
% R1 N8 F# b$ X
safe_mode = Off - O9 t0 ?: r. f' o2 h1 L! o) O

3 G+ e. S, y4 S% l; d$ I" H# K) g改为: 5 \6 [* S1 E2 Y! I/ V7 i

  r7 C4 W2 c* z1 R; x  {safe_mode = On
# |$ z9 O0 t5 `( l8 ?
8 j) L1 i6 Z% e5 `% d这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它3 ?7 `$ r& h1 u0 j2 q5 S) k" D
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行
& m# x/ X6 i4 K' csafe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下: " T6 d" `1 M5 p; V# ]" a

$ Y( x% I' ?& D* h" Ssafe_mode_exec_dir = * o6 |3 |( L/ m/ b- T6 r
8 C3 k( W& R3 k: Y
指定要执行的程序的路径,如: 2 n- }$ N" L/ _9 X" e
, `% U8 p4 h, k1 \* P  f
safe_mode_exec_dir = /usr/local/php/exec
9 s4 I. u. [, s1 H" {1 S0 B
  q9 n. G0 I2 y3 j; m, m然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行8 f; `7 n- y& N( |4 E, {) W8 ?
该目录里的程序。
2 Q! q3 G6 \  z* P
6 j/ V2 u3 I/ g0 ^8 ?关于安全模式下受限函数的详细信息请查看php主站的说明:
( s! G# o6 k* ]" O4 jhttp://www.php.net/manual/en/features.safe-mode.php + c: G4 Q) d' s

  x9 B5 n+ Y! ]4 I3)disable_functions , p3 T# D9 Y) M3 G
2 l1 s$ t$ H% z- s1 N3 s& z
如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这
+ h0 R* T3 p9 r  n3 G* z. K& O' D行:
: s- x  q- D( c2 A% O! Z+ n/ N* w/ U: Z) {; }  b  |
disable_functions = 7 S! C" a7 V' ^5 N% v8 }, u
+ ?# p0 m1 t5 ?! _5 r
在”=“后面加上要禁止的函数,多个函数用”,“隔开。
4 M, s; H6 q+ V- |: j0 w) B8 T# P% d* V- t9 Q) |9 c6 H+ E
' \% L- D) n" r) w& ?% Y
3、修改httpd.conf ; z& Z# J4 M& B
$ P6 z/ b) U+ J+ S
如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作
0 x2 _8 s% Q, P; f路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行:
5 I# W+ f( W: P9 T1 a. m
8 h* @- J0 B7 u4 `<Directory /usr/local/apache/htdocs> . G7 u5 G& Z' N% a) a
php_admin_value open_basedir /usr/local/apache/htdocs
* a, x" M& \9 J# N. L. d9 G7 h* W) Z</Directory> - K) [. S, O$ F

: @% S6 @! B. O7 E' _& _3 ~9 u0 Z这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打$ G7 d* f% o& v8 g4 P
开的话会提示这样的错误:
( A% o9 G4 U6 [# K1 d
5 z; E5 S( X9 M% w* c% tWarning: open_basedir restriction in effect. File is in wrong directory in
& J, H( ^. D7 R* w/usr/local/apache/htdocs/open.php on line 4
0 B8 d& w* R- z  q7 Z6 Y0 N. ]
3 ]# o7 e7 }. q0 ~7 z等等。
8 U) \- S/ j7 w) J$ K& n+ p
' ?" ]& U/ J3 N; W* i7 I
0 m% {( V, l' o4、对php代码进行编译
7 m4 ~) h8 R6 I5 b# N' H
6 o% i# ~! R5 V/ xZend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和7 W( T" {, t4 `$ f+ T% Z' N' c
ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就
% _6 h) T% c" {& d2 x可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统  ^* p7 \  q; h: {1 |

. j, E/ K- j4 e; _* ~
! Y4 u3 o0 N9 w  J* Q* YZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz
: s" m+ P( p3 f+ L0 j  U' ^# Y+ P1 YZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
1 F$ s8 x% B5 u/ r5 M8 i  R3 N* F2 gZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz
, m- C- A  d7 \ZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip 5 Y) N9 P0 x. f" \9 j+ E3 \4 o! A: N

# D2 x3 m5 ^9 e; _3 p优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里% X9 |$ i: y. x1 x* W9 X
的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句5 ~6 c7 e' c3 u: U

: k9 Y8 k; K- b. {/ K. @/ j
9 g" K( C( e% C* A2 }zend_optimizer.optimization_level=15 . Y  c" M* W' ^- o* P" U, M
zend_extension="/usr/local/lib/ZendOptimizer.so"
7 T9 o9 E5 o$ ?+ K. n6 F8 e$ z+ C/ d
就可以了。用phpinfo()看到Zend图标左边有下面文字:
. s5 P. ?% E) i  w% w7 A) K4 d/ e  P3 U7 S
with Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies 4 \  ]' x% w. |
2 v, H9 X/ g3 a2 f4 V+ E  g
那么,优化器已经挂接成功了。 ' ^! [( d6 z* ]* H
/ l3 L9 I! j8 {, m# W, Q( @, Q0 k, f
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设/ \4 j* x" d$ k# u
计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。 6 ]* M6 D8 u9 E' i
7 J+ v+ p$ y5 ~$ ]3 k# T. [
php脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进. N3 w: j( X7 w' K, M+ _. w
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如- x+ D! \* V5 F% B0 r
mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。 * P, s  j  j" G7 _
# X: Y& g- M" V% X! @' W
4 @: I. d2 S' E- |
5、文件及目录的权限设置
% k" r9 l  Q' J* {% q% k3 c9 D8 N! r+ S+ Y) ~
web目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
) N5 I6 ?/ `/ S) @" T攻击者可以修改主页文件,所以web目录的权限一定要设置好。
4 x0 @7 }2 u, d6 ]3 y* k- |" v3 [( e5 W8 C2 }, s
还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属
- |- `  ?0 s/ d5 ~3 h" B# N主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的
- ?+ B. {' K6 j: c4 `: W; G2 b9 K错误:
/ ?, D  y+ Z/ t/ X7 [
7 C3 M; n: I0 d: b  q6 {1 pWarning: SAFE MODE Restriction in effect. The script whose uid is 500 is not + L/ K3 T+ X, a& [2 o8 n- K
allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php ' T! s* ], ]: C: Y% `( Y- \% L, _
on line 3
2 h" `' C% @# t% f7 ~" S# U$ ?% r5 s9 r6 Y. V# Q
这样我们能防止许多系统文件被读,比如:/etc/passwd等。 ( N+ ]* ~/ U4 i4 _& c! R9 I& W
上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。
- h" `( D) i# P
, p  }3 \8 n+ {3 t+ u/ }, I, g) o% ~2 u* B
6、mysql的启动权限设置 * W  E- o6 m1 |! U" O1 K5 R
% Q7 S. z- N1 k! U; p# k
mysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等
4 U& k' [5 O3 u4 }6 t! B6 M- V系统启动脚本里加上一句: 5 }! x  v7 q7 e. R* z$ d

3 Q( N2 e4 B# n4 p5 @su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start"
( _# h, s- ]) S7 p# Q7 s" W7 f/ ~2 v* G( r$ }9 d' |6 O
这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 . ~) L) w! O" m- ?3 u9 D

0 W* w9 s7 p! _- H! s* T
9 h; |' p; M$ q7 T5 e+ N. I) n7、日志文件及上传目录的审核及
+ H7 [! X, b3 M& R
" z/ B; |) C9 t查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且# X1 d  {7 j8 B* e2 b  I
也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非+ l# L5 W8 j( v0 T( Q! F4 E
法的文件,比如执行脚本等。 ; l5 T+ K& Q0 i* _

# H6 _1 X6 X1 j/ ~! h' k' u# N; g2 \3 _7 w# P, S7 |, Y* V% T
8、操作系统自身的补丁 & z; s6 b$ w& {, N6 P; U6 o: R

6 g2 l# L% \# Y: x- H2 a一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。
6 Z8 |" \6 O; c2 ~- b7 ^3 j) w, _8 Q6 A5 k8 `* o$ s, M5 Y6 V
, n  ~  v  t" r0 ~4 j4 w; t) @
经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,
# u6 r7 L4 d8 k" z9 ]8 X& h0 [即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 0 E: ~* ?" y/ h. `, k* g7 u
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;) & ]8 z' b" q" f( g7 U6 ]: `+ }
* D' P8 E, R, \1 A) J0 L
; ~2 H% M! k0 q. h  I1 }
参考资料:
9 w, r7 H/ v: X3 L7 zPHP Manual % i4 h( H2 T$ u$ a
http://www.zend.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-15 06:26 , Processed in 0.017860 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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