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

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

[复制链接]
发表于 2004-5-31 00:23:03 | 显示全部楼层 |阅读模式
发布日期:2001-11-27
& }2 e4 I2 E2 Z% D3 r/ l( F文章内容:
; S% k2 @7 `' c0 l--------------------------------------------------------------------------------" Z2 l( b6 w0 e' V- R

& Z+ `' ^: \  k( p1 l; ]) O作者:san(小许) san@nsfocus.com 9 {1 f% A7 i/ W2 v$ a0 _

& z! \2 r; F4 Z! t! Z# O0 f9 Z--------------------------------------------------------------------------------0 q. Z, n! k  V  P: n

2 x2 L- `9 j3 O$ T) t. D$ s& [6 j前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以
% i# _; I2 }: @$ @及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配
9 y& ?& ?# U$ W3 M置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的
3 h0 U; f2 G9 b3 C" B' B过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的# V8 c/ E' [% t7 B! F
phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现# q' B! G9 l  [
在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题
0 [  X) f& c0 s# C, m5 S9 F了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。 - d% l& u, d3 w7 n- \, q
7 J/ ?% `1 m: P. n  y8 a

- a1 j# I/ g* ~1、编译的时候注意补上已知的漏洞 , Y+ w1 f, g8 M+ u8 x' U
5 e0 U& @7 b8 V* K" @& K
从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突1 c. N9 i( O* I* N* v
破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源- m. l: ]. d' ]9 Q, \1 z; ]: x# ?! p
码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件
/ _4 S9 e$ c$ g, I2 k的第152行,也就是下面这行: 9 s% k2 H/ v( W+ D! q( U& y
2 c6 p& U" O5 T1 S/ C- L  x0 I
if (extra_cmd != NULL) { ) d" C" r1 G& \6 w" V
* g  u$ P6 Y! r6 }
后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php
9 ?: B; w( I6 g7 ~* K: B那么我们就修补了这个漏洞。 - }1 i) m5 I7 p  ?

1 E% ~# V# ]3 K" Y
  i: S  ?2 j2 x* i2、修改php.ini配置文件
4 k3 U2 V: @3 P; ]. ^  P' Z# T+ J% C+ v4 e; I/ P. j
以php发行版的php.ini-dist为蓝本进行修改。 * S$ O2 L7 C) M, M: l4 {
! c; b0 Z! t# F0 s1 ]
1)Error handling and logging
- }# p: {6 H, e, U: \& T2 e- H在Error handling and logging部分可以做一些设定。先找到: ; V3 A3 A0 F- Z! h6 m, s
display_errors = On
% g5 J! [$ K+ `: w' E4 G6 T& q, ^  h' O0 m+ Z% Z1 _  H
php缺省是打开错误信息显示的,我们把它改为:
, I+ @! w8 B% t# \- Y& f+ i/ a- W; g8 R
display_errors = Off % J$ B, }# e6 x* `. J. p

9 L* x. X' A/ z8 Q: Q关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻+ a8 r- Y( J1 c& a8 s' j
击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造
+ x7 k  _7 B/ L% h7 ^% a6 K# z成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以
6 V, Q% H2 E: ~下: 2 b/ \9 \$ g0 Y! p

5 b' e: M- S1 Jlog_errors = Off ( ]; v7 R* d, o8 k$ `
9 w# k! w0 l7 Z! |" l. g# |
改为:
( H+ W6 c- Y% L' }: c1 Dlog_errors = On ( ?, m6 y5 m% S

% I6 `: R' ]. u' A! ]6 D! T8 Y5 f4 j以及指定文件,找到下面这行: 3 l7 g4 z' q& i3 _
0 k, @+ |$ f1 s) _5 n
;error_log = filename % Y- V7 i% X; J1 L! V( k

% G( L0 e0 i: t' ]1 N9 q' I& d去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log $ x# W) C% ~4 f1 S( z& ?- \9 p! s

  G. F( |/ P" W( e1 o* Y4 [# \$ ferror_log = /usr/local/apache/logs/php_error.log 8 z9 ?: C- ^4 s! t
! d! h7 y" {! M, ~
这样所有的错误都会写到php_error.log文件里。
2 w, w! m# p* S; V" q; c1 E6 Z4 a1 T
2)Safe Mode
) a6 c: }5 a! {! f8 Z) i2 E, D" x( B" S
php的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在
' m* I# U+ {6 ^5 mSafe Mode部分找到: ) p9 L- e2 \, L2 E- x; c, T

1 k+ h$ {. m; ssafe_mode = Off
) O4 i. R. w3 Y( _8 Z, r6 F% |
- g! D9 P. [7 j+ j6 }, R0 Z7 O改为: % N6 P% |( d8 g
% Z1 D0 I$ B+ l7 F
safe_mode = On 3 u8 z6 a, a) O: y0 F3 ]
. v$ L& L! ]6 k! U7 }, v. J5 o
这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它" F$ M3 D/ [) D% V/ k0 X4 m
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行
, b* ~4 x3 E3 h3 t+ Z- Csafe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下:
! R' |. \- I# w0 U9 ?6 }% }; C
$ t% K; [+ ^1 W. g) {' Ksafe_mode_exec_dir = - \. D7 M! d/ [- x3 S6 i7 X/ h. M  w

% t- i5 ^  b9 D# l指定要执行的程序的路径,如: . h7 ^9 H+ J2 t: _

9 @% \( P; i' }' q6 ^; {safe_mode_exec_dir = /usr/local/php/exec
" a) w) J7 L7 [( E7 x
( v: B/ ]* g7 ~* a1 Y- B9 o) [! n然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行
* A  l  K0 V( ^& Y; `" t该目录里的程序。
* a$ K+ J' r# N$ w3 s. C1 W4 ?! {* D9 _3 N
关于安全模式下受限函数的详细信息请查看php主站的说明: " s6 @0 W2 W) v1 p# X4 g
http://www.php.net/manual/en/features.safe-mode.php # Y2 z9 Z. V- [" X) t: i
$ W0 e* P5 J8 f" U  ^
3)disable_functions 9 Y3 B/ [' n0 ^" K
( A" _) n8 V8 v( }4 L- E0 I
如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这6 S$ P* f# z- y# p/ T5 s+ H
行: - l! p/ o, ]) b% g
. n  j8 C8 V6 W5 y. J
disable_functions =
( }4 ^' ]) L/ ~- v% H) A& e
/ h0 v4 Y' v3 _  F1 j7 }% _+ O- p2 w在”=“后面加上要禁止的函数,多个函数用”,“隔开。 % p& b; G) n3 D
3 e! J7 [  r0 f5 C' I& @

5 L% ]  l8 c% J! m! M/ A* J3、修改httpd.conf
* _) w- ^0 u' m" _' |* |' `" w! t
% I, G9 \# w! P% U- V0 N如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作& l1 K. l8 X" g& O0 a. \1 k
路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行:
. |0 e( K- K1 b: \/ p- D' g9 H( `9 L6 m* _. |, d0 F" d6 k
<Directory /usr/local/apache/htdocs>
8 t; L* y/ h; _" S1 |* A* Uphp_admin_value open_basedir /usr/local/apache/htdocs 4 F5 ^/ {! l% N1 L% h5 y: W
</Directory>
3 |* O3 H- L! H" M2 j" D. P9 e
' e8 g2 Y$ o% I& C4 `' g0 \* p+ e这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打( G2 B# f/ b7 N# T' f* Z; u6 L; g$ f
开的话会提示这样的错误:
5 @8 E9 N2 c! d' Y* A. H; Y" v* S' _9 J4 j
Warning: open_basedir restriction in effect. File is in wrong directory in
" e' s& f7 Z, R* ]/usr/local/apache/htdocs/open.php on line 4 1 \0 Z5 x( `' J! J7 g8 D
9 i; M% F  R( x; }
等等。
0 ?! O' v9 l: C& P( p
  i5 k0 p& ~1 u
! s( q8 D. f" I  l8 z$ z4、对php代码进行编译 1 k7 {5 T; |# O, [& `( Z
: c# ?& E, b3 H8 r" Q- W% h
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和1 e; X0 h% ]6 @" q  W( o/ t
ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就' u; F9 r( e$ A
可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统  Y; ^3 _# P9 G" {; X& Y' b
1 D( c1 \' \( M6 u$ S) t' l

* j1 ]9 m6 a0 S1 {8 x& V! p  p4 KZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz 6 J1 i" |# a! m  z5 k! n2 s
ZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz + q5 b4 o. f& N, v( p, h+ e
ZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz
# O$ X  `( |- g! p- X6 _7 jZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip
# @. W1 x; Y: L; }' Y7 n1 {: C) Y) \9 f* e1 C/ P5 o8 Q$ l$ J( ]. p! d
优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里
( m! A0 J2 b  n9 b* @& K的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句
7 x& l8 Z+ d) O9 c9 [% g- u# W! m+ c9 y
6 V7 |3 S7 {4 J* F# l+ m
" W/ N" m3 B1 `9 L4 y. y: P% xzend_optimizer.optimization_level=15
2 [6 m1 M% T: C/ q, }4 k, k( Nzend_extension="/usr/local/lib/ZendOptimizer.so" 3 [5 M" }9 q5 M& Z. r+ t6 V
# {" ]) x/ n/ p8 @. G
就可以了。用phpinfo()看到Zend图标左边有下面文字:
+ r! q0 w" H, a
/ S$ d' S9 ?1 A; Qwith Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies
' Y# r, Z2 L% t" p4 G- }8 A- \+ S8 J6 }  w; l& Z' k$ K% C
那么,优化器已经挂接成功了。
3 r2 T  \* C7 n8 ?% _1 g0 \) @; ^7 u. U) L# y
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设
8 ]3 @8 s6 y3 A2 U% V计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。 3 `! K8 U+ |/ P& @- X( T

7 _, D- j( m5 {php脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进0 |; s8 V& w0 i3 O
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如
; Q" M3 d, j) v3 Hmysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。 , o' ~$ _: ?. ^3 X

  m/ O+ v1 J. R9 B- n+ D2 L+ `  ?, l% h5 O, e
5、文件及目录的权限设置
& N+ ]; @( g6 @# F1 J
+ M' G- H5 d6 h. i8 |. i2 _8 l! pweb目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
" {8 Q# |. U( X3 Y+ m( ]9 w攻击者可以修改主页文件,所以web目录的权限一定要设置好。 ! a5 F0 C- z8 q; x: K

0 e# O; Z4 M/ L0 ?/ q还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属. p2 {! }! d/ T& G0 O6 P
主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的
* E* T5 G) [6 B1 y错误: . P; U/ s1 j7 q& S1 j5 X3 b

! K5 b' J3 x3 g1 t" k3 p, ?Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not
- E  B( r9 n! _! sallowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php ' u7 I6 G# Q) ]* t9 ~$ W: |
on line 3 : j' ~- W6 i- Z7 g5 U( @
9 x8 W; c2 u9 S+ f1 y
这样我们能防止许多系统文件被读,比如:/etc/passwd等。 8 ?1 _: h4 Y( b! e  ]# `
上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。 . U( E( g/ N( G
. k2 S4 E0 H3 j# d5 S

7 I% C% z% `0 T+ b6、mysql的启动权限设置
; E% t. S9 I- Q& Y* k' @% R
  T' L5 M4 Y. u8 R9 N( pmysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等
) Q) t, D$ c, x* C, b, B3 q7 i系统启动脚本里加上一句:
1 \8 G7 m6 @/ I9 j* P$ j* V. x' B) e5 g8 `$ T
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start" # j* `7 ]* e* Y2 ?' J1 z5 C

8 m: ~$ v7 @1 }* ]8 J这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 $ v1 z  g5 w& D4 s) S' C

; M' e- U# [) K* K9 j( v9 a% H  w
7、日志文件及上传目录的审核及 6 K0 v/ I1 s) r. Q( R# U$ Y
' G, _3 H' S5 n; ^3 C( l9 s0 v
查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且) a! w0 p. ?0 z+ A- K
也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非, V0 I$ M3 |% T
法的文件,比如执行脚本等。
& t; o5 M9 h; Y" q$ J2 i0 b
$ o& q7 h8 u' A1 `7 r& k# R# Z9 _* r' a4 b" @( s2 h# Z
8、操作系统自身的补丁
) ^. K- S# g. U# _' a! W0 {+ q3 v' R7 X& b: F6 R0 Q9 r# V
一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。 3 G% X* i( A9 U

. ?0 B: c9 Z9 R  w
$ X3 e9 ?9 r$ \$ C' L经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,
5 o4 h5 E0 ?  O! p2 `- {1 T即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。
4 k1 _/ d; J/ M/ f5 c! v2 n) `如果您还有更古怪,更变态的配置方法,希望能一起分享分享;)
7 w: f& T4 O. l) {5 J) C" C
2 V: N7 r  M8 \6 d4 k/ f+ e4 i: h3 Y/ A6 M" L7 B6 {
参考资料: 2 m! Z3 W4 r& z! x! Q. f
PHP Manual 0 U) G, J: Q0 p4 Z! a+ R# G! V
http://www.zend.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-20 07:49 , Processed in 0.036129 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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