程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 存在於php程序中的安全細節

存在於php程序中的安全細節

編輯:關於PHP編程

對於腳本安全這個話題似乎永遠沒完沒了,假如你經常到國外的各種各樣的bugtraq上,你會發現有一半以上都和腳本相關,諸如SQL injection,XSS,Path Disclosure,Remote commands execution這樣的字眼比比皆是,我們看了之後的用途難道僅僅是抓肉雞?對於我們想做web安全的人來說,最好就是拿來學習,可是萬物抓根源,我們要的不是魚而是漁。在國內,各種各樣的php程序1.0版,2.0版像雨後春筍一樣的冒出來,可是,大家關注的都是一些聞名的cms,論壇,blog程序,很少的人在對那些不出名的程序做安全檢測,對於越來越多的php程序員和站長來說,除了依靠服務器的堡壘設置外,php程序本身的安全多少你總得懂點吧。

有人說你們做php安全無非就是搞搞注入和跨站什麼什麼的,大錯特錯,假如這樣的話,一個magic_quotes_gpc或者服務器裡的一些安全設置就讓我們全沒活路了:(。我今天要說的不是注入,不是跨站,而是存在於php程序中的一些安全細節問題。OK!切入正題。

注重一些函數的過濾

有些函數在程序中是經常使用的,像include(),require(),fopen(),fwrite(),readfile(),unlink(),eval()以及它們的變體函數等等。這些函數都很實用,實用並不代表讓你多省心,你還得為它們多費點心。 :)

1.include(),require()和fopen(),include_once(),require_once()這些都可以遠程調用文件,對於它們的危害,google搜一下你就會很明了,對於所包含調用的變量沒過濾好,就可以任意包含文件從而去執行。舉個例子,看print.php

...

if (empty ($bn) ) { //檢查是變量$bn是否為空

include ("$cfg_dir/site_${site}.php"); //把$cfg_dir這個路徑裡的site_${site}.php包含進來

...

不管存不存在$cfg_dir目錄,$site這個變量你可以很自然的去使用,因為他根本沒檢查$site變量啊。可以把變量$site指定遠程文件去調用,也可以是本地的一個文件,你所指定的文件裡寫上php的語句,然後它就去包含執行這個含有php語句的文件了.就像這樣

列出文件目錄

甚至可以擴展到包含一些治理員文件,提升權限,典型的像以前phpwind,bo-blog的漏洞一樣。除了依靠php.ini裡的allow_url_fopen設為off禁止遠程使用文件和open_base_dir禁止使用目錄以外的文件外,你還得事先聲明好只能包含哪些文件,這裡就不多說廢話了。

2.fopen(),file(),readfile(),openfile(),等也是該非凡留意的地方。函數本身並沒什麼,它們的作用是去打開文件,可是假如對變量過濾不徹底的話,就會洩露源代碼。這樣的函數文本論壇裡會有很多。

...

$articlearray=openfile("$dbpath/$fid/$tid.php"); //打開$dbpath/$fid這個路徑的$tid.php文件

$topic_detail=explode("|",$articlearray[0]); //用分割符|讀出帖子的內容

...

很眼熟吧,這是ofstar以前版本的read.php,$fid和$tid沒有任何過濾,$tid指定為某個文件提交,就發生了原代碼洩露。就像這樣。

http://explame.com/ofstar/read.php?fid=123&tid=../index

$tid會被加上php的後綴,所以直接寫index。這僅僅是個例子,接著看吧。

3.fwrite()和它的變體函數這種漏洞想想都想得出,對於用戶提交的字符沒過濾的話,寫入一段php後門又不是不可以。

4.unlink()函數,前段時間,phpwind裡任意刪除文件就是利用這個函數,對於判定是否刪除的變量沒過濾,變量可以指定為任意文件,當然就可以刪除任意文件的變量。

5.eval(),preg_replace()函數,它們的作用是執行php代碼,假如字符串沒被經過任何過濾的話,會發生什麼呢,我就常看見一些cms裡面使用,想想,一句話的php木馬不就是根據eval()原理制作的嗎?

6.對於system()這些系統函數,你會說在php.ini裡禁止系統函數,對,這也是好辦法,可是象一些程序裡需要,那是不是就不用了呢?就像上次我看到的一套很漂亮的php相冊一樣。另外對於popen(),proc_open(),proc_close()函數你也得非凡注重,盡管他們執行命令後並沒有直接的輸出,但你想這到底對黑客們有沒有用呢。再這裡php提供提供了兩個函數,escapeshellarg(),escapeshellcmd(),這兩個函數用來對抗系統函數的調用攻擊,也就是過濾。

對於危害,來舉個例子,我們來看某論壇prod.php

07 $doubleApp = isset($argv[1]); //初始化變量$doubleApp

...

14 if( $doubleApp ) //if語句

15 {

16 $appDir = $argv[1]; //初始化$appDir

17 system("mkdir $prodDir/$appDir"); //使用系統函數system來創建目錄$prodDir/$appDir

 

本來是拿來創建$prodDir/$appDir目錄的,再接著看上去,程序僅僅檢測是否存在$argv[1],缺少對$argv[1]的必要過濾,那麼你就可以這樣

/prod.php?argv[1]=|ls -la或者/prod.php?argv[1]=|cat /etc/passwd

(分割符 | 在這裡是UNIX的管道參數,可以執行多條命令。)

到這裡,常見的漏洞類型應該知道點了吧。

 

 

對於非凡字符的重視

對於非凡字符,有句話叫All puts is invalid.外國人文章裡這句話很常見的。所有輸入都是有害的。你永遠不要對用戶所輸入的東西省心,為了對付這些危害,程序員都在忙著過濾大把大把的字符,唯恐漏了什麼。而有些程序員呢?似乎從沒注重過這些問題,從來都是敞開漏洞大門的。不說廢話,還是先看看下面這些東西吧。

1.其實程序的漏洞裡最要害,最讓開發者放心不下的就是帶著$符號的美元符號,變量,對於找漏洞的人來說,抓著變量兩個字就是一切。就像目錄遍歷這個bug,很多郵件程序都存在,開發者考慮的很周全,有的甚至加上了網絡硬盤這個東西,好是好,就像

http://mail.com/file.php?id=1&put=list&tid=1&file=./

要是我們把file這個變量換成./../甚至更上層呢?目錄就這樣被遍歷了。

2.尖括號"<>"跨站你不會不知道吧,一些搜索欄裡,文章,留言,像前段時間phpwind附件那裡的跨站等等。當然,對於跨站問題,你要過濾的遠遠不止尖括號。不怕過濾時漏掉什麼,而是怕你想不起要去過濾。

3.斜桿和反斜桿:對於/和的過濾,記得魔力論壇的附件下載處的原代碼洩露嗎?

attachment.php?id=684&u=3096&extension=gif&attach=.............includesconfig.php&filename=1.gif

對於過濾.. / 的問題,像windows主機不僅要過濾../還要過濾..,windows主機對會解析為/,這些細節跟SQL injection比起來,什麼才叫深入呢?

4.對於反引號(``),反引號在php中很強大,它可以執行系統命令,就像system()這些系統函數一樣,假如用戶的惡意語句被它所執行的話就會危害服務器,我想除了服務器設置的很好以外,對於它們,你還是老老實實的過濾好吧。

5.對於換行符,NULL字符等等,像" ,x0B, , ,

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved