|
|
发布日期:2001-11-27
4 r: C6 b9 G+ O' ~4 o6 j( J% S$ z文章内容:
4 ~# l. V8 O8 p! v6 a3 a2 x--------------------------------------------------------------------------------
' } K# H- e: O3 a3 w+ R+ ]
2 p9 x9 ^: R# w3 j; j, d2 }作者:san(小许) san@nsfocus.com
% b' d6 V) L4 x% `
- ?' P8 u& S1 T% m4 g- k6 E--------------------------------------------------------------------------------% z2 M# H. C3 a9 A' b: i7 ? ~
# z E! L8 ?9 m/ y T前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以( D, O ~" v1 E; ?; C
及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配& K7 k1 @6 [! k. V* Z3 O8 V
置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的0 `8 v4 \! A& i3 u
过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的" L7 c b! u" S. j- M5 G; _& y
phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现9 E2 X0 A% d! _
在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题5 P, O5 k5 s2 z. l7 J9 h$ ?
了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。 * x, l% B. u5 x+ }& a& \. ]. I2 A
6 R, M H% R0 n1 p- w, i! b: y& q2 [+ T$ R3 N O9 e% ?8 ?' h! {8 I
1、编译的时候注意补上已知的漏洞
- K6 K) K: p8 g- \
8 S+ o1 E6 G7 `1 O, w从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突
+ ]1 g5 r, }/ s4 ~破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源+ X2 U, A9 v+ J9 l, h
码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件1 G# G; g" ]1 n* J" F3 ~8 G: d
的第152行,也就是下面这行:
2 P9 R1 O4 I: e5 a
4 F, O) N6 c2 r3 I- Yif (extra_cmd != NULL) { & z7 @4 p% k1 o/ [, A. b
# G& i( T, i6 {: x4 Q& `
后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php 1 i' z4 a( w! f' @
那么我们就修补了这个漏洞。
& P' N& B" Q5 ~0 _: s# D0 R3 t- J2 t! b
, R: |) X/ [. K$ S2、修改php.ini配置文件
! Z3 G' ]; c! U* a s" t. ?( b0 a: C I! d- ?" \1 R6 M
以php发行版的php.ini-dist为蓝本进行修改。 $ X0 T- M2 r) k2 r
, `% P) o# l( `2 {; X# e1)Error handling and logging
: M6 ?7 y" Q: ]在Error handling and logging部分可以做一些设定。先找到: 9 A8 k8 B4 z6 \" O: }: S+ V
display_errors = On
, m7 {" ?; T, A" q$ U3 W/ e- } X! }0 H$ [( ]; }/ }
php缺省是打开错误信息显示的,我们把它改为:
$ F4 M: L' R6 R: }# {
, y0 G3 K2 H' Xdisplay_errors = Off 1 h# l% O( r5 ~
; t; ]+ P5 I4 F- j X' H' F& n
关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻- o% E( W/ v6 b: n, k) @
击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造
2 b4 ]7 O) m) j/ K1 D- n成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以% G- |/ l: E/ Y) M
下: & q0 C' `& Z" X3 k) w8 X2 _0 O
Q/ G5 j' N3 f+ I# L$ b6 T }" }log_errors = Off
D7 [# x$ C9 E! x0 k' c6 I: I+ W% Q4 w$ u9 J4 z, a5 z
改为:
+ A8 i# n2 ^& z9 l/ N$ M' Qlog_errors = On
1 {7 D$ I; j1 k! M0 Z2 L1 T% E& _% b8 }8 L
以及指定文件,找到下面这行: 5 r1 p7 E( p5 v5 P' c
" S! d0 R1 S# q; |. w' O, j
;error_log = filename % ^* A5 ~% K" ?
& c3 ]; C) J. k去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log 6 t( R+ p9 o3 R: w( i Q* G8 N4 G7 K
{$ v8 I1 h; b, P( f( B$ t
error_log = /usr/local/apache/logs/php_error.log
' M. o; F2 @3 }4 k
; w6 ?3 U5 O% A* X$ E g. I这样所有的错误都会写到php_error.log文件里。 9 c/ {/ \3 S& t' c; Z8 v
) G9 r" e1 ^) A
2)Safe Mode " ?3 W5 {, l4 v6 _9 O& i2 b
6 O( }" @# j) I- u( `# [2 G/ Cphp的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在# @% W; @. X* _4 ]5 K& x# Y9 a- E0 s/ j
Safe Mode部分找到: 9 ~$ u$ e$ D8 b1 j1 f
; a. ~) V- Q) z
safe_mode = Off 7 z/ j9 C- ]7 C/ ]# \+ b& y) j4 I& s
( p" W y6 [# b改为: + ^/ X, @) u# ]8 F7 n; h
* A' P# M" N1 e# ^safe_mode = On
( a( M+ l. I( j/ v$ d& U8 U5 N7 X5 h% k1 \7 D3 ^! g( e1 N5 j
这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它4 k \5 \& U, ^) m, e- N( y
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行
8 Y) O6 e; X! }3 P2 E1 Q5 e5 s% jsafe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下:
% w+ g8 _% Z2 l7 n+ a3 x: a
6 X$ P- m B8 @6 `* F) x6 Xsafe_mode_exec_dir =
7 ?5 g' A2 c) F, k) S. p0 `( H0 G, Y0 p1 y5 H
指定要执行的程序的路径,如: / H8 E+ K: j; J) T, \4 Y' L
; Y6 m" P% j: L2 A4 G4 ?safe_mode_exec_dir = /usr/local/php/exec
q0 k7 ^( H( u9 `" ?3 G3 \. M: e: h
7 i0 M+ `' Z9 _/ q8 t; h然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行. ~9 }/ N4 M3 ~# g/ T$ P3 c
该目录里的程序。 . X4 `5 U( k4 I
# L) P/ c4 @5 K* V6 l2 Z6 R: m0 R9 ?
关于安全模式下受限函数的详细信息请查看php主站的说明:
" L8 |3 {+ ^' Y2 X/ ihttp://www.php.net/manual/en/features.safe-mode.php # E) p5 s9 h8 K8 v& F
( K& F; ]6 R) N8 D, |: E. _0 \8 x
3)disable_functions 6 `* t$ F* ?) O% f% } X
: Z6 |5 o/ n$ }; f3 A$ X" t如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这! k% \# B8 E5 \( j. B( d; R: |
行:
4 [7 w2 a% _- Y0 ~2 k' g$ f+ B* ?2 O3 u% ~( F$ U2 o3 s* m
disable_functions =
9 Y4 b4 T' e! ~' N% p! w6 J# b
6 G/ ~5 @5 F# l6 ~2 L9 s在”=“后面加上要禁止的函数,多个函数用”,“隔开。
; q& h+ q# J) r
( R7 O$ `0 O, ?' u' T0 o7 A3 d; ?+ G( v3 t) z3 L9 w6 P& O% ?( @' ?3 k
3、修改httpd.conf
+ W% }2 v5 O3 m( ?6 @
i0 C+ L2 K" E7 C如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作4 a$ Z; \7 o; N3 s9 \0 z8 W) |
路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行: % e9 I) H5 C# l5 P
# l; j! D0 A6 H( d& o }5 Z, W<Directory /usr/local/apache/htdocs> 6 ~# Z9 E+ [1 T* m k, A
php_admin_value open_basedir /usr/local/apache/htdocs
" u4 `; B0 j& s</Directory> & O" C! J; @" l W
4 b7 b7 Y1 Q% Z% k1 i
这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打$ L. N- Y, s7 ]1 n; D" I1 n
开的话会提示这样的错误: * P H* B1 S+ X K$ G+ v0 T! ~- c
! @6 p9 I9 _2 r
Warning: open_basedir restriction in effect. File is in wrong directory in
# j7 V- u; K9 H3 }! f( X* h- e/usr/local/apache/htdocs/open.php on line 4 6 ^5 W) T- f4 b y# }8 g
- ]+ d' v4 P( D/ A/ Q7 f/ Q r
等等。
$ E7 T6 O. m! m# {' x- d/ S# @7 e; J
6 h' x4 F' m4 K" h" z+ G( X0 ^ [! ?- E5 G' k0 M
4、对php代码进行编译 % b0 C' T( }+ C4 L/ t
( v- L* H! K+ {% L! L7 j5 B
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和
: Z/ |9 b5 L- XZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就8 n! s* k4 r( L! T& Y* J- ^+ u1 H- I
可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统8 @3 e% n7 W: b/ M$ s$ c7 B
: ' P2 u7 d. v) A! w+ f- i
( s8 Z: ]& ~& V" q
ZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz
( U9 {$ Y' \% j8 C/ F* L5 v+ C2 jZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
8 [) P d5 l, K5 MZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz 2 x0 F$ ?9 ]$ Q% j, F
ZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip 9 H* r; C+ ~$ U' u! n0 P
% Y# u9 B |3 ]" B* t+ J3 Z" ] z8 u
优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里- |0 R8 m" G, j; l
的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句
7 ~ N, E. R3 [7 u! F9 n: 7 M( O" t5 q3 }: b, C% Y
9 j. Q; ^0 v4 @) k6 Q
zend_optimizer.optimization_level=15
) V- l0 h+ n2 g- G; Jzend_extension="/usr/local/lib/ZendOptimizer.so" - R9 Q; t) q# ], i8 m" i6 s
& A3 X# {' B9 I6 N就可以了。用phpinfo()看到Zend图标左边有下面文字: 9 j2 r+ U7 h0 O! P
7 G; @1 O$ ?1 g1 ?' F' Twith Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies
0 ?* S j4 D* B* m, `# m
1 ^* K6 X& T7 ]; Q- k' R那么,优化器已经挂接成功了。 ) ~7 e# t" O/ i+ W4 y# `0 K
& d. f9 b6 v* U) r1 a$ J- K
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设
0 G1 X3 R9 ?0 ]! k) D计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。
# d& d' w" a3 W4 H
# [! q4 G6 \$ ^' |2 ?7 Jphp脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进' D8 i* ~! h( f7 }4 s
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如! H9 P, M- o( \( |
mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。 6 j1 k- c, B$ y7 u
! `" w; H' Y. T, \
7 [1 ]/ y S' O: o' Z" S5、文件及目录的权限设置 ! z! Y" v$ I6 y# d$ m6 s. j
. q9 e4 N; r- W7 J4 @web目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,9 M4 z% y ^& G1 N1 ?
攻击者可以修改主页文件,所以web目录的权限一定要设置好。
8 H! O1 U3 Q$ X7 ?% F) S( {+ X8 |; E# w5 u! h: j0 g
还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属2 \+ d; L( q3 R: Q) _) L
主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的
% e/ c. f: {7 F" z$ e; f错误: ) |: d; o7 B, S- ]6 ?- P! m! C
! `" E7 H& a7 x1 l; w# l9 ^Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not 4 `0 q. Z% y" b( a( l* c0 ^" `$ T
allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php
, j5 c; g/ X* hon line 3
! }* b V W7 j. L- v6 J! W: W* ~* N
这样我们能防止许多系统文件被读,比如:/etc/passwd等。
! G: L3 @2 g) J9 R2 y1 {+ c- k0 t上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。 0 m1 s# s& \) R. k4 ?8 T3 s: l+ Q) u
' q# u E0 {( f N0 T) `# N/ K, c; q+ n# o' n8 x. v
6、mysql的启动权限设置 - ?1 I2 p8 p5 w: u! E
: N$ L! t/ x! N% J1 s. P
mysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等7 Y. O5 t/ L/ t, n5 z8 U9 `1 h/ X
系统启动脚本里加上一句: ! r/ }4 X3 n0 I& ~: Z
* |2 }7 m/ e3 V0 I7 N
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start"
+ b+ w1 q" ?+ b$ \' I2 B n' h' v% o6 @; t, v% {/ ?
这样系统重启后,也会自动用mysqladmin用户启动mysql进程。
2 b h& M2 Z) j4 s& S& H5 X* X" i0 ]
. l, @- K0 Y) f* I5 d
7、日志文件及上传目录的审核及
# }& s; X" ?" e% Q
1 \1 }+ A- p9 b% t查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且
3 B( E9 ?8 Z% B; |+ }/ `也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非# L" C# B- ]( K5 G3 N+ m
法的文件,比如执行脚本等。 0 q$ ~1 t# F6 R" H5 s* o
: L6 u$ \4 `" f
5 _+ E& j; Z- k6 \8、操作系统自身的补丁
- D7 ?9 S! ?+ [4 O! O) w% |5 A" V% V( Q8 c y5 \' D2 X" R Y
一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。
0 h# i0 u, T6 E/ s! t. \
5 [' g' Q- w$ R0 f3 C7 T i
j7 v" R" Q4 g2 d6 O" d0 i0 ~5 k, t经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,
$ S @1 x) F7 ]6 C7 D/ ?即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 6 T0 z" v6 a& B3 L: x8 _
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;)
- @# \ S/ c, E+ l( `; @
, @5 i0 }+ a. Q7 l7 m, y' }: _, I# S6 t
参考资料:
, ]/ b! ^& r. Z g3 m5 a0 N* ]& rPHP Manual 2 x4 n7 B+ ^2 H6 t
http://www.zend.com |
|