|
|
发布日期:2001-11-27
- @* k) C* s; g8 A5 d$ z+ ^文章内容:* M& \1 G+ F* \9 q( C' f" j
--------------------------------------------------------------------------------$ A2 J# D4 i4 `; u% x7 n
( G @' f6 W6 V ~7 y) D作者:san(小许) san@nsfocus.com
4 g8 ]! G) {5 X% Q( j$ w" |6 [# _+ k: d% V
--------------------------------------------------------------------------------7 C9 R2 L6 W* e7 Y; A* j
' ?, ~, s1 ~! r
前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以
! Z3 S; B# O' w, K. N及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配
, p k# D: G$ i/ E置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的
% U, M% x3 P# F过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的" h1 Q6 e y A
phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现, |, M+ U% ]+ ]0 t% G) I
在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题1 |; }( ~' _. r' G8 h2 M8 ?4 Y& P
了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。
0 r" U2 f \# ~& ^4 f; t1 K( l7 V% Q! A" U. ?
! i! I1 T( {1 v3 Q- R' C) f' j
1、编译的时候注意补上已知的漏洞
9 ^2 Y+ B/ a/ ~+ _) y, r0 y1 g$ c; P4 _7 n8 w
从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突
% `- \2 X( }% K- x7 X1 L2 |% `破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源( | ?$ w" Y1 J) ~1 V
码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件# ~3 \; U) J# K% H
的第152行,也就是下面这行:
3 |) F# Q' v) o$ q+ b
( q- Y: \! y) e1 F6 z" H7 Fif (extra_cmd != NULL) {
- s( J5 S% j$ J( h9 x: W) e0 O/ N: a7 N
后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php
9 r, J0 E( B" q那么我们就修补了这个漏洞。
' S$ v6 [7 R- i4 Q4 g* M' X
' F" g$ B! Y- J/ K5 ~. Q7 z1 h1 ]# X4 y- d' \9 B- ?2 R
2、修改php.ini配置文件
5 Q3 ]5 \; P1 Z: Z! z
1 I9 u$ Q/ ~+ H! O# |2 E" i+ S以php发行版的php.ini-dist为蓝本进行修改。 0 B. A I1 `4 v6 H5 a2 C. {
1 T* j; l9 I w; V1)Error handling and logging J$ f1 N! F* V# }' j
在Error handling and logging部分可以做一些设定。先找到:
8 G4 \. I+ p: G, `: adisplay_errors = On
# f" m) e- [0 _1 y3 V1 A, U
+ s( t( C* Q0 F% r) w+ V( n" ~0 w. |php缺省是打开错误信息显示的,我们把它改为:
$ W1 f; t+ Y) I, T$ H; J
" H1 u! E+ h5 Adisplay_errors = Off
& m5 c3 x3 |# P& \9 N5 g4 r9 r! F" z! N# K
关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻
1 ]( K% ^- S v8 }) F1 g3 `( X4 K击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造9 w1 J1 N1 h- M2 _% N
成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以
& I" }: W" k1 p6 k8 j) ^- N" A下: # P# s6 N- i/ d' y& |
# _8 q6 a/ Q) V7 Q. `log_errors = Off
. E3 A! ^- S! ~; N0 f# H G# `. O3 u f
改为: ; Z: s$ T5 d0 x! s3 c
log_errors = On 2 ^' J; a. K% w6 }+ L
, T% W( }2 x/ s8 O1 b: z
以及指定文件,找到下面这行:
+ L/ i+ z* C! R8 o, a, S8 m4 s& g8 Y/ t- Y( k( S- ~4 P
;error_log = filename
6 s/ j0 [, {5 v, r
& S9 k) O) @6 H去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log
- N: h% y& U7 y9 H/ B
. d1 Y/ w! f$ _. aerror_log = /usr/local/apache/logs/php_error.log
* h# f3 m! d! ~( z8 } L8 C Z1 H
% A% a# Z2 s. A V. g6 k" C1 Z这样所有的错误都会写到php_error.log文件里。
' U8 } j% u8 |- X9 e
. p- K5 W k6 T0 ^; F/ g2)Safe Mode 3 i8 o8 @- h$ e: g
6 @" i* c* a5 a6 \$ H% `; Uphp的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在+ M1 y6 ?8 ^ A/ J/ L9 z
Safe Mode部分找到:
) ], d- S7 Z, n: j2 M0 A: v+ D: O, c0 G" e) v
safe_mode = Off
4 r& [: Z# O; W7 L, ^0 I
/ x a7 j# s: B改为:
2 N" v. v1 n) m% E" V* a- k0 l( r% M5 s0 Q. T
safe_mode = On
- w8 | a1 O+ M" x& J* O; l+ K, o
这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它0 d) ?$ W( O) c# T* Q, ]1 I5 W
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行/ B& H R) a2 k0 i3 O
safe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下:
k% w0 j. ~0 j( B9 {" M6 _2 a/ K0 ^# L
safe_mode_exec_dir = D4 T: ?3 c9 V0 p& p
" A0 W2 \. S. v" F1 E
指定要执行的程序的路径,如: 1 a. }( j% F& v
4 K( T v2 T% o& Y5 a/ m
safe_mode_exec_dir = /usr/local/php/exec ; n9 q9 J# [0 j9 |
1 T E7 B1 U% x/ R# ?
然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行
+ B* o2 K4 R7 u. Z) ^该目录里的程序。
. e. L& S0 G, ~& s: Q/ y" ^& E1 M9 @3 U& J- G* \
关于安全模式下受限函数的详细信息请查看php主站的说明: % S* x, u7 X" A
http://www.php.net/manual/en/features.safe-mode.php 4 Y3 H- _" e1 O1 M' }) |2 x
7 H4 z7 a2 S2 O
3)disable_functions
; V7 M$ s* C a
& a+ j" a6 x W如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这
$ n( _ q: l9 E- M' Y3 j行: ; K" o- n1 O5 N0 S% h
. a3 Q8 _; x3 @% U% ~9 D
disable_functions =
9 j; Y4 T, z: V7 C8 t3 ~( |7 g1 ]: P @, K6 h! Y+ G2 }
在”=“后面加上要禁止的函数,多个函数用”,“隔开。
+ v! ~3 @0 r8 F# a6 W6 ?5 x
& b3 N0 ~* c' H) C- B$ L
6 ^& d8 d5 R8 ^# D5 {3 z$ W3、修改httpd.conf 1 Q/ V$ i, q3 v% y0 j0 h7 x
# Z6 b/ [( _; g7 x& i) |5 O如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作( n/ S/ P$ g. `( c; q* C* y
路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行:
2 d8 Q: l3 |. R \3 u
# z l7 o5 |4 y" i# O<Directory /usr/local/apache/htdocs>
( j- P- Q( _# k9 J: Z$ t- C4 {- fphp_admin_value open_basedir /usr/local/apache/htdocs " D4 p. E- g8 |/ l( p4 P
</Directory> ' w3 Z* S- _, e6 n
3 U& X) j A8 w" a% V ~这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打. C" t- m5 A2 a) s* b
开的话会提示这样的错误:
. L" r- W1 u% @, Z" i7 a% j3 [5 S; q* l/ A1 `0 L6 j- v) I
Warning: open_basedir restriction in effect. File is in wrong directory in
9 ^" [! U$ P6 a5 p9 g8 ~/ Z0 E/usr/local/apache/htdocs/open.php on line 4 # }, {# Z5 i. W$ b3 D
; k2 O5 c2 i, [
等等。 5 j) r% S2 a) F6 i; X f0 m
$ L# H% G5 V( g/ t. {
4 k' o6 X6 d8 H; b2 c# t2 L4、对php代码进行编译
, s' ` t9 v! R4 G- I+ u- l
+ y* u/ |! R* Z8 r( E; b3 dZend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和; z0 j M/ f$ }
ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就
. ?9 L3 L4 K% m8 {1 z- `可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统: l) B) Z/ O2 x- L6 p/ w" u
: - ^: j. a- R* |- p X9 q
; \3 T1 w2 U( u' I% X
ZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz 1 j1 m: p9 g ^" h
ZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
7 n# Y3 r0 W/ n0 ]1 o8 OZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz & X0 V2 ~1 i& b; c" }2 a1 d6 h% l* ^
ZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip # A: Q# E0 H) R9 S7 G' c) ?$ C
6 d7 e3 m. V. e0 a- O优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里
: G" `) r3 K& Z) z& r的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句9 C. x# Z, T% W8 R. h* A
:
% R4 ^! ? I6 b
7 D/ Q/ p6 v. L. x( U, f- _0 ?8 tzend_optimizer.optimization_level=15
0 U7 {1 ?/ e* zzend_extension="/usr/local/lib/ZendOptimizer.so" & d/ Z( x. v: f& p& v2 x
4 @& P% [" B0 {, x7 D# N7 T. `# M
就可以了。用phpinfo()看到Zend图标左边有下面文字: 4 z$ Y4 y2 u9 _& p, v
2 Q# \ i ]& N6 g! W# A
with Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies . `+ x0 c8 u* ?1 `
* X4 g6 x4 G, s5 w8 \( y那么,优化器已经挂接成功了。
: B7 a& o! n# {1 C" L: Q' o& }* e
0 {! F3 _$ Q; T3 y: w5 k9 J" U0 _# C- Q2 u但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设
. q5 r7 Y# N- u/ U- L计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。 * p* e* ~* c4 a; P' v8 w4 u; k
. y9 n% H1 ?) d' @6 j" xphp脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进. T& t3 N) ~5 {
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如
6 b8 Y5 A4 L/ a8 J7 Ymysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。
: H+ N& p9 J! m8 B0 r- |
+ m% V! W* C! S+ w# D" Y" H( q( P P3 |8 I# Q5 ?# N7 i
5、文件及目录的权限设置 8 X0 C+ i+ A! K' f
0 F( D( Q6 ^$ ^2 Gweb目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
& A3 x( \& Y& y4 I攻击者可以修改主页文件,所以web目录的权限一定要设置好。
+ t- t' z1 `2 @$ o" i9 ^9 t# G7 Y# A K2 z$ r% t" v
还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属+ T& ] F6 s. k. c
主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的
# s; B, V7 N, D$ b错误: 6 @( O/ c: ~% {$ b: Q2 n5 w3 a7 ^ \4 Y
]6 D- N( `+ B8 H& Q, X3 u
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not
5 }2 O% x6 J' Lallowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php 4 U2 k B4 m3 \0 |! Q
on line 3
, ]% k/ e* V% M9 U
% q Z& t+ u7 k# {( |; Y这样我们能防止许多系统文件被读,比如:/etc/passwd等。
7 `% f! [7 r2 g: G/ e上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。
8 @4 `& X3 v* L' E' X: N3 P- ], u! M
* k. Y. t% c* W a6、mysql的启动权限设置
$ J: G4 @( r* k+ T: D. b
# \( l7 S% ?+ Qmysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等
# q( n! K! a7 d3 R+ J9 _4 D系统启动脚本里加上一句:
2 [% I) Z A, q. I3 r4 t/ D( Q _/ e( c+ R! a: t6 w' r1 q
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start"
# _& F# v8 l9 z+ ^' u3 i* A" L$ F$ O2 w
这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 & M# u6 ]1 a% e& j3 i% Y
/ a. V5 D2 c, u
5 b1 R' T* X( s
7、日志文件及上传目录的审核及 0 C; w V9 s& `( N, Y% T
: B3 ?, t2 g; u' M& q+ b1 G% ?
查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且
( c h9 ^. C3 v/ v* E9 q也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非( @% [. D; d3 P# O+ s! G! L
法的文件,比如执行脚本等。
! h9 W) A7 e6 U% O h) u
8 X8 }8 O) s% P* ^. n: Q
+ I$ ^7 ]2 h: K! B! [+ W& y8、操作系统自身的补丁
5 j$ b& Y7 t/ A
% Y! V3 R2 E$ [2 q4 I一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。
' m" H/ e- F9 k- W" w3 Q8 l F; g0 \8 W9 f
; z, I9 D' j$ u6 L3 j9 F经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,6 q8 ?9 q! z2 F" Q" ~: e
即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 ) O6 w( v& n& y4 f' ^
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;) . P& y- ~8 P6 w3 J4 I- f
# o" o) {8 I6 L. A+ f' ]0 v5 X
( v! Z6 v( d; z1 e参考资料: , J! t! m$ @" U- {& z3 L9 X
PHP Manual $ O: a! {$ m7 j$ @6 \! m
http://www.zend.com |
|