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

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

[复制链接]
发表于 2004-5-31 00:23:03 | 显示全部楼层 |阅读模式
发布日期:2001-11-27' W, d, e! n4 d7 q( ^
文章内容:
7 G! e2 ~0 \. h( j( ^8 G& ^! L( y--------------------------------------------------------------------------------2 Y$ k0 e/ I5 k/ l5 d9 k, z: U
( s  s% ~& M4 e+ p
作者:san(小许) san@nsfocus.com
/ w1 B2 `6 Y2 ^. c
0 C1 y/ ^% t0 u8 E: F. B/ M8 v--------------------------------------------------------------------------------
9 ~* Z) g, I7 `8 E( v+ K" k. N, T  A  u( `1 D# F) i0 c
前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以
) j6 E( N+ [! o及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配
: S. a& `4 x* ]. L4 h0 i置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的
  S5 a6 z0 P, ]" J+ w$ g2 S2 i8 n过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的
' D% L) ~+ @  Uphpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现
9 ]6 h& y4 X) a" W' i* c0 X在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题; T" A, T- s) C: D
了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。 ( \6 C/ J# Q% l+ i( x; @

& Q) m; F5 T; T( s# `
* M7 V; l1 K! O9 E. y1、编译的时候注意补上已知的漏洞 1 W  {. q! \- v! B( A
  n' I+ e1 x9 g/ }
从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突
& N2 S9 Z2 V! M破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源
9 }$ M' i- a" Z: K0 u; C& E% f码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件, E2 v- T. Y1 _+ O
的第152行,也就是下面这行:
1 ]' p, F7 ~6 L3 V: M& Y% L, G- }# p0 R! Q  W
if (extra_cmd != NULL) { & i5 F9 n9 _& ~, W; ~

; L  j( }4 x# _) g7 w" A, t后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php 8 {) \) v8 {# g. Y
那么我们就修补了这个漏洞。 % U: e& K/ o- j6 Z/ I
- X' Q( V: Z) q& D; g6 U) M! D

% y3 }7 g3 E6 {7 r8 j7 _, i" [2、修改php.ini配置文件
" w! a+ `, a) u# p! ?8 U5 L: a) x/ V# y2 ^! f
以php发行版的php.ini-dist为蓝本进行修改。
; Q8 f3 n4 |$ P. J/ T2 A4 }$ [
7 K6 S' M( u  K0 F1)Error handling and logging $ d1 I0 a: C9 L9 c0 q
在Error handling and logging部分可以做一些设定。先找到:
0 m9 E" t/ X% R4 |  D* _0 jdisplay_errors = On 6 w+ H  o. n" S7 e, N0 |5 Y, I$ A
0 w  z2 Z& |/ I3 l0 _- a
php缺省是打开错误信息显示的,我们把它改为:
: M5 \' @) h% w  \# A3 g
5 j5 O2 ]' h5 l0 j% bdisplay_errors = Off 9 Z  _9 ?, f. s
- F$ s0 n" d/ v1 B$ |3 W
关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻
; D, I5 z9 N0 g& A- p! N0 U击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造6 W; e8 c+ L' k
成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以
( ?0 _$ R9 D. r+ N* w下: 8 k) B. s& R) D& j  X+ C* L

7 z8 J2 i5 x3 z5 ]  l  J! alog_errors = Off . D4 f2 b4 l3 Y0 _& V5 e/ n- k- N
' w! l! Q, c) T4 V) M" X" H4 z
改为:
- F+ W( P0 v4 K- W" k7 w! ilog_errors = On
4 }/ o: ]  i7 c4 H/ R1 N( |7 Q+ \3 `) N& x' [3 ~$ H" K
以及指定文件,找到下面这行:
+ ^/ [+ `( r; k, N, f6 v/ ^+ K  g$ P3 a2 E' T- [+ n
;error_log = filename % w5 `9 |5 o" H5 s$ M
" O( F* F. ^' N2 t; f. e0 ^
去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log
8 t; a! h/ ~3 C; E
; G# r/ g4 n, ^' A- [6 d: Oerror_log = /usr/local/apache/logs/php_error.log
8 n* _5 w( q/ k+ ~- z) W+ d2 w" S. c, @
这样所有的错误都会写到php_error.log文件里。 $ k% _, s' L" C  _8 o

5 E3 {) b7 U' _! n' i5 [2)Safe Mode : R4 s2 @0 X8 D
& ?) b& e$ U2 y. ]' K, u
php的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在/ K5 I: b$ A+ j- `0 H
Safe Mode部分找到: & {  N6 [& s% _- I) b( R
( j) L# p5 w% T
safe_mode = Off
! g+ T3 r- {) c$ U% q) r7 U2 K7 j6 ~4 I9 s. r! I
改为: " ?2 s/ l0 A; ?0 c* K  i
! o* K9 q' e1 X3 N5 C" x; M! [2 K0 f
safe_mode = On 8 P5 U7 v5 ?5 a. |- x

' e" U( h, e7 S2 }7 K9 m1 ?这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它: p0 _, x9 Y  i7 m# B5 i
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行
& r* e9 {% m7 E  d, `7 ?safe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下:
$ m, Q! H" ^! ]
2 }  o; o2 p" Zsafe_mode_exec_dir =
/ X) `) o: B" v3 f1 u# G! E1 z* m% Y; \
指定要执行的程序的路径,如:
8 @8 F2 ~/ S) }/ W0 W( k
! Q9 _8 X8 M6 ]; {- p, \5 Esafe_mode_exec_dir = /usr/local/php/exec
7 b% S7 t: A! H' G* a; s* s1 @& S
然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行/ A1 R# l' J1 j$ w
该目录里的程序。 + y  o; q! r# v6 Z" ~

9 y9 E9 o0 t: }' {4 J/ R# e) e- w关于安全模式下受限函数的详细信息请查看php主站的说明: " @* f1 d( l6 m" V  C
http://www.php.net/manual/en/features.safe-mode.php
5 g. w$ ]" r( \! u- \
* W' v& S) S3 g1 T4 m% ?+ y3)disable_functions
  f- T! P# U1 s! N( ]2 e7 ^) t) {' F1 n8 O& F
如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这$ j( f& \) W$ Y& H) I# n) w' V
行: * }3 H' M0 ]& j" E

7 x+ o, L5 v7 N4 u5 v; X8 w9 edisable_functions =
6 `# Y9 b5 W5 V6 C) i4 U" q* R4 O: h/ A6 m, t" C
在”=“后面加上要禁止的函数,多个函数用”,“隔开。
! B0 }9 _3 S( p) Y$ }" @
5 o# S1 U9 ?! h) I8 I6 D" n- J$ Y  y+ f2 z
3、修改httpd.conf
' X$ z  |  e9 y/ [/ Z: q  u) {4 T# c% {7 W
如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作
  a4 i0 Q( S' V* {' |路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行: ; Q* R. i6 F- S" c, W/ \, b
" H  m) Z/ c( Z( c9 m2 u
<Directory /usr/local/apache/htdocs> 3 h. c. K/ c4 n
php_admin_value open_basedir /usr/local/apache/htdocs * O6 Y7 ~$ e4 M% [
</Directory>
1 z! l6 m4 Y$ H1 w2 j  A9 V$ |( x, s9 n4 C8 S
这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打
" r3 t5 k6 ?, |5 x: M: h开的话会提示这样的错误:
! F& z+ g2 s2 o8 u& s  J1 r5 R, b  p0 s+ @+ O9 y
Warning: open_basedir restriction in effect. File is in wrong directory in
8 u" |' r5 o3 L% J( p: ]# W, h# U/usr/local/apache/htdocs/open.php on line 4 4 I0 @# E3 |# Y; u" x  U7 ]' a9 i/ ^
+ E6 x; Z$ Y  u- p+ v, w8 D
等等。 , T/ d5 Y2 F* a1 ?% A
0 u4 E* D7 C, `( P5 i

. G! G" f, J+ S3 S6 m- s4、对php代码进行编译 & {, {3 y7 U2 w2 U: I2 S

6 n: h  x7 c% y9 {- Q; zZend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和! U% o! M9 O5 v! f8 `' z
ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就8 [! g# s' x! i
可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统
( S. V. ^! g1 c, ?! z
& ]7 F7 Q5 d6 g4 S5 @. P
; b- v) V" d- m9 }5 cZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz
/ j* v' h! ?2 B$ i! i& z, lZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
8 d; u6 k% @( J$ p; AZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz * X/ s' y$ \8 I* Q
ZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip 9 v# ^3 ^  A2 b# W: C1 A; D3 X
* a9 f; [# N% e) V0 y
优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里
) T. @3 c6 y' @8 n" h. Z- f1 r' K的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句5 [7 T$ F4 {9 w. b4 q5 X

! B( S3 a8 K6 U; Z( y, k; f: ?$ p! N! G3 Z& Z  I
zend_optimizer.optimization_level=15
, L9 ]( K7 c# M- S  K- T: |zend_extension="/usr/local/lib/ZendOptimizer.so"
* P6 l+ R6 B# ~& k) l$ _1 P: C1 }0 m! G1 L; ]; e
就可以了。用phpinfo()看到Zend图标左边有下面文字:
. G  H* h5 ^4 X$ E
0 h; U. b8 X% G. r( l' R# twith Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies
% d+ b0 u9 f0 ?/ D# |- l3 D6 K$ z& r( k& F
那么,优化器已经挂接成功了。
# m/ V8 u9 I! n. Z* K9 r* N. G. T% W4 N0 t7 E) D* l6 |
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设
' K  g& ]1 i6 T' W8 z( R, ?计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。
) W. z6 F* e+ M3 [2 R2 ^% f, _- y! s9 z6 v: U) D" R" L' ?1 E  r% G3 [
php脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进
0 O; X7 s/ h7 J& N一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如# ^* J( X( ?1 B9 H+ F! _# X; [
mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。
$ f9 A; M6 s- X# z8 @: u% a! \' Y: g, Z4 y
: @& I1 ?3 I1 C4 @, _
5、文件及目录的权限设置
' i/ q5 [* \2 Q- ^3 C' g
' b' Z, _* m- k! A4 N; t9 K, zweb目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,! P% n7 o) Y: b
攻击者可以修改主页文件,所以web目录的权限一定要设置好。 2 M1 n; s  h# c7 r( o

. U6 ]. ^& N3 {  F0 P" \还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属
' ~, l- v& M/ p$ q+ ?1 T. J主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的" X  w( m8 u8 C  f2 E- i
错误:
* g) Y# U: U& |! _
7 P; u' |5 U+ v& q3 C) R' y( b: BWarning: SAFE MODE Restriction in effect. The script whose uid is 500 is not
" X& h7 J- F* R2 u: t- }4 k; gallowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php
# g1 o0 U" h- e1 R% o8 ~5 qon line 3 4 }  `! e5 A$ X. ?0 l, s8 i) k

8 K8 M2 n  x" {; n2 Y1 Q这样我们能防止许多系统文件被读,比如:/etc/passwd等。 ! k# U8 ?/ Q( f* @& o/ H  P6 j
上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。 & V! K7 o0 b" p7 e, c- i% g) \& w# S

# H+ k& [$ S- c) e
  s4 ^& X- z4 y2 e. ?6、mysql的启动权限设置 5 i  w7 V. c& R% D3 X, n
' ]5 H. B& y0 t' e( ~
mysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等; j3 ]7 q+ Z, p. M+ U
系统启动脚本里加上一句: # |8 l7 ]8 K3 X4 K& N0 c
4 P2 s- r' b9 f  [$ l
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start" % [7 U( Q& I" R6 i3 t
' x! k8 o3 t' l0 t+ v+ ]4 U
这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 / G1 O7 D) W. p7 Z8 y7 y( ?

4 N8 X0 a" `& t* k9 e& z
' |- m, ?% ]- R7、日志文件及上传目录的审核及
; S! h3 U- G1 h+ J. d; I1 I$ Y% {
" s; ^1 }) _, K$ u5 U$ `查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且$ i7 D: o# P3 `* r& C
也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非
0 m9 V& d) S# _, H法的文件,比如执行脚本等。 - \# s, Y" D# c. \+ o. i
/ x' N/ R, B1 Q+ j/ v6 x

1 P( z5 R, y: Z$ P- p# a8、操作系统自身的补丁
4 S/ b) v  m1 ?1 [$ {8 R# {1 ^% _0 F& k, s2 W. a0 D' J3 T6 e& Y
一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。
9 k- D- Y& P) F% Q8 x+ H( P5 v
- {" o2 T0 M- U$ r" n5 B9 N; X
% p& }* Y  i, G" s" A经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,
/ l- k, o  l' M0 y) r即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。   d% ~8 W! E9 |. J$ f
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;) 7 o8 t" J( R6 h6 R- i' n

+ m& ~" w, K8 k; E7 Q) ]2 Z  X
1 h$ E, c- B8 t5 R参考资料:
" A& ]9 _7 ^- l6 JPHP Manual
9 o1 a4 m7 e' C. F6 mhttp://www.zend.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 10:18 , Processed in 0.020824 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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