|
发布日期:2001-11-27
. J' `- {. y. X2 d# C5 C文章内容:
0 o1 j( U% c1 W--------------------------------------------------------------------------------
1 U1 k+ k& M$ G) t7 F$ B9 y7 s/ \( N' V6 v: M0 v$ M3 \
作者:san(小许) san@nsfocus.com
/ _5 ?5 H: c4 c" c8 ^+ s# A/ [! s* Z/ C a( Y% S0 l
--------------------------------------------------------------------------------, O. |4 t; ^" t
3 h2 H- K5 Z( ~4 E+ c, R) ~1 d前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以: G' k2 a5 y- R: [2 B
及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配: l* j& O5 a1 C
置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的
% ]. d ^- f" j4 Z7 D3 s$ y% @8 a6 C过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的9 a$ s" P) s- ]( R/ H" s
phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现( b- E6 R* Y3 H" L1 n0 l1 @+ g
在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题
2 b* k: ^: p" f7 q t9 D了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。 4 a+ B$ u+ L) P) V5 J7 l
5 m# z! y* ^! y8 C
( t# L* G+ f4 k/ M1、编译的时候注意补上已知的漏洞
3 F) J( X7 v+ R7 t3 k' Q; C4 N: h4 }
从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突1 m: d9 Z0 m( U- r! ?7 S, O% S
破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源- P/ O$ p; ~$ ^# s0 [' \- `& h
码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件( A5 c0 x7 |2 }* j! i
的第152行,也就是下面这行: ; c0 i8 P, q, Z1 o
- d* E0 o# v) M$ E3 Z) Sif (extra_cmd != NULL) {
9 f5 J, M, o& M* B& L& d) q, E; k- O7 a2 ^, v6 c5 c+ }0 E
后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php
4 ]. z5 T. Y( @那么我们就修补了这个漏洞。
: c, Y( q# e' T# f8 V6 I% D* M! s8 K" e* r7 ?0 }. Q
/ [: Q. \ X' x8 _4 A
2、修改php.ini配置文件 0 { P8 ?/ c' Y& t& F4 @
& l! z8 e* Z# X以php发行版的php.ini-dist为蓝本进行修改。 * P$ A7 Z' V0 i/ F, k
( w6 p7 j0 V4 h9 { a, u9 r4 X f& ]
1)Error handling and logging ) t. N# [8 B4 i6 ?! ~
在Error handling and logging部分可以做一些设定。先找到: 8 `" G0 P! o; _) |& `4 N% B4 Z
display_errors = On
! F6 W* V3 ]( ^( s( Q5 f) p$ d: n" R1 c& ~0 ^! n: K0 ]
php缺省是打开错误信息显示的,我们把它改为:
- N* g0 S5 d- w$ O# x$ F
+ ?6 ^, K6 r: I& mdisplay_errors = Off
* [6 d- ?& a* ]5 W6 Z' j( I1 Y. G+ [; |; R9 ^
关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻& t5 a6 K* u! A! A
击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造
' g; a* j, H+ s* v: p成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以: V9 d7 v0 o- }# i- }
下: : R6 _3 q# ~% C5 o: [' n9 y
8 `4 |% e/ T; `2 j) u( Mlog_errors = Off
5 e f' ?/ L# }7 g8 ^) e" J; v4 c( R* @7 _9 x2 P$ F5 A0 L
改为:
0 v6 e$ |1 P2 R3 plog_errors = On
8 j: G3 w9 T- t* {3 L" s2 n7 K2 m$ J" q2 g: q9 T# M% C
以及指定文件,找到下面这行:
+ b! z. A# f4 _- |0 ~3 d; i$ T+ N1 Y1 z$ P7 }+ N' g. Z
;error_log = filename
3 R3 ]- e% r6 ?2 q9 x# y m9 @
1 [+ c* [: I" J, R" z去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log ( `2 Z( }( X6 m9 F8 y5 b( m0 y
9 |% Y" M0 b6 @' C' C& perror_log = /usr/local/apache/logs/php_error.log . X9 s4 g7 b7 Y. w% \
6 y" t$ E4 b7 m9 G6 G, g
这样所有的错误都会写到php_error.log文件里。 0 k4 [$ h6 V" Z) N R- ~0 w5 I
. N, m% U# P0 {# L, R$ P; p7 D! N
2)Safe Mode
( Z5 T" O& a6 q$ {7 K& h* Y x$ D& b: v1 ]
php的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在
' d5 j2 S* Y% ~9 k: y, }' NSafe Mode部分找到: , G. A: W4 ?/ G. A* X! Z h3 D
8 J" ` I# L! [- d$ ]3 r
safe_mode = Off
7 Z. T7 D8 L* ?+ X
, [$ L' t9 H9 p2 h6 J/ l% ~: @改为: 7 D) w; E7 J3 A5 K0 ]7 K" H) j
; e" j6 C' }0 N' H7 \safe_mode = On ; c; H/ v0 f$ }& Y
, e1 j9 R& Z2 T C( ~3 ~* g+ @' H- A
这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它! H* p! M5 R1 Z! Z) ]1 R) B$ y0 C
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行 v$ y( X5 m& h* c0 W- G1 ?
safe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下: 1 r4 a. T) A+ S) j) ^/ B3 c
2 E2 h+ Y5 G L9 y
safe_mode_exec_dir = ; b A# b- x$ K
1 E6 i h4 H1 m9 t0 S( h3 B/ [; |' a- ^
指定要执行的程序的路径,如:
3 E ?# S4 I0 t e+ ]7 v8 T3 v+ k) b4 U7 t
safe_mode_exec_dir = /usr/local/php/exec + Y, d. B* g& {5 S. C
4 A% a9 L- ?6 I9 m* N5 q' S+ z然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行
w$ F5 P, q0 w R/ l该目录里的程序。 . y; |8 J- Y- j; T( y8 P
- D; c7 Q9 S0 m
关于安全模式下受限函数的详细信息请查看php主站的说明: 5 C/ b3 o! O8 u: G4 Z( e8 J. D9 n
http://www.php.net/manual/en/features.safe-mode.php ! N, W) J$ B" }) Z9 @! U
+ m( X. w$ ?8 p! a
3)disable_functions 5 F& k5 {, `1 I' E* N2 F
" d) j! Y5 K+ [# Z- S
如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这, v; y7 `3 l) Z
行:
1 [+ }3 q- ~; d6 F8 A# {- [$ q$ }0 V0 K$ _, s4 V, d6 _
disable_functions = 2 f! i: D( o9 y, @8 r8 f
/ o( q9 T4 R9 T$ O9 G! G
在”=“后面加上要禁止的函数,多个函数用”,“隔开。
+ l, [: s% X8 f' S
; `; `: u, z: g, F0 ^- N+ D9 P! v
+ d8 U6 j( V! Y( j/ a8 ?3、修改httpd.conf
; b3 ]" K; P1 @: O7 x5 L: T4 c" l9 Q9 M$ E1 w9 v
如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作
- C0 O" U( D9 R9 K- O8 t6 l1 `路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行:
' I' L/ J9 H, M! F7 Z X
6 n* Q; {/ [7 b<Directory /usr/local/apache/htdocs> 1 Q' O2 S# q0 R* f+ F+ }0 l3 K5 I
php_admin_value open_basedir /usr/local/apache/htdocs
' n- a( x. F% N k3 n r</Directory>
0 v' W; G1 J, t6 i/ ^# [. _& [# T+ G0 t" g8 Q1 G
这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打
/ M' r* J: v" l% `1 Z! Q开的话会提示这样的错误:
; m3 i) s- f7 w# I' ^: P
& j* x. R# S3 j) t2 z X6 RWarning: open_basedir restriction in effect. File is in wrong directory in * z' @" G8 F: z
/usr/local/apache/htdocs/open.php on line 4
3 \& Q3 Z0 Z& C1 [! ~4 z" i1 l8 K( D0 ^
7 D, F, `+ n# G/ v* m' J等等。
* E1 P9 L M, n9 `5 |
. l( ]5 o5 O6 P; z: B7 g D! e/ |9 j6 i$ c& i; J
4、对php代码进行编译 % D( ?& b! H [- t- @1 H
% M1 T2 J- F' u( [4 M, `- H
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和
3 ~( d; E. k$ V% R8 `1 {" O3 TZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就
4 t" V) d8 _; N% i" o% h可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统$ q& Z! w i1 U
:
) q2 _- c9 S! t1 e2 b$ G
5 J: c2 F0 C* c/ ?ZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz 5 p4 x8 f5 l3 f# ]
ZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz & g6 c1 f2 X1 A0 k6 n
ZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz 2 ]* o2 K; t: v+ Q% v' y) c- V
ZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip % f# Z4 y3 J" L) M3 h! |& b. `
! o) C5 e5 d, ?优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里
& @' x `, h' ^; [7 [4 ]/ H0 t1 c的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句 e2 \( Q* C$ U& _3 P n: @5 j
: 9 Z& n5 S4 X5 h: Y1 D
" z" b: p5 u: q* F* f$ kzend_optimizer.optimization_level=15 * K! I3 G `- K1 u) X% `& y
zend_extension="/usr/local/lib/ZendOptimizer.so" 5 n# I% t0 L5 \, E5 J
9 x g) d& D8 q/ \
就可以了。用phpinfo()看到Zend图标左边有下面文字:
- V) U, ? g' Q( O! f7 L* {& v# G/ s: O, ^5 C7 E* T; Q
with Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies
( e( |2 K+ `' C2 `6 d
9 A# z& R5 y/ w5 ~% U/ b那么,优化器已经挂接成功了。 + R. @2 G/ G9 q( T! F8 ]
: r2 ]/ E$ n; r9 s3 y" W' ^但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设9 O. e: z* F: ?: ?! A; b! w
计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。 ' U9 [$ [8 d* u3 q5 O% a; E$ O
' u9 u# j) e: iphp脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进9 `7 E4 U6 N$ ]4 {
一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如: [( F0 s; b7 p4 R( j3 V
mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。
% Y! i4 z1 n' `) H$ I
& F, D( c( P' j1 S; I7 ]/ B( u7 b& a* Z2 P- X
5、文件及目录的权限设置 , ^- K( y. Y) y2 i3 ?( V
# B, l8 U. E& I, {2 u) y6 @( H$ m
web目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则,
3 V: M0 [$ D% Q攻击者可以修改主页文件,所以web目录的权限一定要设置好。
' Z+ t9 C7 }# b( Y3 @
* H& c( c4 }( Z* w3 M2 M1 ^还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属; ?( t5 o; ~ s" g% ]& H
主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的
0 f* X2 l2 |5 Q7 M) O+ l, i. @错误: : Z1 n- h2 @1 t
/ D( _: t# \( A. [0 [Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not ( e+ [3 S" f* f
allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php
& R% U6 e7 T% e) Hon line 3 - h$ [. P/ P! u
" Y4 @% I( [$ }7 B* [% a
这样我们能防止许多系统文件被读,比如:/etc/passwd等。
& S0 e3 j! N4 o上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。
! L3 ~; M1 J! w+ ?# Q9 L$ J
E. ]2 {7 t1 k- n
1 O0 R& C2 ^% V$ C& D6 o6、mysql的启动权限设置
. s/ S6 Y+ t5 u" c! g
8 d* U' n0 L! V# }! _ \5 g8 jmysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等
9 e/ r2 |: f r/ v6 j0 W. I系统启动脚本里加上一句: 0 C5 Y( W7 a5 M0 k
y, ~# t3 A8 o' W" ksu mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start"
) q& ^. T: K+ b' p* i! x( W
- H; V) P+ ?+ A" H; L这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 / C: ~5 i8 g) D, ^: b2 j: z% D
8 r4 b) a$ H: k/ x+ @
5 @4 ~8 Y7 p# o# S8 H- o
7、日志文件及上传目录的审核及
9 I. D `4 j( R2 n e! x: T0 C. o
查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且1 X$ {% g. k' P" }
也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非
5 f0 \) q* ]! d* Z4 ]1 _) L法的文件,比如执行脚本等。 ( O+ [ Y# n3 ]' |
7 V/ R& ^/ Z3 F+ ]$ p3 r% H$ ~. N2 R. @2 w. B* w' {. o' S& ?
8、操作系统自身的补丁
8 l* y. p* U1 C0 O. m
. }% o2 h% O `5 |4 b! l2 R一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。 . u6 k; f0 l$ S) U) P; m1 V
. F- g1 U8 w( W5 R2 z% \) k
4 d5 b' x; l, f6 C1 r& c$ \经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,
1 B; K/ T$ K, s, z即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 " K7 l+ L( F" Y/ q% G' F3 Q
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;) 3 C0 q7 m+ Y+ m, L# A8 N/ i, b: |! U
- @0 J$ Z5 \3 x+ M
0 f& t, y6 [4 y# u; P. s参考资料: 0 i9 N" |; V( W
PHP Manual 2 @2 S2 a, o4 j& ~& Z4 W
http://www.zend.com |
|