|
|
发布日期:2001-11-27
8 Y$ T. v9 w4 B. Y% [8 P文章内容:
& S& l3 H% x% j# b" p+ `0 a: d--------------------------------------------------------------------------------% Z _( d" q' z$ C7 K v: I) U( S
5 E% F& t' [) y5 A作者:san(小许) san@nsfocus.com 6 I* u0 m+ d2 [+ K" ]* T: C2 v
3 Z$ R% T7 Z1 V2 y# ~
--------------------------------------------------------------------------------
- G6 S! x3 R7 K$ e7 x& U
5 v' C) {. l8 k* C; d' _- j前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以
5 Y9 i2 n( S; Z及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配
/ [) W3 b5 T: o- E2 c; m0 I. t置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的# @) i! ]3 _ S! U4 L$ \
过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的. W2 o* J) D" s% L: L* F2 ~/ z }
phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现
4 Q3 V' }0 n! ^/ e9 @在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题
3 F5 D' S$ R0 Y4 m. `了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。
: d. r' ~8 p0 {$ U) n, m$ I
8 K/ _6 [$ F* O9 Y8 c% t$ |" B( N7 N7 u6 b% T# I
1、编译的时候注意补上已知的漏洞 5 M0 ?% R9 W: H; L
2 A2 S; s- P5 \, D3 c" V: X% \
从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突
: v' X3 h$ ~- \破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源
+ s) o% b( T( z) U1 X! j" I2 e* _码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件
" k3 U% c( q- d m0 t' @" \的第152行,也就是下面这行: 6 r% F9 N# o1 z& o
2 R$ i, [! y7 cif (extra_cmd != NULL) { , h0 ^" I) y* M
, [; H/ a" e+ V- C
后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php + u/ s( {) y o8 d1 H
那么我们就修补了这个漏洞。
1 I' P& o( [" s. ^9 D; W( Q& c- J# l, T' @. K( c+ S3 b2 J
* r$ |$ G. L+ T+ S3 \
2、修改php.ini配置文件
6 Z. ]7 n- Q2 [) E
( E! U9 b1 h1 T- @以php发行版的php.ini-dist为蓝本进行修改。
; h0 f7 m2 J/ O, _! n) x, w3 Y+ E( q0 m. t t9 }
1)Error handling and logging / a' K0 o% x6 v, _- @- l5 Q
在Error handling and logging部分可以做一些设定。先找到: * R+ N( f3 B% L: K7 n& N Z
display_errors = On
8 H0 l# t8 X! E; o* \ ?/ s; t& P8 x# ?0 L) l% T5 y
php缺省是打开错误信息显示的,我们把它改为:
$ Z7 J5 U- n' M- V; _$ W; r* L8 r1 s% y( L8 J$ m7 n% H1 Z* f
display_errors = Off
$ o5 d/ d( D* h) H, C& N
# H& v$ L: x( x0 a1 A关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻
" z7 s" Y9 Z, v9 @, P击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造
# ?7 W' K" D0 ~6 _) ~, g+ g成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以
5 l6 W V! `3 z4 j+ @/ s% ^/ [下: 7 M/ Q' Y, G5 U+ ~; d7 q
8 e8 ?- i1 Y6 }, h plog_errors = Off & f+ t: N+ D4 Z% ?7 C/ C) g# u* G
' Z8 Z, k! g5 y! c3 e- A
改为:
) w) \3 O% B/ U6 u0 L6 Z$ zlog_errors = On 7 P% X# f. ?5 e* Z5 L9 }- ~
& y0 n" ]' X% f8 s以及指定文件,找到下面这行: }& u+ o$ a+ r8 e s t
5 i7 ]* P! E) q4 V* T4 }0 r1 i
;error_log = filename * O- y0 G' H- \6 g/ i. v6 H2 q4 g0 S
6 t, l' V3 p7 u3 x" {
去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log
0 T) c, a" B H; B% n Z
& d: ^( u, w; l; Ferror_log = /usr/local/apache/logs/php_error.log 4 T- g% h0 E7 @0 Y3 g+ b( L
7 i# h: q3 a+ b- ^# H这样所有的错误都会写到php_error.log文件里。
$ I* b( Y+ P' F# J; A1 i. l! c* O, j9 p
2)Safe Mode
. [5 m: ~( c* U2 b1 J" ^
! p! a" S; i; n# t0 A8 z$ Aphp的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在
% F7 T' Y. o# p+ USafe Mode部分找到:
/ W! L) c+ [0 Z1 ]! c* n
9 \6 X' o, T" A1 G& I0 h( o$ bsafe_mode = Off 4 K' f) u+ I8 h% G6 T, e
% a) a: t* q G& `; m' e
改为:
/ v3 C6 n; c8 Z
9 h& Y$ }: k9 D4 [ A5 R4 d" dsafe_mode = On
% v8 S3 M9 y4 _2 v% ~- T; T/ ^, x( R
: m: h; @, L: q" I7 W1 K' ^# ]( e6 E这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它5 V1 {( b" u5 C' |; |( a
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行1 d/ V- Q n1 D% e6 D7 \; k; s5 k
safe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下: L" B) M ^1 H' Q
: p& K/ A! C; ` y- H# y. e" S _safe_mode_exec_dir = - o' O+ I; j4 }: m! F/ o' e/ `$ ?$ N
: ^" a0 {/ E4 K- F) X1 z8 B
指定要执行的程序的路径,如:
" ]& ~2 p7 W2 R8 z+ Z: O, R2 Q& `2 c6 {! j: t6 O
safe_mode_exec_dir = /usr/local/php/exec
( |5 b6 a; W6 R" Q( ]' ?& I; R$ {1 _
9 T- X$ J8 Q1 O然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行; D: }( R9 d# q
该目录里的程序。
. t& V/ w, V' [/ C$ W% _0 p( h
. ?1 [$ w6 m1 f* t9 J关于安全模式下受限函数的详细信息请查看php主站的说明:
M3 @8 t$ s+ j' ` v" L6 ehttp://www.php.net/manual/en/features.safe-mode.php + ~# B2 k+ [2 m& L/ V1 A D
& T- ?8 Q: D& W- `# ?1 s: d* q- s: l3)disable_functions
C" L8 w5 P# _+ f: e
: b% n! E' V H如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这
1 _! E# U- J3 H. C7 r* H* v9 h {& Y行: 5 ?7 y+ Z8 s1 g# L2 g/ e( r& S
& V: u5 Q/ `, V& ~, c; }
disable_functions =
; t4 C( i8 ^- N' w& a2 C- w' S$ s" L0 p* H0 T. i: q6 H! u
在”=“后面加上要禁止的函数,多个函数用”,“隔开。
/ Q# h( o" n/ h' b( Z5 t- }; k* ~" @# S9 P. V
9 w3 I3 C4 b' y8 o$ {+ g. |$ K
3、修改httpd.conf i, f, F) N& N; L
- Z5 f; c, ~ ^
如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作1 e; [% b4 p. E! J8 q+ m& h$ Q1 }
路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行:
5 q9 V2 a" m" t9 a# ~2 u; _# L& X4 S8 G
<Directory /usr/local/apache/htdocs> / S- ^- w2 M$ T- O: q+ T8 f
php_admin_value open_basedir /usr/local/apache/htdocs ' x. `, s |" s+ i
</Directory>
% B; t# O8 ^' \2 U+ r
; a2 x- M5 S8 Q$ Z) \! `这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打
5 x3 \+ D6 Q; R开的话会提示这样的错误:
+ F) \! c R6 ], w/ p- m; `' Z
6 O) T3 \2 m& E0 q" S( e- A, XWarning: open_basedir restriction in effect. File is in wrong directory in
- X1 |7 ]% v* a% d1 Q5 p& Z7 H/usr/local/apache/htdocs/open.php on line 4 . C7 y4 F3 V* S6 k9 A6 N; N
( u+ O- N7 f% _等等。
. o5 I: h' f5 v+ j: z( s1 x, e
, C4 V# Y- [3 h. t& y3 T; H3 O( H y: o
4、对php代码进行编译 * C1 H% ]8 t4 ~9 w3 l5 x
7 l% x0 A1 T& y2 q# [) W1 w
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和7 J6 T* ` s7 r. Z! @- F/ o
ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就
1 {4 N. \) b- K1 t. I可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统
# r+ Y" U* T. ~ `* G r: p:
9 m. n: e$ x$ V! y( v6 p2 M( }" `( Q a* x- a Q0 b
ZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz y! G! ^) U( ?, F8 P
ZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
' k$ ^3 [* U9 J9 x) P% M+ T9 QZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz
0 v$ o$ l& @/ T1 }ZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip ) f8 e; w9 T# C0 g! R0 k) C3 U
1 n7 Y; `* ]4 O* J& R& ]" L* b优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里; p- h& t V& ^0 h9 M" x& m
的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句
! a- [6 ]6 S, C3 N" b9 e: / R' T9 B& V+ |9 e
$ ~: L- C4 R! G/ Azend_optimizer.optimization_level=15 8 W' J) T) C: L$ s: r
zend_extension="/usr/local/lib/ZendOptimizer.so"
- O+ ?6 F0 v t" C- m8 b# p0 w: P7 K. J( Z
就可以了。用phpinfo()看到Zend图标左边有下面文字: 5 k1 h6 G& E7 ^& J [; ~
: e3 ^$ z! P1 t I1 n
with Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies ' m: r+ ]9 K( F5 D+ d
3 M! ?1 e, B$ Q那么,优化器已经挂接成功了。
( ^" y+ C0 S8 a$ x
/ t; {3 `# [- ^* m但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设& o% {, f" F! v X0 ^$ m6 e, r
计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。 0 R( v) X; R% l7 \% Q! ~& t
7 Y# J( G2 r% j$ x4 ~7 u8 @
php脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进1 G9 `7 P( M; P& Z7 z
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如
8 k3 Z1 ] v3 ?1 |9 u) k5 Dmysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。 + U5 G9 U( B! }( n; D8 H+ d
/ @7 w" ^, d& q7 r4 C; s
3 z r+ b; w( m5 N; R1 }( P5、文件及目录的权限设置
R- B; q0 Z: {
7 d" ]2 S, J) b( Jweb目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
+ `4 ^. G1 ^* C+ v4 K攻击者可以修改主页文件,所以web目录的权限一定要设置好。
( @6 a& A" F: J) A1 {/ i2 h
' P6 T, B3 C V( y还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属
6 Q+ ]9 U4 z$ U) {主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的
$ `/ V# C; S. E& u# Z错误:
" p; G9 [) i& H1 O- t9 m' g7 ~
6 p' K6 M. ~4 _7 I6 j; XWarning: SAFE MODE Restriction in effect. The script whose uid is 500 is not 1 r) f+ B5 {; k$ s
allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php ) i" q8 I4 ?2 G W4 f( F
on line 3 o% @1 Z6 n- B H1 t1 D l
- H8 R) G1 O4 Z1 U& G- T( j1 O这样我们能防止许多系统文件被读,比如:/etc/passwd等。
$ ]# b8 Y- ]! v: n/ B上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。
2 o' v$ f4 h' o& p( T
. K) n+ [% g5 c z8 L# ?, H' ]& o7 c! ]% @; [6 d% b
6、mysql的启动权限设置 ) ?) j' r& A! q6 v! m& A! l8 p
* j7 {$ z# A4 I& O+ X; |
mysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等
5 I, d) s2 G0 H系统启动脚本里加上一句: 8 \- x' ]% ^2 P) J8 L6 B, I
$ C. I! Y b; A2 D! M1 Xsu mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start" % m% M) K2 B/ N8 x1 O2 L
* W. q! Z: G( V+ z1 x这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 4 C1 e0 ]7 ^# S4 j, H: ]
: H* u8 ]7 I2 Z& Z: |* O
6 a% ]2 l# N. J3 o/ h$ s- m; W7、日志文件及上传目录的审核及
0 C4 b7 l' @2 c9 } P+ d# ]4 u; {) K S4 c5 y; E4 J1 p. i, Q
查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且
) v7 |5 V9 @8 Z F5 ?也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非
2 h* a' b" H3 H$ y法的文件,比如执行脚本等。 : z: ]# u/ I7 t. }$ l7 @3 j
$ [8 [5 K$ _, J$ P9 @8 x
2 M4 M5 x, c+ L( f8、操作系统自身的补丁 : I! B: V; l7 G- y
1 s+ W3 ^ q2 Z1 G一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。
2 F1 h) p. ^- }6 ?) P# ^. F$ b
% V! [7 u6 B1 @- @0 ^% B
" u: p4 Z1 B+ ?; W2 m经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,6 U9 O9 \# Z) E, w6 c: z6 ]
即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 * m1 N3 e7 e) L' B* k
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;)
7 \. x3 ]- i% X0 }! Q
q0 u5 S" | u c/ _2 U e/ \- V0 a# w+ E; S/ @3 c- A% s' G; B% i
参考资料: . G5 o3 `# [& D' i
PHP Manual
% v8 C$ N, l, W0 n5 g" ehttp://www.zend.com |
|