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

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

[复制链接]
发表于 2004-5-31 00:23:03 | 显示全部楼层 |阅读模式
发布日期:2001-11-27; I# M6 a! ?8 i9 N+ |2 c
文章内容:, f1 U- l* u! F" ~* q6 u
--------------------------------------------------------------------------------
( q2 K1 P* W8 r+ a/ `5 [0 P1 e& p- H" C( E- Q
作者:san(小许) san@nsfocus.com
& T$ o$ e* T" w: n, x
0 i: r$ {4 a1 o% i- m7 N--------------------------------------------------------------------------------* @/ r( y4 F+ |) M+ z, f

1 z0 W3 R; y. v, x前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以
% \6 a; z! {# }1 z* x" ]4 Z- ?及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配
+ l; l" Y8 U- r3 {置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的
/ [- p, G2 G5 V; ^+ ~5 m过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的' W- X* @8 ~8 `0 f& T8 w  X) `
phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现5 R" m' H8 f3 O) C% s
在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题
8 [8 j# ~% J! q+ j了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。 # b! ^% y" k# G' I

: k0 O  R8 y$ v* [: t8 Q! a! B2 p" b. I
1、编译的时候注意补上已知的漏洞 / i& y, h4 W1 s
/ Q+ Y$ f: }6 }1 |7 G- t. L; r
从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突5 }/ k5 a6 b$ X4 A$ ?- E
破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源) a, b7 H3 y4 m. n; x
码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件
! H! H2 ^! l* B$ z6 j9 Y的第152行,也就是下面这行:
: k9 f( R0 M0 \+ c5 V6 o0 U, @) L' U
if (extra_cmd != NULL) { 6 W% y; M, j5 ^8 ^" ]
6 l! X  ^  K: Y9 |. X" r
后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php ; g( A' P5 A: U8 z2 G6 ^, a( ~
那么我们就修补了这个漏洞。 / {% h; G3 V6 E3 A# b5 Z
  s* c. c! a6 }  ~7 _
8 m! q+ H, G  N3 x# c8 U
2、修改php.ini配置文件 % X" ~  l* x* g" x

' ~) m" |# s. T! g, J以php发行版的php.ini-dist为蓝本进行修改。
/ H) Q( N# y0 P+ P; [
8 J9 c$ x: D. t# k7 n1 }, ~1)Error handling and logging
) j- e) ?( b; H+ L9 q! ^在Error handling and logging部分可以做一些设定。先找到: ) f* h# B. @! M, U
display_errors = On
8 j! t6 p  a3 M$ N# {1 p+ w8 c+ E- c7 @; D) s0 S
php缺省是打开错误信息显示的,我们把它改为:
) z- J& C3 g! j" c% X$ A; c$ i
display_errors = Off ! [" R% _/ ]' @
* e  D$ V) O; N9 z0 {. o0 A3 ^
关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻/ q. J" p8 Q; O) I. w! S2 L
击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造
: P( N7 [/ @) R' i1 J( O& {成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以
6 V9 y, q6 |) _& U下: 7 d) D' K6 J' Y* v; E

2 f/ U* Y; x* q0 _4 }0 R: j" m4 Ulog_errors = Off 2 m& \* e0 ]; ]: d! v- C5 D6 e
  w/ m4 `; h3 X3 I/ z
改为:
3 V; S6 y% M: R0 Q7 Vlog_errors = On
8 C4 Z6 l% @* m( y/ J8 W) ^. H: q0 I6 @
以及指定文件,找到下面这行: 8 K+ M4 Z  |9 s# \7 ^6 S
" ?# C4 J9 M! a" B) R" ^
;error_log = filename
/ f  Y1 d( X" d/ K- j4 M1 m) b2 Q0 Y5 d: x6 ~
去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log
) h! B) Z9 a" I4 t' U7 G, }" i4 G/ w8 t& Q
error_log = /usr/local/apache/logs/php_error.log " B- b7 {. K0 Y$ T- C' M

4 ?# g  y1 Q; z) j这样所有的错误都会写到php_error.log文件里。
& H' s9 H9 l" I  Q3 O- W2 C% j; F9 f- r# C1 I, a' |
2)Safe Mode
" J( D3 W9 K& T8 k
1 ], ]( [. ?% I4 Ephp的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在
" L+ O" S3 U# z* x) J7 c) B2 zSafe Mode部分找到: " K2 p! k  O5 J) S/ j

' l: }7 [, f( G3 X8 q- h# Gsafe_mode = Off $ d3 U8 o- r" G, P. U. t

8 g) C* `; j/ G; t! u改为: 6 N! g; h' A! g' U  A+ m

& j2 u1 ^/ j, _, I5 O, @1 q% psafe_mode = On : g2 I5 u, x7 Z' I# L1 z

+ N1 O0 P8 b8 h/ O; W; w( d& e' D, Z这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它1 m7 N# K2 O8 u# w" i3 ?
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行6 j" r+ [) S( a+ @8 d
safe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下: ) `  Y( x, H- o9 |6 n% k0 F

! ~6 z' U& ?! r5 K5 Msafe_mode_exec_dir = , d" J7 F% b" C4 X; ]& p1 b8 X

( m2 L1 \, R- T指定要执行的程序的路径,如:
' e5 S& h& }! ^7 h& q
. f" X3 k2 |1 G- Xsafe_mode_exec_dir = /usr/local/php/exec - [4 q; l0 s- P# @7 Q! T$ }

. H4 c$ ]# C% n- p* m然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行& ?  w( {0 u# ]0 y" _1 h$ E- C& D: H
该目录里的程序。
1 T" k6 J- f, k1 U/ h9 j& b2 Q1 T7 {/ R
关于安全模式下受限函数的详细信息请查看php主站的说明: 3 z" z. y( M' W& g1 {
http://www.php.net/manual/en/features.safe-mode.php
- s: ]) D1 o, o" `9 G' D: ]; z; }' b6 `9 M6 D  o
3)disable_functions
7 b- u, e) _- m8 x* h+ H- e# j8 K/ _; r* m1 @& }2 a6 I) J
如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这
) i* Y; S3 i1 R行:
, w8 C8 W# y2 f1 ?! X' c, ?7 z+ B8 s6 G
disable_functions =
. _) o9 f" @: g1 ~
; f" u5 q- ^, i0 _) i在”=“后面加上要禁止的函数,多个函数用”,“隔开。
4 _4 w3 H' F7 u
) T  w3 v5 E- S( `2 ^2 \& l9 u  K& q2 Y
3、修改httpd.conf - z: h8 T5 y' d" z/ v
& X8 p, r" i6 Q
如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作
4 m8 T6 @( v) Y; R- c- ~1 w* p路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行:
  \/ c9 h& j7 I' W5 `0 b. K
+ {" U% B+ V6 a- O) Y# L) }<Directory /usr/local/apache/htdocs>
2 q; }* u2 i2 V1 L% ^+ g5 f, J. Qphp_admin_value open_basedir /usr/local/apache/htdocs . x( e, S1 @7 Y3 |
</Directory>
% m0 J* f$ B; @3 W# x
/ L3 z1 P: j: M这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打6 G( E" E! o, w  S3 X* e3 {
开的话会提示这样的错误: 2 d* e7 H, n3 d( z

  Y5 f; r4 j1 q% D: g/ |Warning: open_basedir restriction in effect. File is in wrong directory in
* {% R; ]3 v; ?2 A- e3 k7 k0 R/usr/local/apache/htdocs/open.php on line 4
  e1 u& |1 r) V; x3 ^2 v% f4 w6 h& S; g8 Q! b" u7 C$ Y8 `
等等。 . b4 ~6 `, y  R
3 v" W* ^) p. B& m: x% L% ]

3 n7 l* S6 s" J5 T/ ~4、对php代码进行编译
! R' M6 C. R, q  z! n& T/ g2 ?1 i) H
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和
" x( v) F* Y2 H. A) FZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就
$ _& w1 O, |. G: m可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统2 |& k, ^! r' }2 L# e! _

8 Z, @6 Z" ]7 u
- P* }2 K: T) ?ZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz
& {/ y  g! Z. w6 @8 BZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz 2 s/ d& I* P) c
ZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz 1 N( A+ a8 X0 o5 k, H4 i
ZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip
+ l+ H! ]$ N& d# m9 K1 W& z
9 i, B4 ?/ v1 `9 w5 O  s优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里
! u# ~5 p+ {+ r& S的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句) l. s! f  R! a
$ l3 F: P/ X/ \5 f* h+ [) t% w, i# \
. k5 D9 l- O) y& I7 z# ?5 I9 _
zend_optimizer.optimization_level=15
8 R$ _8 I9 t/ f9 |zend_extension="/usr/local/lib/ZendOptimizer.so" & C/ d8 }1 C" `6 y+ h
. k- E( |2 A# B
就可以了。用phpinfo()看到Zend图标左边有下面文字: ( Y: y9 p4 j0 `( A% X- }

+ }. y0 j) X8 v5 R* h. X8 Hwith Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies
) ?* r. l7 N5 g; i3 _. R' y% s9 y9 V- g6 n5 ~. b
那么,优化器已经挂接成功了。
3 @7 C3 ?0 \7 Q$ ^8 ?, H3 K" l  O7 y) h  k" e' X
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设4 Q# J. ^+ Y' ^1 ?
计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。
, Y" Y, L5 |2 ~" L' w* J6 |" E8 Z3 W; p8 @: x
php脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进
2 `9 d5 ]" L( o0 W7 ?5 D. c; w一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如
$ ]2 q" p4 c1 q0 }( |* e. cmysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。 5 y* ?; N8 U( ?0 }
5 C" y: N0 h0 ^7 B0 V  W: r
; ?9 m7 n/ p# O7 @$ o
5、文件及目录的权限设置
' K0 K0 A, a- r5 S6 w  I& W3 J) _# s: M8 F+ P
web目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
; p5 ]$ X1 a2 g" R& }6 ^4 Z* U攻击者可以修改主页文件,所以web目录的权限一定要设置好。
1 U  S; k3 U/ ]  D5 V# m% h  o' q- r0 G. \+ w4 m; p  }) {
还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属1 V+ c9 w& s/ F: g3 q4 M: v! j' w1 Y$ k
主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的
  a( B/ ~5 @/ R+ z1 A; e0 }! D9 ?) V* _错误: & o9 \; z: b7 j& f
9 r0 u# f6 B& r# V! a8 i& q2 c
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not - v  ~5 B2 U  e/ [
allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php " O8 A5 X+ M( V4 b6 b' T
on line 3
' S/ Y9 M. J$ e  o
# f' a! j& D; ~( n这样我们能防止许多系统文件被读,比如:/etc/passwd等。
9 \0 s1 a) @$ X上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。
1 p0 O, O' A2 I. A* T
- M8 T4 }: l: g6 f: {8 C, {  ?+ |! D) Z
6、mysql的启动权限设置 # n8 M8 B% Y+ ]

/ i* P7 t! b8 L) y0 Zmysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等6 _) m: T3 }* {1 X
系统启动脚本里加上一句: * `' F0 B# s6 s; t; H- M7 W
$ s! P9 ?  g% l
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start"
9 h% r2 R' m+ f: C* S
8 \9 d" d4 [0 ~5 ]这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 7 {5 z3 {: H' b* O/ x
1 c$ H( \$ ~2 X3 i
- |4 j- ~1 r6 j" ~
7、日志文件及上传目录的审核及
; Y% n7 f  j  O/ s( k$ W
7 s/ B% h8 v& d% s1 A6 _3 c查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且6 {- P' `( \8 e  r( V" e* H
也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非
, m9 m( p- }2 ^! [8 c& b- }法的文件,比如执行脚本等。
2 [" M$ x5 L* Q' U8 {% C7 h' U" {4 h+ }

6 P0 W8 }$ X% O; ]" J2 S. ?8、操作系统自身的补丁   Z  X0 x4 t7 n% _) J
* R( c! y- J. Z; P3 g. y
一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。
; G, P: f2 h$ g$ }" ?( J
% m4 H% V  `! o6 g0 E) i0 N$ Z- }
7 S; u) V* @- x7 v! h( c) f) [( K经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,
* x# {" O( z1 R3 y即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 ; ]# `2 F/ C" y/ A+ E% _1 [8 g" K
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;) + f- B/ N1 _5 z4 Y9 w4 Z# W6 V  B

9 C* @9 b5 i, A2 x( s( w8 E6 `2 w9 g- s6 H5 l3 f8 Y
参考资料: : @0 q$ [9 d. U. G" g
PHP Manual ) T$ i& ]" _8 ^
http://www.zend.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-30 00:36 , Processed in 0.020436 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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