|
|
发布日期:2001-11-27" M- m: b& f$ c2 V* L' ?$ h
文章内容:
0 r- l7 x0 o/ r2 i+ h: r--------------------------------------------------------------------------------2 q$ F4 k) W& O4 S9 E! W0 V
; r$ o9 C7 d# M
作者:san(小许) san@nsfocus.com
: t. [5 c5 S7 K- `; i
$ |( i, Y9 { n# j1 F--------------------------------------------------------------------------------0 s0 F0 ^, m; f5 j9 z: ]$ s& }( }4 n
* o$ \ L$ F% M4 u& y9 F/ c前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以
1 k3 T+ J; ^8 q及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配& k! l! _) y3 v/ p H
置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的3 D4 y. v8 y3 ]* y' J# p5 C6 ]1 g
过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的
/ C7 X2 y' ^1 [phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现
! t w! K% z, t. G1 c# p在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题
5 A3 e B: S1 n% | g/ c$ h& @了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。 4 ~. G3 J1 L# H# \4 B V
; [) x4 s C/ f7 K* }9 I' `) Z6 Y2 P: i4 b9 l! [5 \
1、编译的时候注意补上已知的漏洞
" D3 s' `4 b5 Q/ w- e- A9 x0 s4 L' s
从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突 U( N E5 P- Z- [4 h, l) F
破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源7 |7 Q' d% X8 e- J
码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件
, r; Z4 I" D$ n3 V- c5 q的第152行,也就是下面这行: 5 J! L; y4 ` E1 `" `
/ _6 ?) }9 Y/ Q2 G5 ?* ?6 r2 [
if (extra_cmd != NULL) { 0 x3 w0 |: \& n
7 X" C% n, U4 R: z- a/ }
后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php 6 z) ?3 p+ |/ d: V- T. E& I; S
那么我们就修补了这个漏洞。
: U6 g. ~/ e3 u; o: T
1 X; f! l. f9 ^) g8 a2 X. j5 b/ L! u2 ]) w- Y. S
2、修改php.ini配置文件
' g) b7 ^- y2 @( k2 t7 ]8 t$ V# t
以php发行版的php.ini-dist为蓝本进行修改。 7 N" @* r' V! n6 N* i5 L
. d2 R& o$ e6 S. \3 P) ]1)Error handling and logging
& E' l3 d" d- y/ z7 ]2 X在Error handling and logging部分可以做一些设定。先找到:
& I& A3 h, Q3 A' ]7 f6 Cdisplay_errors = On
! g! b% q' Y- k$ C' i( P/ N7 x6 q' N- M6 F
php缺省是打开错误信息显示的,我们把它改为: $ w) `. \6 b% i' z* B
+ T3 V( ]2 H& Y: d; k1 q4 _
display_errors = Off 0 i; F4 q; A8 m1 v" n! Z
* S. C2 ~: |: z0 y) I. i关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻 ^# d A7 [) ?3 r9 _
击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造
3 ]. o+ d3 P- g1 h成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以
4 I8 g2 ^% i2 F/ [* s7 G下:
. G, j: J2 a; x' C b0 ] ?8 P. Y; V4 K- X/ k$ S: |0 K
log_errors = Off
9 @$ _" Q8 e6 D# w" D
+ h2 }7 @9 g/ E* V改为:
% w2 t3 S, `1 e0 T7 z, Mlog_errors = On
5 U+ H0 p1 i* z* |; n5 y- N+ r6 M+ \1 U9 X; m2 I5 E
以及指定文件,找到下面这行:
% j5 D* e k& T5 A0 }8 u* C7 S* o$ F
! m9 k2 o; {( @; a9 k2 t/ c" s;error_log = filename
! d' i& B5 b, i2 P( v. _7 r
9 y. W2 m0 h5 p$ C去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log
- d7 j+ |, p: W i/ z, x% V" ^# k) ^* e5 I3 d& H
error_log = /usr/local/apache/logs/php_error.log - V' U$ a: d7 K% d
! @+ I; [/ @. p. {0 l) n) W+ F, y这样所有的错误都会写到php_error.log文件里。 7 S& y/ H. k* E5 b- Z9 V: b9 D5 g) K
6 [* G) C3 j6 Z( u4 P' s3 J2)Safe Mode
7 ?$ A1 Q* s* U9 |8 R
/ O$ h) R- W' ~php的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在
. }( c |5 n( H& J/ Z) a4 m$ _Safe Mode部分找到: ) H6 `! G7 X N# L% a, q
0 I/ k0 q; Z$ r) Ysafe_mode = Off
s1 g3 k* G) v, {7 T( ^# W
# K1 V3 Z1 {6 [3 l& E- O改为: ) v1 W$ n3 m3 c% t+ F, z
8 ^8 p G w5 H. J7 k0 _
safe_mode = On
1 o) Q0 z! W& k( S; i; e. |) D0 c9 A: m" t9 w0 q
这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它% L7 y( }+ n, ^
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行
6 m# |8 O; Z7 ssafe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下:
% w3 ?( ?4 Z- p8 E5 {/ K& [$ [1 H. H+ d# A. r
safe_mode_exec_dir = & X: S* S" D w* H# e M1 C
" d) {) f0 s' M
指定要执行的程序的路径,如: * X* c3 `7 b% @3 [, A
1 e2 j9 O" k# o
safe_mode_exec_dir = /usr/local/php/exec
2 j" u8 q; e: a0 m' A
2 A6 G8 H: \" X然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行( D% w+ r% V6 A: ]1 W
该目录里的程序。
2 C% C' s# j) F5 O* b
9 N1 k/ |! Y% H5 t% [; U关于安全模式下受限函数的详细信息请查看php主站的说明:
2 E: ^3 _* u5 _ Z1 Shttp://www.php.net/manual/en/features.safe-mode.php
4 A, k3 G% E: k. a, F7 i- U
5 G5 {( s) P6 V% k+ m) a3)disable_functions
/ G' Q& t) F; k' l. @/ f0 ^
+ }* Q" |- U9 X8 F6 {5 u9 T+ |如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这9 p1 t# `6 U& u1 U
行: : y2 s$ ~! _0 d% E$ O# S
" t2 j4 ]* f4 O+ Q5 xdisable_functions = 4 D) c5 w U0 y; [- s5 f
0 U7 t9 J! M+ S9 D' G在”=“后面加上要禁止的函数,多个函数用”,“隔开。
- M% [- _7 l: u8 i2 n' u1 F( E% H( n/ `/ t3 o% ?; l2 e
: `; }& Y }% \# ~
3、修改httpd.conf & c, o$ K1 w5 A C4 n# Z7 h. S
) ?9 q6 k# D1 u& b- L如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作4 }0 a7 _; e$ n
路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行: 0 n, g, b/ I& R: k" k# `
+ `# T1 Z2 F5 F3 S4 Q; W' u2 J4 V
<Directory /usr/local/apache/htdocs> ! w- d* H9 b% _8 V m
php_admin_value open_basedir /usr/local/apache/htdocs $ e$ o3 J2 T3 g1 a2 P3 k
</Directory> ! f+ ^7 E) E7 M; q- J& o
5 f8 P( A. J+ x# D4 L7 S! B这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打- Y L* N& A; z. g+ G# ]. m
开的话会提示这样的错误:
( y8 s% i3 P8 N
, X! {% o) b" |% J0 IWarning: open_basedir restriction in effect. File is in wrong directory in
1 a1 ^( `% F/ m0 R) L/usr/local/apache/htdocs/open.php on line 4 + i! w+ i2 P9 D( h( W) K8 l
$ C' o5 [0 v! o R$ I9 A& l
等等。 D% X/ P( l4 E( V
% s' [8 }$ t* R9 b
1 B3 k8 Z4 H% n, t1 {" G4、对php代码进行编译 7 g7 z. L1 _' ~! }
. y, h& q) G: P% `1 L" P7 T
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和2 U; t) }: Z' Z; q3 l- b
ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就2 Q# k; R6 |8 U, i4 [
可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统% X3 m: w8 Z& m- a" E4 c
: 6 z$ m4 O& Q, s' d0 \+ P
7 E6 d$ h, o' J) S S& DZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz , e" S9 r5 `4 `" u
ZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
( |0 N; i. }3 EZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz
# l Z5 H% k' ^1 s' WZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip
$ {: q9 i5 j/ f F! ^/ B4 _- [5 V
% }( S, R. x/ x* ]优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里
' D0 x% A4 ~' B$ C& K) ~, e6 t& q的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句( n0 L( b) w+ t! O8 C/ L/ |4 [
:
/ B. R- F; g( P4 ]& o8 e' n; q6 E( P
zend_optimizer.optimization_level=15
# ?; t8 `' T" G" f2 Ozend_extension="/usr/local/lib/ZendOptimizer.so" 8 A2 @- W, C7 l
' V5 E- l& j0 D9 z- b" G就可以了。用phpinfo()看到Zend图标左边有下面文字: * K: m( r' F8 s7 V. s
3 a* ~0 [2 {/ u3 ?/ x, w: G
with Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies / A# t8 {1 u( J6 j4 L) ~
* }! Q; D1 i. i" b% q7 u那么,优化器已经挂接成功了。 5 l2 T& y& ^( G% H) L1 c6 X. u4 ~& a
/ V0 p4 J6 ?; W8 v" X
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设
& t# h0 T$ \, d* i+ o计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。 - P1 V. A% t6 U, g$ q1 o/ i
. y: [* E6 A% G3 {" e2 hphp脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进) X, |9 }! e8 p5 B4 w
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如 _7 p: m5 ?9 O& h+ g
mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。
. |0 T$ ?' n$ R" z# c# d0 y R+ m: N# r0 o! ^8 M# X$ {
; R @/ R) h8 t2 y7 I3 u( o5、文件及目录的权限设置 2 _+ L$ G' E: H
" r& P" X( F$ y* ?# d" |web目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,8 N) w/ R3 Z( L1 s
攻击者可以修改主页文件,所以web目录的权限一定要设置好。 ; s1 ]# I& v# J6 X( Q5 B& l6 D/ f9 I
+ y8 ?; L4 n3 v% e4 o
还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属3 n1 i4 l0 \( b& z4 @$ o' D3 s
主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的9 P% p2 O: i# n* g& ~: x
错误: . ]8 y6 \* q( E6 }
* Y6 V/ c$ I# A0 H3 d
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not # C4 d1 W& f9 ^1 E+ S0 A* f
allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php % {8 F& u9 u C' v* {
on line 3 - P& C4 v( u t9 [' q5 p# B7 ~
; E4 \: g0 @$ p这样我们能防止许多系统文件被读,比如:/etc/passwd等。
n. @' p" M/ s' i, t, ~+ h1 Q上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。 % W' M$ p1 W& I8 [
3 Q w8 v; Y/ N1 @
7 j" f1 v; r$ M% d- X4 a9 ]6、mysql的启动权限设置 - U: W& a0 D. K3 p9 n- s
% n% N& n) B5 C5 U( [8 Kmysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等
! i) U; U, U o1 m5 ]$ H系统启动脚本里加上一句: 4 `& T+ N- p4 V* n8 H7 r( V+ i
% x) e& s: m. X# e' a
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start" ) K0 L2 n3 V4 G0 }: W
) ?7 b1 k& d3 \) }8 \
这样系统重启后,也会自动用mysqladmin用户启动mysql进程。
8 l _3 l; I }/ p" i' h( ^5 G# `9 p
5 r* \$ y- K+ Z% D2 Z# r1 d
7、日志文件及上传目录的审核及
: i) Z( ?& `$ X3 v$ K% b7 U9 K- J( c- I# P+ d
查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且& h, e, z! Q/ B5 r3 n* A0 q! e
也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非
5 y2 _8 m a2 c- T4 ~# j" J法的文件,比如执行脚本等。
( r6 H# F; v$ m1 [' V: M# U; b
5 j( D7 p" {. \9 e4 a- [ @ T8 u5 M& C9 O5 P* \! J
8、操作系统自身的补丁 9 v$ F! w/ [0 J& j% l# K2 H4 Y
$ V, j" i5 [8 l& n) Q0 Q一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。 3 H2 W. ?4 m/ \
! }) w* Y! i% `7 F5 B4 K7 H) J4 ]) ?7 l* Q q
经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,
0 W) r4 X8 f' o% ^即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 : [# v$ h; D* ^0 H0 H# g$ A; j
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;) 4 \( h; y {( `0 L2 i- j6 j
6 S$ i5 Q: k' n0 A# ~2 ^1 N o3 _% y( b0 ~( | a
参考资料: b% k7 X/ G, b3 q4 F: s
PHP Manual
5 {8 X" H; L9 Z- K, f3 [% Z: L6 Dhttp://www.zend.com |
|