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

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

[复制链接]
发表于 2004-5-31 00:23:03 | 显示全部楼层 |阅读模式
发布日期:2001-11-271 G$ V7 r& i) D! J$ d
文章内容:2 [) d6 c8 q& d2 O# h
--------------------------------------------------------------------------------
" y8 ?! o- M7 B3 D5 `' m+ H5 K4 V( }" g& L* p
作者:san(小许) san@nsfocus.com
' h6 d4 B- D3 G8 n( ?& P, ]; S3 S( z% n2 o3 ^) _2 Z0 s
--------------------------------------------------------------------------------! Q% U- w3 D( j
. @6 h: c+ E& ^& e( k5 c
前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以$ _! X6 \+ D' D; v3 s7 K
及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配
' p' r: r6 ?: O: _0 v置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的( L6 ^! p& v8 P& B6 Y
过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的
! b; J- l  R2 R/ E7 C! o1 Yphpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现7 z( x5 z& X1 I8 x' m
在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题$ z! v* B9 y4 L, w5 L( f+ Y
了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。
9 v1 U7 ]: R2 _. V/ }( i+ H! l4 s" n# x) o. {+ M! Q

6 q& |9 }- F# n+ K: Z$ l6 B1、编译的时候注意补上已知的漏洞
0 M& u, H8 W$ Q1 {; j; G4 @* B, n3 E  e
从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突
/ H/ N* d# |5 i2 w3 j破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源
' e2 ^9 |) S* W1 [; l码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件5 v0 p) I9 a/ y9 Q9 A
的第152行,也就是下面这行:
" S5 |, y% s3 q) e5 M# i" B$ F! a5 L% k) Y6 i% d9 ^3 _
if (extra_cmd != NULL) { $ R) J! ?" m2 k9 n, d9 ]+ v

( I: l& ~) |$ [+ g, B/ p, T7 ~+ ^后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php
" \( E' Y. z$ o那么我们就修补了这个漏洞。
+ h; }: B/ t# V2 [
1 ~9 v( p1 ?# Y. X$ }% {4 s4 ^9 P6 d6 @( ^8 I9 z  J
2、修改php.ini配置文件 5 e- Z/ U2 W3 |& y; j0 [& i: [
' y2 X% G1 ~# h  r2 |7 W/ i4 J0 ?
以php发行版的php.ini-dist为蓝本进行修改。
# q( L& z4 g5 w+ \/ ^% d3 J8 `- Q: {2 F0 A- ~
1)Error handling and logging
  |0 G4 H: f5 s6 T; ^+ a2 v在Error handling and logging部分可以做一些设定。先找到: ) n+ ^' S3 o8 Y9 h
display_errors = On + c* @1 p' x- }' f( w% k6 Q
, C4 P6 |  L, \& `2 q
php缺省是打开错误信息显示的,我们把它改为:
5 r( y) v  k' R) w+ v1 e  n
- ^( t! Q0 f" Ddisplay_errors = Off
. R% y! a; _1 ?5 p7 ~: W6 b" Z& M  `5 `2 S1 I4 s- [
关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻
( Z4 f& B) A  s$ b0 k% m* J' A- `击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造6 G6 W* y& s6 l: t
成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以& k+ Y5 G# k& @! y
下: $ Q; R2 g8 B' A: x0 o& E

+ s% {6 f1 o# l- h  q: l* Flog_errors = Off ( J5 G6 U6 m) C+ O" j
1 f- N" ^$ }: ?/ f" {
改为: 2 v( a0 z, Y( u% u+ \" ^
log_errors = On 1 _/ p* I2 p9 t; l4 }
  d5 C7 y$ w0 c* X
以及指定文件,找到下面这行: 8 |# b9 a  n6 q3 T* g

# B1 q+ }4 C$ Q4 g& V;error_log = filename ! a$ t( `3 \6 e3 x- t8 f; Z' ?

/ f6 p5 }9 R) e去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log & _6 V$ ^) N! W2 S2 m
  O7 C7 p1 h  R$ q
error_log = /usr/local/apache/logs/php_error.log
( h/ [+ d2 Y- t! ?+ p' v: `7 W2 D2 ~. N9 g' g' n# s
这样所有的错误都会写到php_error.log文件里。
2 p" D# I7 [* }: l# A
- f- w3 M# |8 t# [! m2)Safe Mode * ]. V, Y# x9 Y5 g5 [& E+ K% K

; d! x: V$ H+ }- {* Bphp的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在
1 ^- _+ G8 U" e7 `9 X; C: C* hSafe Mode部分找到:
0 Y9 a7 X4 I; I% O
1 l% Y& m8 d# \$ Csafe_mode = Off
, }+ ?$ v: n( T0 H$ d) R% N) q9 }1 X7 b& r5 b
改为: 5 j/ ]9 g) h  J5 |( L- w

+ ], J. C4 }5 {& J8 Hsafe_mode = On 6 ]: {, [' `- e. e
. G! J' S" X2 O3 b8 A+ _
这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它
7 a3 u6 d0 _# {% X8 S! i1 v的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行6 c4 Q# U2 i/ ]0 N$ w4 S' F
safe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下: & P  q% R/ O9 o5 ~5 Q6 i7 C; e

! R3 `7 {" P2 m! P+ w# n. R( v5 Qsafe_mode_exec_dir =
7 g' B4 q7 s5 N- a
1 H% |; t; H! f: S5 E% j指定要执行的程序的路径,如:
* W( n$ F! o! q: W$ w5 s+ i8 Y' K$ c) V3 d9 l3 D6 P
safe_mode_exec_dir = /usr/local/php/exec
/ I/ ~/ p3 @2 J8 v
% N5 R$ j. H0 L' C0 p然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行
# z! l- q% [  }4 R8 e* ]& c; A7 g该目录里的程序。
& N( M. _, O8 j' g) A
. d0 ]. L4 I8 {* ^- Q关于安全模式下受限函数的详细信息请查看php主站的说明:
( y  B3 a+ x2 V( G: [/ J( Lhttp://www.php.net/manual/en/features.safe-mode.php
7 [( @+ K# E) D/ `- g# w
" h( ]' {, r6 @1 ?' S3)disable_functions $ \+ _/ E* g5 n1 y0 g2 I$ x

# a* x, E0 z  Z& {如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这
. ^% n' w% A+ F% j) R+ u; R+ n2 X: J9 b行: - X# h3 J2 w& B1 ~) U

1 `) }2 ~1 U% h4 fdisable_functions =
3 i3 @6 r0 }  y( l5 s+ D# V& S- M; x7 @
在”=“后面加上要禁止的函数,多个函数用”,“隔开。 4 ?1 v# i* K/ H8 Y$ k

. _' _7 h2 d- `5 y% K# q* g4 T
3、修改httpd.conf
, d7 V6 B- m; r2 n" d, |
3 l0 N* L0 y( ^1 V7 A# V如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作
: i4 c& J" U: q5 i( E3 ^路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行: $ T- s- V. f7 H# z2 F) x$ v9 v
$ ]1 g- \/ h& Z; ~1 n! F$ X
<Directory /usr/local/apache/htdocs> 4 l: {: _' a% g+ S. l* p
php_admin_value open_basedir /usr/local/apache/htdocs
# z0 b. J& D2 O5 a# w+ y) H</Directory>
1 q3 R3 W% p) Y$ l7 w8 ~& u8 K" ?+ E/ d! n* L
这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打
2 B+ @9 w, o: v6 [& p开的话会提示这样的错误:
* z: E% r4 Z$ ~$ `: c
3 s0 u6 V0 P: x1 H+ O) W  YWarning: open_basedir restriction in effect. File is in wrong directory in
. L; k& g' e& N: `' Q9 N* W. N/usr/local/apache/htdocs/open.php on line 4 . w- o/ _% j& {& b4 k

5 |0 D1 c  C3 ^9 p$ k等等。 ) T9 |  _6 L  V8 X. m) ]5 v
" H8 [. |& B7 {3 A$ v/ }

4 R% r8 J- H% X1 N0 X8 a0 w# d4、对php代码进行编译
2 ~; m& q* P$ D, b; \# A" x5 V: h: A( O7 H) S4 j
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和$ o9 U) P7 |. B7 H  f
ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就; c1 P7 x5 B3 Z4 M4 z
可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统
) M3 d+ d/ o% F
: L8 y+ m2 _1 |$ y1 d* s
6 U/ q) Y7 l1 z) B6 |9 F2 ~ZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz
" r4 h/ u) p/ M0 bZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
5 A: R, X) U8 kZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz . ?* I& z( T0 }) V. H/ g
ZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip
6 g- p$ y2 g( L0 x1 T( J% t9 ]
& ?; O% {. d$ e2 Q* D优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里5 t9 f$ t9 b2 ]2 U% X, G
的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句
5 v5 S! b! O0 n+ d2 [  G" u- A, C9 Q2 b; w! s
; C. L- X  A- _+ r! f  A$ Y' O
zend_optimizer.optimization_level=15
, O+ v7 f2 Z5 F1 Pzend_extension="/usr/local/lib/ZendOptimizer.so" ' c$ w+ s. `' \+ A! y
; s3 X* I5 ?) i  i, M( n
就可以了。用phpinfo()看到Zend图标左边有下面文字:
7 M, l( K/ ~$ B  L2 }+ H8 W6 f4 o2 M) E: Y2 s. q% k! i
with Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies
3 t& r0 b) F6 y8 N8 c& w6 m: i- ~8 z  N! N7 i" `( k: D
那么,优化器已经挂接成功了。
- |( O8 [( s* Z2 J% d* S8 i1 V& y4 P% T8 G) w  w! R: O: l
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设
( U7 B: I) E3 T: Q( q5 ?- T2 Y" J计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。 : A- C9 a* |2 m2 }! `

1 P" J8 w/ W) d6 G. |php脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进% T& K( `7 b; T4 c" Q
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如
5 Z/ S0 H1 `" w- `1 M& Umysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。
. {4 @5 D& N$ Y, k* {3 ~9 z* V+ Y* G- D( _6 |

0 C5 M: @8 O; ?( y0 F- X+ Z/ O5、文件及目录的权限设置 3 o4 H) P. g- D7 r

7 N0 u; d. r4 m, H/ jweb目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,+ {; g/ V. ^7 V) q: ~3 ~
攻击者可以修改主页文件,所以web目录的权限一定要设置好。 3 M; m6 n' y2 x- y0 m

$ n/ c+ t; p! O8 f# T还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属' t6 J. Z8 v6 Q+ @; p
主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的# b) [7 y; F8 ?, n/ f8 B
错误: & F* f- {8 r6 X" r: ]9 C7 M
# Z0 k7 x/ [$ j! ?; R/ q; c
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not 1 |: x7 d3 h3 m8 ?, [6 v# ^0 \
allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php # j2 ?1 _/ T7 d- R, P8 D8 n
on line 3
9 S2 k( _2 h1 h# F& I" W. X
* X2 M7 T, e. {, R这样我们能防止许多系统文件被读,比如:/etc/passwd等。 5 A$ w" |( l% F$ [4 h/ N, p
上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。
1 _! A" Q2 e& n3 J- Z
) {3 d1 O9 z- Y0 G& y. |- t$ I5 U+ n+ ]& t  Y8 _% V- T
6、mysql的启动权限设置 8 ]% X0 q7 k* Y% R5 O

, B* E- Y9 G. Y4 [3 lmysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等/ P& p2 a5 v- N6 h$ o  d( B# e
系统启动脚本里加上一句:
5 k' @6 M: e" {$ G( Z
" x! ?" w' g1 ?/ _' P# r: tsu mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start"
1 x' a2 P$ _/ t" r2 M* Q
5 ]3 U1 O5 r$ H这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 6 V8 r" H( M6 i2 ]8 i: j
5 K/ p' g' \  ~0 L

" n) l9 c3 J% k, u- R/ E7 E7、日志文件及上传目录的审核及 $ d2 C$ H1 k# D. q& C% k3 U
4 v$ s  a" q6 Q$ y# a. ]
查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且8 s; v: ~( n% d" o+ ]
也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非# N1 J0 G; z! m0 \; k- E' J! Q+ f
法的文件,比如执行脚本等。
- ^6 _( m; @6 V: z% {/ k- b: `7 B& e$ L% B& u1 W

! C0 k/ ]  \" q* {0 ]- j8、操作系统自身的补丁 ' i0 L5 G; q' ~: O6 U1 s
7 a+ s! V* M! \3 A% e/ I: a
一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。
( x$ P" K0 Z0 \, V3 b, ^  \- i  n6 Z" D0 r5 m
4 k. W- M" t8 r( S
经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,# o& r, u& i7 t# V# `
即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 ; {7 {, q" a- _5 R, W
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;)
7 v/ E5 ?, g. G( K* [. F4 e) s0 t' Q# ]
) i0 G6 A, w7 k9 E2 }' P8 C( q3 `
参考资料:
3 l& H3 v& _* W/ R0 BPHP Manual
* _) U1 n: c; F  e9 l) \http://www.zend.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 10:16 , Processed in 0.024682 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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