|
|
发布日期:2001-11-27; \0 k2 M4 X1 u7 T4 _9 e
文章内容:
- H6 r2 h+ b$ h2 w* R--------------------------------------------------------------------------------
" _' }% {% F1 J$ R% _( P& D5 K5 X$ d: v& Z* X2 O2 I
作者:san(小许) san@nsfocus.com 4 D, E4 K, ]" u7 T
5 K: ^3 s! o) E--------------------------------------------------------------------------------! n: e6 w$ [3 K
/ O* [+ c9 N& e1 s
前面象Shaun Clowes和rfp等都比较详细的介绍了php、cgi程序在编程过程中遇到的问题,以; B& q v) }$ r" f( u6 ]
及如何通过应用程序漏洞突破系统,这篇文章我们来通过对php的一些服务器端特性来进行配
, D, w1 V! P# e, \( ]置加强php的安全。写cgi脚本的时候我们的确一定注意各种安全问题,对用户输入进行严格的
0 c) {$ c Z3 ^8 ^% Q) G过滤,但是常在岸边走哪有不湿鞋,吃烧饼哪有不掉芝麻,人有失蹄马有失手,连著名的5 k5 ^# E" z) K0 R# g; J
phpnuke、phpMyAdmin等程序都出现过很严重的问题,更何况象我等小混混写的脚本。所以现
4 @- K; v7 ^$ q3 [ f在我们假设php脚本已经出现严重问题,比如象前一阵子phpnuke的可以上传php脚本的大问题
9 y2 P" z9 f4 s9 n9 c6 R& p% l了,我们如何通过对服务器的配置使脚本出现如此问题也不能突破系统。
" T/ ?8 S! Z3 j' k6 f& M% u/ f, U4 F
" a" I' W, j( \/ O# t1、编译的时候注意补上已知的漏洞 3 N4 D5 D! H0 x. B& F4 J4 u
7 O& O7 l6 h$ \1 m: ^7 J! Y
从4.0.5开始,php的mail函数加入了第五个参数,但它没有好好过滤,使得php应用程序能突8 `; R; Y, t( a5 C# c
破safe_mode的限制而去执行命令。所以使用4.0.5和4.0.6的时候在编译前我们需要修改php源
# U; K4 p3 T' S码包里ext/standard/mail.c文件,禁止mail函数的第五参数或过滤shell字符。在mail.c文件) v) z+ k+ T# m
的第152行,也就是下面这行: 1 C- b( i$ }6 N
N' ~; p8 J: V4 x; ]" Z0 q, x
if (extra_cmd != NULL) { # j+ d% {6 d8 f( d- @
6 z8 B$ W" B. d1 i% j4 d后面加上extra_cmd=NULL;或extra_cmd = php_escape_shell_cmd(extra_cmd);然后编译php 8 X: g; V0 Y; W4 {: `+ r& S
那么我们就修补了这个漏洞。
# I( ]7 @/ {6 N/ z% g( n, q1 v' _
& v# H9 x! P, X ]
4 A8 H* D1 Y0 i4 E- v2、修改php.ini配置文件
! C \" H% }$ j8 x# z8 w6 G* @% j9 S% g+ S; [' l* y7 l& Q
以php发行版的php.ini-dist为蓝本进行修改。
$ y4 @. e3 [) `% C* D) A
0 f! \1 n- y- y* z8 u `' L% s7 W1)Error handling and logging
# x1 U' B; B- q/ y* I! S在Error handling and logging部分可以做一些设定。先找到: 3 x. @" H; z3 S* {& {. M0 n
display_errors = On 2 F0 r1 I; \ m3 C/ X
) Q( T# q& {5 i
php缺省是打开错误信息显示的,我们把它改为: 0 O6 g# s" X" r5 k; S3 b0 b
5 M5 p4 m+ d. r& G" t9 c+ Z
display_errors = Off
0 }6 [" c6 t' T6 P, s+ T
$ p! {+ }+ ^/ v关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻
2 C4 R8 m/ D( z# s) P2 F击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造
" C1 q" V+ ~4 n2 W) b/ L9 b成一定的障碍。这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以
* r! F8 H7 i- ^# f0 c下: 8 Q8 p/ d. {* j) X6 h
0 N- h3 d) r: K( R: zlog_errors = Off
* k$ F6 o m% `0 [6 z. `
) }/ P3 n/ ]- ?* R. F改为: 1 r w) C; [( t* \ |
log_errors = On
/ E0 g# v$ S9 P) h% V ^5 Q
% w" ]7 v8 B/ V; D以及指定文件,找到下面这行:
$ _$ V* Q' w& O% ~0 N
# i/ |9 E; `; m1 \; s. A: b;error_log = filename
4 R E Q8 G! O m+ \! i% s1 X3 w- g% _$ H( E& S9 P
去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log
; n( B6 v: B2 n4 i+ m/ z8 G( B' k3 u3 g7 q+ ]+ X
error_log = /usr/local/apache/logs/php_error.log
4 g" I) E6 O: ~
; a a! a3 D/ Y' D0 a这样所有的错误都会写到php_error.log文件里。 * Z: ?: K X- y. i7 \
; `8 |4 u" Y8 t4 x
2)Safe Mode * k6 Z. o% ~9 G2 P+ |0 [
# O+ I- B7 P& l9 X- x, j
php的safe_mode功能对很多函数进行了限制或禁用了,能在很大程度解决php的安全问题。在8 G" K4 p3 f$ O# \( r
Safe Mode部分找到: 4 D% Y$ Q+ c/ T; L% y" r' a0 [
. z# B( ]9 x& T( y; l! b# {
safe_mode = Off
. j- f, F% s# Z5 S* D i5 z+ K) _" u4 U1 c
改为: 6 X V* k" k* a4 {9 A8 A' y# n' I
# j# N+ _6 d; S9 U
safe_mode = On . P8 z/ `/ g. q1 Z3 u
* k6 x0 g( h8 [ J3 g" Z6 d这样就打开了safe_mode功能。象一些能执行系统命令的函数shell_exec()和``被禁止,其它2 I! I* r# x9 V( g @( E a
的一些执行函数如:exec(), system(), passthru(), popen()将被限制只能执行
! {, z7 Y% \# V) y& usafe_mode_exec_dir指定目录下的程序。如果你实在是要执行一些命令或程序,找到以下:
8 o: A1 t0 O# y6 }6 u/ o4 L
8 h3 \# ?' W& ~safe_mode_exec_dir =
3 f) k2 w! |9 G7 k z" W, {# @' L5 a( {" Z6 a
指定要执行的程序的路径,如: - I% z [, [% f+ R6 p+ F& `: Z
$ T) ?& \* V9 P# t8 x* @
safe_mode_exec_dir = /usr/local/php/exec
3 I2 ]' e* w( P9 Z$ b
8 ]5 r/ O. U7 w然后把要用的程序拷到/usr/local/php/exec目录下,这样,象上面的被限制的函数还能执行* o( J1 c" {) U& m8 V
该目录里的程序。
* ^ O) i/ h, g ^& u+ C/ k1 z1 E9 j# t- b- a6 o( n. _8 {. K% N% K
关于安全模式下受限函数的详细信息请查看php主站的说明:
; K( }7 c. [" Y; K( M8 F0 lhttp://www.php.net/manual/en/features.safe-mode.php
$ c% u$ _8 c% @5 f
7 H4 l3 u; x8 m3)disable_functions
9 A, P* b' _! y- A1 x2 T) d9 D) T. a$ t. R* v0 Q
如果你对一些函数的危害性不太清楚,而且也没有使用,索性把这些函数禁止了。找到下面这
1 ?. n5 X; ]6 l0 z4 {行:
- c% Q3 X: K0 g+ E6 T1 B4 d5 o7 v: V7 B( N4 _
disable_functions = 5 X0 [6 F& T0 [0 G2 P, a
6 E' {. x9 J7 T8 G2 {5 X4 D
在”=“后面加上要禁止的函数,多个函数用”,“隔开。
' e4 U; D1 e2 [& u$ L( w$ N! B" H. O3 _' `8 \/ x
) R1 q+ h! h' O3 m* z3、修改httpd.conf
" f. k9 s9 b% t( M# m* ]! ~; P
4 ]% Z0 [% e1 O+ Q如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作
! X/ j/ R% h; c x* F l路径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行: " ^7 X" Z3 V2 K7 s! W+ O, j1 ?/ F
: M- |9 U `( ^/ o: k( w) K0 }
<Directory /usr/local/apache/htdocs> 8 Z2 S. K) E* i+ u4 o
php_admin_value open_basedir /usr/local/apache/htdocs
% D6 i) e! X9 j0 q( ^3 S$ j6 ?</Directory> + r: t1 Z8 e6 L6 s7 M! |6 y* A
* n7 E! c: m3 t5 N& g! X
这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打5 x6 s" E; F+ y* E( u
开的话会提示这样的错误: 3 Q7 [ `* S% J8 v0 v
' P2 ~ T+ B$ A& D
Warning: open_basedir restriction in effect. File is in wrong directory in 0 ~1 U2 S- g( W7 i* s
/usr/local/apache/htdocs/open.php on line 4 ! L. G% B6 Z! {; K, P6 H3 u1 b
6 s2 K/ m8 @( U. \: y9 G
等等。 1 l$ w9 L6 B/ J
, h1 }. [, L. M- m+ }: s& l7 U* }
. S4 x6 ^) S7 [; ?4、对php代码进行编译 $ \8 J2 l- t8 ~. c
. d! [+ c) _; @( A; d' [9 f
Zend对php的贡献很大,php4的引擎就是用Zend的,而且它还开发了ZendOptimizer和2 e- Q% V" G$ W8 M1 Y
ZendEncode等许多php的加强组件。优化器ZendOptimizer只需在http://www.zend.com注册就
' F' @! T l/ h* b3 ]可以免费得到,下面几个是用于4.0.5和4.0.6的ZendOptimizer,文件名分别对于各自的系统
" ~8 D- ~) i; A+ ~2 ?:
* `% B/ G& B* m& o
+ {) W/ T, w0 Z6 l. x! XZendOptimizer-1.1.0-PHP_4.0.5-FreeBSD4.0-i386.tar.gz
) r, G5 f( L) m5 F) s+ D& YZendOptimizer-1.1.0-PHP_4.0.5-Linux_glibc21-i386.tar.gz
: l' t: Y# O8 K4 ~ZendOptimizer-1.1.0-PHP_4.0.5-Solaris-sparc.tar.gz
: d6 [2 J; R" l5 C, |' HZendOptimizer-1.1.0-PHP_4.0.5-Windows-i386.zip
* Z+ D) T3 f/ ]7 K: u d
; M: w' F; T9 @( o* W优化器的安装非常方便,包里面都有详细的说明。以UNIX版本的为例,看清操作系统,把包里# ]! H) U4 x% _6 O/ N4 n$ k1 B7 N$ h
的ZendOptimizer.so文件解压到一个目录,假设是/usr/local/lib下,在php.ini里加上两句
+ A4 P+ M9 F' d:
) b+ ?- F: A% W/ \+ [ O3 @& {, |: G$ |: e3 ~. l0 P
zend_optimizer.optimization_level=15 % P0 J6 s% L5 x" I1 A
zend_extension="/usr/local/lib/ZendOptimizer.so" 6 H( u0 z0 X( [' {
) Q( _0 M, ~% Z
就可以了。用phpinfo()看到Zend图标左边有下面文字:
1 D0 ?# d( c; P. P& M& Y) O: n4 E6 @) P
with Zend Optimizer v1.1.0, Copyright (c) 1998-2000, by Zend Technologies & b0 t- E8 I2 j* z" j0 q, u9 ^8 h
1 _4 j! N3 B |
那么,优化器已经挂接成功了。
! U$ P' l: e- ?8 t2 p; }# p7 h# r+ _4 F6 L9 ?
但是编译器ZendEncode并不是免费的,这里提供给大家一个http://www.PHPease.com的马勇设
& i1 Z/ F. Q: l计的编译器外壳,如果用于商业目的,请与http://www.zend.com联系取得许可协议。
9 |' F0 L% A9 w' Y% W
% {, u! D3 R( s3 \* Rphp脚本编译后,脚本的执行速度增加不少,脚本文件只能看到一堆乱码,这将阻止攻击者进
& N% x( G X9 Z' n, E5 e一步分析服务器上的脚本程序,而且原先在php脚本里以明文存储的口令也得到了保密,如' K3 N. c8 i8 s
mysql的口令。不过在服务器端改脚本就比较麻烦了,还是本地改好再上传吧。 " o7 ?) y- i% O! E
) ~( T; N: O" h0 v0 l0 S
, l) e$ t% z i6 L5、文件及目录的权限设置 , e- a' U! \4 E, M7 Y
" U1 d! y. L0 \1 Y: g8 {# eweb目录里除了上传目录,其它的目录和文件的权限一定不能让nobody用户有写权限。否则, C% K0 o" r4 |6 m p% S
攻击者可以修改主页文件,所以web目录的权限一定要设置好。
+ |. x! Y0 b9 ?. A0 J8 M% i
( o. @+ I, w2 v! s' l还有,php脚本的属主千万不能是root,因为safe_mode下读文件的函数被限制成被读文件的属
: U+ @7 \- g; h7 [/ S8 K* }9 n主必须和当前执行脚本的属主是一样才能被读,否则如果错误显示打开的话会显示诸如以下的- d2 s7 |6 {: i4 X0 q V
错误:
$ D. ^- [" }$ W% ~# N( u+ Q' b3 Q1 U f+ d3 d9 u" o2 p9 O
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not . X3 C& m4 Q0 w/ u
allowed to access /etc/passwd owned by uid 0 in /usr/local/apache/htdocs/open.php ' a) g" u4 @* Y( `
on line 3
2 h6 W9 B2 A, X3 e
* N. s; x+ X% t& U; G& B这样我们能防止许多系统文件被读,比如:/etc/passwd等。 0 Z2 [; a4 }) h* ]' l1 D- @
上传目录和上传脚本的属主也要设成一样,否则会出现错误的,在safe_mode下这些要注意。
3 P% Q5 g7 T% {7 a. G& Q0 ~, {- v w5 D9 c
! l2 K' L7 b) P% _0 l
6、mysql的启动权限设置
! C' v9 `0 A$ V( I) d3 i! u, F- I6 F
mysql要注意的是不要用root来启动,最好另外建一个mysqladm用户。可以在/etc/rc.local等! V- x& }- e9 C# t6 X8 j+ K$ C
系统启动脚本里加上一句: 1 g# l. I$ n( f+ z% l. L8 O
% A; H$ S# ?6 {; L
su mysqladm -c "/usr/local/mysql/share/mysql/mysql.server start"
. d. k+ X; H+ C* ^
. c' R `. ?6 S/ W- @这样系统重启后,也会自动用mysqladmin用户启动mysql进程。 7 T2 @7 j' t7 V7 [2 Y9 P/ ~0 u
: @) e$ [9 H0 g6 a# r
' Z7 E( w* S5 ] W7、日志文件及上传目录的审核及 1 l4 }8 r4 \9 i7 e0 }" K
1 _ i6 F) N+ ]( S6 q查看日志和人的惰性有很大关系,要从那么大的日志文件里查找攻击痕迹有些大海捞针,而且
0 Q+ ~2 D" f/ o! e( f* q也未必有。web上传的目录里的文件,也应该经常检查,也许程序有问题,用户传上了一些非
5 n Y+ B4 H+ n2 o9 U6 `: x- P; w法的文件,比如执行脚本等。
5 F& z3 {% ]. k6 Y+ Q E) ~0 M9 ?3 ?; o) ?+ h# E \
7 U6 d6 v- q1 l2 X" l
8、操作系统自身的补丁
. u" t' N H3 j8 d0 A# l- k
* q6 E) ]8 ?# \: B9 q& U$ w, j一样,给系统打已知漏洞的补丁是系统管理员最基本的职责,这也是最后一道防线。 ' r3 @0 n$ q% l$ X5 U
9 B: ~% |9 l& j2 x o
# n- [- {& M4 e/ i7 D- x) ?, K
经过以上的配置,虽然说不上固若金汤,但是也在相当程度上给攻击者的测试造成很多麻烦,
; l. o& r/ i$ l! O6 u9 D即使php脚本程序出现比较严重的漏洞,攻击者也无法造成实际性的破坏。 6 Q. q" E8 c9 z; q& w
如果您还有更古怪,更变态的配置方法,希望能一起分享分享;) 5 [; l V. l8 i& q0 K! s, A
' e2 Y+ V! L" ?7 Z. E
* c+ N) p5 L% V& {! N: [) A3 ~参考资料:
! h' O2 E' u5 S1 \PHP Manual & M# y' G: K) r' k' M" L
http://www.zend.com |
|