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

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

[复制链接]
发表于 2004-5-31 00:23:03 | 显示全部楼层 |阅读模式
发布日期:2001-11-27
  g4 j5 e( y" r$ {. I5 Z9 V  P) Z" H文章内容:. C2 [5 d+ Q- Z# w" r
--------------------------------------------------------------------------------# e, A2 D) i4 D9 w; }# {

2 M9 \1 y2 f* f1 J作者:san(小许) san@nsfocus.com
0 D: i7 s' T& I2 q( y) j( _% x  q- n$ _0 Q+ U# i
--------------------------------------------------------------------------------) v+ O7 s* @: z  {* o, w8 K
+ G2 |/ s& S/ H1 l
前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以
- [, {3 }7 j8 `6 {及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配
' F* k7 g- h" v" M9 r7 ], v, H置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的
5 ~4 j4 G! _5 z/ Z4 ]3 ?8 m; w6 G过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的4 H( h( a, g9 W! ~
phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现& ?  n- S0 @/ D+ z7 K/ b- Q
在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题, H* G9 p9 ?$ n6 I% C6 s
了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。
- ?& G, N. k7 x
$ W% C0 c5 W/ j) `! m$ G% C9 H" H  x" C/ H. @
1、编译的时候注意补上已知的漏洞
3 C; K7 ]+ b4 J5 P; n" f8 \. a1 Q7 ~
从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突
# a) |5 _0 c; f" }; n) l( J- J破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源# a* D4 c5 \8 p
码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件( @4 j. c/ R' M* x5 e! h. |3 F' m
的第152行,也就是下面这行:
9 P1 e0 i$ X* ]* Y  U- I1 m- _5 T( ?  ?
0 W  }9 H9 G/ w8 e2 iif (extra_cmd != NULL) {
& L# ?9 Y& j- [' h' ?- a% G7 O& [
# p: g! z1 m" P# |; q3 P后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php & O5 q: I' g' ^$ K, d+ C8 ~
那么我们就修补了这个漏洞。
" r$ v& S! S* R- R
5 C) m( P% O& m. F: ?5 m4 ]6 K
! Y' N" U8 z( _" V- g/ x2、修改php.ini配置文件
; Q4 @* U* k1 W) [' V) N$ ^3 }9 ~- n2 s7 S6 e' M& ~; |
以php发行版的php.ini-dist为蓝本进行修改。
$ ^+ b" m2 W% [+ j
9 {- p  N2 `$ K/ V8 c7 z1)Error handling and logging # V4 J4 C7 b$ L8 P# s
在Error handling and logging部分可以做一些设定。先找到:
9 \  D8 p3 y3 c1 n  D2 n! Vdisplay_errors = On : Y) i% B7 n, L! ~
2 Y( }+ b$ K& s& I/ I
php缺省是打开错误信息显示的,我们把它改为: 8 ?; \, F  N! C' T3 q' W
& S4 ], a% A4 z, A8 r" ^. m
display_errors = Off ! C( N  k. k% j+ s; J

0 [/ k6 g7 M6 b- k* |9 g关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻6 i$ D, q3 e( s
击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造  z& r+ L0 A6 {, J9 G/ `7 o* K
成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以, l7 z# e9 c- [# q0 d; M0 @
下: : {  Q+ H, D% L/ P

& q, e* E( d/ J* p- l) F' L1 plog_errors = Off 3 y# o" N& w9 G3 e6 \) h

9 h6 L9 F! X* n  q改为: ' E  I7 i" Z2 J7 w
log_errors = On , n& P- n0 {9 R3 c
1 O3 E; c9 l/ v: R" G$ Y
以及指定文件,找到下面这行:
$ Y) A& l: W8 q
( L0 Q* ~* D9 \1 X1 f;error_log = filename   s& A- f. C" K1 v
5 T0 N2 c% A- ~3 L9 c2 b" D" v
去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log 4 h  y1 q- E2 n6 Y
: e* t0 n0 F8 P. g" m
error_log = /usr/local/apache/logs/php_error.log
- i* f/ Q8 I( G4 n" ~- {
  ?4 ]2 I! d$ W9 v. n) T5 h! Y这样所有的错误都会写到php_error.log文件里。
# U  L8 f( L& {' c2 F1 q. G, J/ M8 i( J0 f
2)Safe Mode
: X7 N+ |8 w! z
0 j5 }7 a! q2 ophp的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在0 ], p! |7 G0 G7 w6 p% c
Safe Mode部分找到:
$ t! |3 T- ^; N7 a; {( Q  I5 ?/ j, U( a& a
safe_mode = Off - ]2 i# l2 o+ b' d- B. r4 D% G
9 ]4 f& |; ~2 n8 C
改为:
5 C/ `3 e% z& j- J( b% w
/ y: J: t5 u9 m1 f6 G3 w& @safe_mode = On
/ n0 J% {6 \. f5 y5 D) k
. E& [5 V. G7 J( v" q4 D! R0 N这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它9 l% _, u* E8 w3 ?
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行
: L4 U) Z5 y& i4 C. l* r- J, t) Ksafe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下:
( M9 u$ N5 N  R( A& h  V7 D7 N- L9 [
" Y! K% _" S. \7 V3 Esafe_mode_exec_dir =
$ Q+ B3 H6 V( T7 l9 L0 U/ E7 n5 {  `5 V# X( H% }8 v
指定要执行的程序的路径,如:
/ R& d3 G0 j2 S! n! B/ }6 M3 l0 o
6 @! ?1 S- {2 Bsafe_mode_exec_dir = /usr/local/php/exec . z5 r! O% L/ {

6 }9 o- a( T$ ]然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行
7 m6 O. g0 i. g6 p' D该目录里的程序。 " c8 s! h& X$ Q* n4 ?4 ]& ]
9 M$ I0 ?7 I& \# [% r! H4 D( i
关于安全模式下受限函数的详细信息请查看php主站的说明:
  E, P. n/ N' {' P7 K: _http://www.php.net/manual/en/features.safe-mode.php
! P! u6 Q3 t$ D, Z; K
& B# v+ A8 ~) l3)disable_functions
& H" Z5 w2 g- o  @9 d  ?, c7 {  @; F4 N* |2 V; ?( M; M
如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这
1 V* {8 X3 q5 ~+ a7 \1 f行: ; T$ v0 V6 T0 ~; _/ T. h5 [
  ]( b2 x' c0 N3 c: \& f  @8 W
disable_functions =
9 I0 u8 F0 A1 g2 R1 `2 j5 i' }5 A7 W% P7 d7 E5 k; d. z1 n( a) l
在”=“后面加上要禁止的函数,多个函数用”,“隔开。
! ?& C" y! u3 w- [8 U- t! k) |* G1 s. w
' x# G2 D! h* U* _. E/ l9 I
3、修改httpd.conf
' \1 a0 H- q3 E  _; G% Y. k' {% Z; |8 {9 r" j
如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作( S" n1 C; C9 D* s4 J1 I
路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行: 7 W5 [" B" H- H( C. \

) |$ ?; Z6 g9 `  o<Directory /usr/local/apache/htdocs>
8 e, M0 w+ ~, ^/ _! ~  Y( ^2 [php_admin_value open_basedir /usr/local/apache/htdocs
) A* M2 b% p' G7 n. z. C/ W: I7 e</Directory>
, m/ N5 E9 }8 m. h8 W; \- @5 g0 ~# M: Y( U* k1 v9 J# w# M
这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打
! N  ]4 _4 }" y- W4 H) t9 |4 V+ Y开的话会提示这样的错误:
8 ?3 L6 h) l7 g5 s$ }3 b
* R: U0 u( \( U/ W3 D" V& MWarning: open_basedir restriction in effect. File is in wrong directory in : y9 N$ q9 \1 b8 t3 ^4 B
/usr/local/apache/htdocs/open.php on line 4 % g% q) b( V( v
" q; _* d* z) A# K0 v. e
等等。
) x. g& b: W! e% f2 ~3 R
8 P7 G4 T) S$ z
  i  L7 f# w, g+ G  F4、对php代码进行编译 % m" f3 ~- [0 |* V. z+ @. ]* O
; f7 h  O, ~+ E6 X5 H9 A0 y& n$ s
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和
* ]% A1 g6 m( s7 ?ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就$ ~: z* J8 v; T( H+ H; j7 D
可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统& u% _- e" H9 b/ x# n$ C, r

. `2 I; K' r) H  ?2 L: i' N, |4 o+ j. q, q- l
ZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz : \0 R1 s* a$ k! R' r
ZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
, K- U( I! G& WZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz
* _+ t& M7 z) L  J; \ZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip : u) N; v. o' g  |9 |( U  D
5 p* t+ v) r1 _9 V& `# _
优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里
/ P# w# x- Y3 n+ ^- U* O1 c, l的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句
* _8 B- f, g( c1 m2 J( @, O+ J  O  m) S

- P3 h' N8 k5 \2 h, K2 r6 |! \  Ozend_optimizer.optimization_level=15 1 b, w8 o8 S2 Z
zend_extension="/usr/local/lib/ZendOptimizer.so"
& X* b0 o0 Y% J& y+ o* a1 S: o6 l' K+ H4 C& z. D+ \
就可以了。用phpinfo()看到Zend图标左边有下面文字: 3 s7 L8 b' J& T9 ~
+ P. |' M, t7 G9 F6 C0 |) z" V
with Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies 6 O4 d* z6 X# ?) |# W

9 u6 O  b! i* R$ N* [那么,优化器已经挂接成功了。 8 w  J9 `7 o- @6 o* M! S
6 a$ ^3 X' R: u; d* f  x# z
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设. x3 r; w9 ^  o% l1 W
计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。
9 H9 E( d! \: s. \7 U4 p! c$ x' h1 _- Q
php脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进
; k, N; D5 W$ t% `% s  ^3 s一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如  W5 @1 M& f5 b1 u# i' @" U
mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。
! |2 C8 ~9 Y: F! {  d2 {) n  |( z- _: W7 X& k0 l! q1 Y

7 P0 l  ?, ~, l6 h- O7 M; E6 S* ]5、文件及目录的权限设置
) S1 J5 t6 s& }1 y4 p( h/ I# Q
8 D. _& ?) O  E; y+ b3 Cweb目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
9 z# F) R& O0 |4 s  t攻击者可以修改主页文件,所以web目录的权限一定要设置好。
& C# ~; q4 P# A' _% c6 A2 f: P' k1 \1 C5 g
还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属& ^4 N2 X- Q* w6 \7 s( @
主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的7 ^4 z& p, [* N5 L! i
错误: , r  f# f  ^4 H& G* E
8 K: K, V  P" t$ d" L! W
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not
: [0 h3 r4 K6 Y( l$ Callowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php 7 E1 A. ?: g3 d5 C
on line 3   J3 x  ?! l) f7 G/ I

4 I! n& @: [) ?9 L; }这样我们能防止许多系统文件被读,比如:/etc/passwd等。
/ u( H, t: ?7 _3 }' X上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。
5 S1 \4 |) v$ c
* n% O9 O' b0 n+ ]/ B- R* A# @& @+ ~+ ^2 B0 J
6、mysql的启动权限设置
8 k8 B' P4 M, X, Q$ J2 p& O1 g2 S
mysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等
8 `- u) e- J! T: _+ I4 H* A9 ?9 N系统启动脚本里加上一句:
) p+ ]3 V' K2 N+ t4 P' }9 ]3 r4 c% d: U% n, B( j- F
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start"
, {  S. f9 D8 ^( }$ `; i+ j
  Z: [" K% w$ o+ N: @+ R6 E# A  z这样系统重启后,也会自动用mysqladmin用户启动mysql进程。
" ^* m( ^0 Q( G' c$ J. d: ^9 Y9 N4 e6 x1 D) l/ R6 e

  m! F2 ~( t. M8 N/ U7 M! t7、日志文件及上传目录的审核及
; m. x" n# H; X# @4 B+ k
" M2 k4 Q3 F+ I- e7 ^8 h' M查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且1 q8 e2 l( S  Y  d& f3 F: v
也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非7 k1 e- d$ U& C
法的文件,比如执行脚本等。
7 e  R7 j! z6 L/ S9 v7 x; ?$ f
* J: ], H, L8 L( ?5 }, O+ @0 Y: t7 u' n. E8 a, ]
8、操作系统自身的补丁
4 z+ p" w/ x/ L: @1 n+ \" P/ O: d9 e6 y3 H  K) }+ W, W
一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。 ; ^0 E4 q3 a- Z. S, [

# l) k: [9 u" m: r7 {; I$ p1 ]" w6 N* D& @+ D5 a5 Q9 r& ~/ O
经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,& E, B0 Y* L/ t7 ]4 Z/ l6 `, b
即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 / O/ O0 |+ z1 [5 x5 @$ I
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;)
* M3 R# [# ?, j3 ~$ @+ g% p5 w8 B1 \  I! C) ^* D3 y0 R
3 `, v2 z1 E; I; A
参考资料:
, R- R# P9 E; n& }PHP Manual # U2 m" S' w0 \$ Y8 O& c; n
http://www.zend.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-30 02:50 , Processed in 0.018420 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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