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

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

[复制链接]
发表于 2004-5-31 00:23:03 | 显示全部楼层 |阅读模式
发布日期:2001-11-27
7 t1 ~* [2 K1 J3 l0 v文章内容:
; J! [4 S7 r5 Q" [) I0 B--------------------------------------------------------------------------------# O- A9 e6 w" R

- G4 l( ~3 f1 v6 [' F' ^作者:san(小许) san@nsfocus.com " P  y6 A0 I) E/ C" f8 |' G# }
! h, W! ?( o6 C  G& @
--------------------------------------------------------------------------------
% B7 W1 m& C$ k, I+ C) N8 [( g2 J; w7 l+ O( B. M
前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以1 y( b; O+ t/ B. ~4 o6 i. W+ a( U
及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配7 L* N' `4 U; x
置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的& h- W5 \$ F! T8 G9 e
过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的
7 ~5 H( c  x$ r  ophpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现/ u4 d) w9 A" M3 ^) w! s
在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题$ a  s& f6 J) P
了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。
$ U- g. J3 Q# j8 p7 V" W+ z
% |% |" c# U; ]- }3 I! C# a  e2 X3 Z3 f5 P5 M# G% X2 @8 P
1、编译的时候注意补上已知的漏洞 & o1 g7 I  e* b1 S( `, v

$ n! B0 v4 s1 C# k9 e. H从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突  R; ]1 b+ z3 y/ f& `, ?4 D/ ?
破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源$ [( h+ b8 E9 w9 T- q
码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件
8 T- a5 K9 T# y1 K* }5 q# g的第152行,也就是下面这行:
. w0 \" u7 U7 y) n- H$ ]! T8 R
8 y  }& m/ }% Lif (extra_cmd != NULL) { 6 w7 l7 p$ ~, t$ i; \- x
" m( h2 r( o" G+ m* f
后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php
+ b, Q6 v6 ~! c2 p5 v, {那么我们就修补了这个漏洞。
0 ^" ^6 @* M, u0 f9 z8 A4 _' A. f3 ?( Y/ ?* v4 \+ F: L2 J

# P7 k, L; f) t* D1 l1 D2、修改php.ini配置文件
8 K" j- k# c  ~6 K* y" ]. u- ?! O& u
. S  a% F' d, [2 O' v/ a9 b+ p. c3 C" a以php发行版的php.ini-dist为蓝本进行修改。
5 k5 V8 V7 d4 J, V: z* h" W/ l  n1 k' p) z  w# G+ Z
1)Error handling and logging 9 g- b# c$ K: {5 ?
在Error handling and logging部分可以做一些设定。先找到: $ [; k  m5 p: M' y
display_errors = On
; ^0 D8 S& z' n; z1 R+ T4 ~' B1 F0 I# F6 h: b# ~/ I; C1 ^6 g# H
php缺省是打开错误信息显示的,我们把它改为: 0 A* P$ M7 x- a$ [& b' r
' p; w  |# X; c% S
display_errors = Off " `4 V" v8 y  v# C# Q
! c+ s, x$ i! v) v5 Q7 `( m, M1 a
关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻
8 B- t! Y7 c7 B( R' H/ U" T击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造/ {3 D. U; ?4 P; l; q
成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以$ o- Z' h3 M! ^, d
下:
5 I2 L7 m2 m' e( k  H) s4 H- X$ L: g5 M% O
log_errors = Off
9 `* T6 M9 E( ?1 W+ I" I8 R" v
7 l% X6 v7 C% E7 s改为:
/ }$ Y0 l, Y. [; T1 wlog_errors = On
" l7 K9 c2 W9 s3 S& h' o$ {
/ _2 n9 ~/ Z" Z! E以及指定文件,找到下面这行: 0 Z! y+ O( g" `

) j7 T) v% g3 g6 G: F' c" e;error_log = filename
2 q- ]+ u$ u( V/ ?0 v: W* m9 M
8 n* T/ _/ a8 \! t去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log 9 y+ `+ E8 s: m7 l

# s0 N0 F8 W" x7 `0 F4 x. Merror_log = /usr/local/apache/logs/php_error.log
' w) q, v- Q1 {2 C
6 M# v( `; E* e5 l! d5 K这样所有的错误都会写到php_error.log文件里。   f  q6 E: n3 M. E% o# E* D! O" U; _
' }# g) }0 o0 l4 M4 k4 d$ w2 X% @- e
2)Safe Mode
5 ?% c! @/ u4 N/ [. B
, ^4 u& M! U' Q; ~3 _php的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在
, F9 C& R% N6 s  f1 t' ZSafe Mode部分找到:
& a: i3 `  T5 C5 f! T- X
! @. s0 Z: P6 I; Ysafe_mode = Off
' u1 r! }: s' c$ L: T% n7 J. x( K  i& j- @) `  r
改为:
3 F( i4 V. C- ?. e" K! d; u
! a6 R* C& S/ x* ^safe_mode = On 1 C" ?! j: O3 h* W; `% n; Z

/ R3 c2 x, {+ i3 n这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它
7 T2 I$ q* U& |- {, h' j% m; d的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行
6 G; U8 |1 N: ?safe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下: ( |1 E- i, M2 h: L7 N: F
  l9 `; T9 H( @( U1 D7 ~7 D
safe_mode_exec_dir =
! v+ |& B4 ?8 Z7 K+ e* r8 B1 `  c, E; Z. K
指定要执行的程序的路径,如: 5 p4 J, R4 Z  s6 }2 v* _
8 }! }0 |* a6 L3 X8 o/ h' U) o  |
safe_mode_exec_dir = /usr/local/php/exec ! H. n3 Y4 S. B4 }4 K: z! t  V
9 o, ]; I& c# J) F$ W' J
然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行6 s( |) P5 G, J4 J
该目录里的程序。
% l  C9 P; t% B6 L+ o$ |" n; x( N& I
+ w6 Q! P7 V0 K! M9 S( [% f1 J关于安全模式下受限函数的详细信息请查看php主站的说明:
9 {' h: }1 d$ h& l5 thttp://www.php.net/manual/en/features.safe-mode.php
' y  U2 g# m: M- v+ g4 g. o8 \& q$ p" M+ `4 Q. `/ q8 M, N4 z
3)disable_functions
* m/ x3 M+ _  N# L* u8 q' E/ z. E5 [& g1 c0 ~  Z& V6 S
如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这2 @2 D, b- T  c8 |" T
行:
/ c! k( z$ d6 n
; ], V+ n! ~# C3 Hdisable_functions = , H' J  K' m* m' n
9 \+ k# A8 J/ O2 H* g
在”=“后面加上要禁止的函数,多个函数用”,“隔开。 1 h; Q% [& ?/ l; A7 |, D& a9 G
2 n( |: |: m! D! {
( V+ f& e! F' y4 t- t( V
3、修改httpd.conf 0 w- ^- \+ i6 H, M  {

. C  Z9 m+ m) S, E: \* i+ b- i; x如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作. R3 l, ]: u) X, e; M2 P0 {  b
路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行: 3 W7 R5 U! E0 I, `0 h) g, ?! O

1 a0 ^2 B0 D/ ~8 A2 v+ ]7 b<Directory /usr/local/apache/htdocs> 0 C5 G) d$ }6 Y
php_admin_value open_basedir /usr/local/apache/htdocs
: u9 O7 v; O8 w( D% w' X, D</Directory>
; D, b1 I2 p( l  x- H% d- c$ W2 W. ~/ f, G3 b3 G6 V! W, Z% }2 @
这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打3 y- ?# G) q2 d
开的话会提示这样的错误:
5 D) K: W! h0 A2 h; [7 h' ^! h! k  [, L/ ~9 m
Warning: open_basedir restriction in effect. File is in wrong directory in
( J; U9 g+ n' {1 J/usr/local/apache/htdocs/open.php on line 4
. s8 b3 P- v2 m
: K% {# |, @( |9 L1 d: c, m6 p等等。 - H* P$ q0 s) G. o; y( v
' p6 A9 ^' i& T( u& a" }; K- b
# Q9 m7 @% [9 K0 r6 x
4、对php代码进行编译 / \1 X4 j, e! R

5 ]: z" {$ m4 Y: p0 W+ o: lZend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和
! x9 d* e# j  r9 U$ QZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就
- Q2 u7 k4 ~, D2 c$ T! h+ @" M可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统
" s4 x4 b3 I( ?& ~* }1 Q, R
( U) ?8 s: ^: P! R& q
7 x+ G, W& {) u! Y- I# ^2 A0 TZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz 6 B+ |! @- J- B9 _9 n6 ^
ZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
9 a' w3 v4 ~: s# gZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz
  e8 \3 c2 [  u  U$ n) bZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip - Z# o2 U9 y1 \  V

7 @2 ^5 m: i( \优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里
4 A, T4 |. E+ W) q3 u) M的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句
& ?( `2 i# ^! V* c" Q$ Y' n; c+ q
+ Z% o; w7 r3 C0 C6 Z0 ]! _; `& i1 M  _/ h0 {5 D
zend_optimizer.optimization_level=15 4 S; }9 W( j7 y
zend_extension="/usr/local/lib/ZendOptimizer.so"
2 p! L8 V  |. s% I7 v1 `+ W8 }( k) `' C
就可以了。用phpinfo()看到Zend图标左边有下面文字:
* q* c3 s! J" Y8 I/ j
. ?6 b( _7 @+ Z2 M0 M; pwith Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies
0 k. E, s3 P  s) {
' b, B7 q& C1 g+ |; J3 f8 ~% A" g* E那么,优化器已经挂接成功了。
. A! B1 f( s( a6 {7 G; {3 O+ |) g$ X* D1 `0 p: G2 g: i5 g
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设2 F" q+ C& w! t( {5 x
计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。
0 [9 B1 z' l: G3 [3 p) R+ U3 C# J9 n$ o, l# e3 w
php脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进" r; u/ i' [# Z, D
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如
- G8 J1 m# o1 G9 ]5 k! V! z5 s0 |mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。
% r/ p$ o+ _% L0 A
) U* S" U3 j2 Y' m1 F! l0 w9 U8 g7 m3 X* U) ^  D- \1 |
5、文件及目录的权限设置
) }" g1 I" ]3 {1 D
1 r! J" x3 f9 M% T1 qweb目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
/ _* m. \& _' i) z  Y攻击者可以修改主页文件,所以web目录的权限一定要设置好。
' e" _& Z# G) L& X+ _$ c' d1 t+ W: _3 [+ {' V! K3 y
还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属( X" N" @4 K2 `9 @% d. Y
主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的
' Z7 |  Q3 s! \+ h9 Q/ u错误: 7 [& F+ p+ n( T' b5 R6 X

" `# x( c; r& W1 V; ^; h# qWarning: SAFE MODE Restriction in effect. The script whose uid is 500 is not
6 p7 L- P" S3 G  f2 T) c# s# T6 q9 jallowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php ; Y9 s7 J9 ]) Z! I
on line 3 6 y, q- ~8 u3 Y4 A, s& i; ~  K

; ~3 J+ k" w# }" U" Z+ h这样我们能防止许多系统文件被读,比如:/etc/passwd等。
6 b" N, u8 `3 _/ m上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。
3 K/ j. k0 k! o& [8 b9 D& _: ]# c( V- L' y9 F" F
/ K4 p% n6 e1 ?6 A( E3 T
6、mysql的启动权限设置
0 ?+ ]5 R& i! p) O& g. g0 ?" L' s+ U; E/ F8 N  F! }
mysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等- V$ |7 P. a0 w' Q) l
系统启动脚本里加上一句:
, ^9 k2 o4 p- q8 s7 N* d4 U
9 |+ h. A" R" G. \/ Xsu mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start"
% P+ I+ @+ O# t1 c
# D' i) m! y) q这样系统重启后,也会自动用mysqladmin用户启动mysql进程。   Q( y: i1 s3 D8 Y5 Q& I! H
5 o- |0 b1 y$ V2 u3 V
, k  A. h' |: [' D5 z
7、日志文件及上传目录的审核及 , \; z, O) X* e. v1 p. v) k
+ L9 `& `+ z  F  l# Z
查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且$ K/ e$ h& t! X. I! i$ r
也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非
- R& U6 |! z& T; @# \法的文件,比如执行脚本等。 7 `) ?  h. g: ^7 W* U
# ~0 K2 z$ s7 k) B" X! }( U
: U: |9 y  u  W4 w; N
8、操作系统自身的补丁
3 k/ r  W. O9 k
8 a  Y9 R5 r7 r( D# B一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。 : V, P( `- p# z- v
' F' s  n( {7 Y  ~, O
* W! a9 e4 O- y# r% \# j, a8 j
经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,
3 F1 v3 ?; z4 F; X即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 7 E2 X& ?! j! Z8 |
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;) 6 a1 _/ S! G$ n9 X) E

9 ~$ Y0 b( S" c/ r) Z
3 e& G4 [# m" C. X' I参考资料: # n. S6 B2 g0 _/ B4 R3 s/ ?. _/ S
PHP Manual - u( i2 C/ h  {$ r% R- v* X1 e* k
http://www.zend.com
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 08:48 , Processed in 0.019771 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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