萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP程序漏洞產生的原因分析與防范方法說明

PHP程序漏洞產生的原因分析與防范方法說明

 本篇文章主要是對PHP程序漏洞產生的原因分析與防范方法進行了詳細的介紹,需要的朋友可以過來參考下,希望對大家有所幫助

濫用include    1.漏洞原因:    Include是編寫PHP網站中最常用的函數,並且支持相對路徑。有很多PHP腳本直接把某輸入變量作為Include的參數,造成任意引用腳本、絕對路徑洩露等漏洞。看以下代碼:    ...  $includepage=$_GET["includepage"];  include($includepage);  ...   很明顯,我們只需要提交不同的Includepage變量就可以獲得想要的頁面。如果提交一個不存在的頁面,就可以使PHP腳本發生錯誤而洩露實際絕對路徑(這個問題的解決辦法在下面的文章有說明)。    2.漏洞解決:    這個漏洞的解決很簡單,就是先判斷頁面是否存在再進行Include。或者更嚴格地,使用數組對可Include的文件作出規定。看以下代碼:     代碼如下: $pagelist=array("test1.php","test2.php","test3.php"); //這裡規定可進行include的文件  if(isset($_GET["includepage"])) //判斷是否有$includepage  {  $includepage=$_GET["includepage"];  foreach($pagelist as $prepage)  {  if($includepage==$prepage) //檢查文件是否在允許列表中  {  include($prepage);  $checkfind=true;  break;  }  }  if($checkfind==true){ unset($checkfind); }  else{ die("無效引用頁!"); }  }   這樣就可以很好地解決問題了。    小提示:有此問題的函數還有:require(),require_once(),include_once(),readfile()等,在編寫的時候也要注意。    未對輸入變量進行過濾    1.漏洞原因:    這 個漏洞早在ASP中出現過,當時造成的注入漏洞不計其數。但由於PHP在當時的影響力較小,所以沒有太多的人能夠注意這點。對於PHP來說,這個漏洞 的影響性比ASP更大,因為有比較多的PHP腳本使用到文本型數據庫。當然也存在SQL語句的注入問題。舉個比較經典的例子,首先是數據庫的:     代碼如下: $id=$_GET["id"];    $query="SELECT * FROM my_table where id='".$id."'"; //很經典的SQL注入漏洞  $result=mysql_query($query);     這裡很明顯我們可以用注入來獲得數據庫的其它內容了。這裡就不再詳細敘述,和ASP注入一樣的,大家可以看看以前的黑防。然後我們看文本數據庫的問題:  復制代碼 代碼如下: $text1=$_POST["text1"];  $text2=$_POST["text2"];  $text3=$_POST["text3"];    $fd=fopen("test.php","a");  fwrite($fd,"rn$text1&line;$text2&line;$text3");  fclose($fd);     文本的漏洞可以說是更加嚴重。倘若我們的提交的變量中插入一段很小的PHP代碼,就可以另這個文本數據庫test.php變成PHP後門。甚至插入上傳代碼,讓我們可以上傳一個完善的PHP後門。接著提升權限,服務器就是你的了。    2.漏洞解決:    這個漏洞的解決方法其實很簡單,就是嚴格對全部提交的變量進行過濾。對一些敏感的字符進行替換。我們可以借助PHP提供的htmlspecialchars()函數來替換HTML的內容。這裡給出一段例子:     代碼如下: //構造過濾函數  function flt_tags($text)  {  $badwords=array("操","fuck"); //詞匯過濾列表  $text=rtrim($text);  foreach($badwords as $badword) //這裡進行詞匯的過濾  {  if(stristr($text,$badword)==true){ die("錯誤:你提交的內容含有敏感字眼,請不要提交敏感內容。"); }  }  $text=htmlspecialchars($text); //HTML替換  //這兩行把回車替換為    $text=str_replace("r"," ",$text);  $text=str_replace("n","",$text);  $text=str_replace("&line;","│",$text); //文本數據庫分隔符"&line;"替換為全角的"│"  $text=preg_replace("/s{ 2 }/"," ",$text); //空格替換 中國網管聯盟 $text=preg_replace("/t/"," ",$text); //還是空格替換  if(get_magic_quotes_gpc()){ $text=stripslashes($text); } //如果magic_quotes開啟,則進行'的替換  return $text;  }    $text1=$_POST["text1"];  $text2=$_POST["text2"];  $text3=$_POST["text3"];    //過濾全部輸入  $text1=flt_tags($text1);  $text2=flt_tags($text2);  $text3=flt_tags($text3);    $fd=fopen("test.php","a");  fwrite($fd,"rn$text1&line;$text2&line;$text3");  fclose($fd);     經過一番替換和過濾後,你就可以安全地把數據寫入文本或數據庫了。    管理員判斷不完全   1.漏洞原因:    我們用PHP寫腳本,通常要涉及管理員的權限問題。而一些腳本僅僅對管理員權限作出"是"判斷,而往往忽略了"否"判斷。在PHP配置文件中 register_globals打開的情況下(4.2.0以後版本默認關閉,但有不少人為了方便而打開它,這是極度危險的行為),就會出現提交變量冒充 管理員的情況。我們看一下的例子代碼:  代碼如下: $cookiesign="admincookiesign"; //判斷是否Admin的cookie變量  $adminsign=$_COOKIE["sign"]; //獲取用戶的cookie變量    if($adminsign==$cookiesign)  {  $admin=true;  }    if($admin){ echo "現在是管理員狀態。"; }     看上去好像很安全的樣子,呵呵。現在我們假設PHP配置文件中register_globals為打開狀態。我們提交這樣一個地址“test.php? admin=true”,結果看到了嗎?我們雖然沒有正確的Cookie,但由於register_globals為打開狀態,使得我們提交的admin 變量自動注冊為true。而且腳本缺少“否”判斷,就使得我們順利地通過admin=true取得管理員的權限了。這個問題存在於大部分網站和論壇當中。    2.漏洞解決:    解決這個問題,我們只需要在腳本中加入對管理員的“否”判斷即可。我們仍然假設PHP配置文件中register_globals為打開狀態。看一下的代碼:   代碼如下: $cookiesign="admincookiesign"; //判斷是否Admin的cookie變量  $adminsign=$_COOKIE["sign"]; //獲取用戶的cookie變量    if($adminsign==$cookiesign)  {  $admin=true;  }  else  {  $admin=false;  }  if($admin){ echo "現在是管理員狀態。"; }     這 樣,就算攻擊者在沒有正確Cookie的情況下提交了admin=true的變量,腳本在以後的判斷中也會把$admin設置為False。這樣就解 決了部分的問題。但由於$admin是變量,倘若在以後的其他腳本引用中出現了漏洞使得$admin被重新賦值就會引發新的危機。因此,我們應該使用常量 來存放管理員權限的判定。使用Define()語句定義一個admin常量來記錄管理員權限,在此以後若配重新賦值就會出錯,達到保護的目的。看以下代 碼:  復制代碼 代碼如下: $cookiesign="admincookiesign"; //判斷是否Admin的cookie變量  $adminsign=$_COOKIE["sign"]; //獲取用戶的cookie變量    if($adminsign==$cookiesign)  {  define(admin,true);  }  else  {  define(admin,false);  }  if(admin){ echo "現在是管理員狀態。"; }     值得注意的是,我們使用了Define語句,所以在調用Admin常量時前面不要習慣性的加變量符號$,而應該使用Admin和!admin。    文本數據庫暴露    1.漏洞原因:    前面已經說過,由於文本數據庫具有很大的靈活性,不需要任何外部支持。加上PHP對文件的處理能力十分強,因此文本數據庫在PHP腳本中的應用甚廣。甚至有幾個很好的論壇程序就是使用文本數據庫的。但有得必有失,文本數據庫的安全性也是比其他數據庫要低的。    2.漏洞解決:    文 本數據庫作為一個普通的文件,它可以被下載,就像MDB一樣。所以我們要用保護MDB的辦法來保護文本數據庫。把文本數據庫的後綴名改為.PHP。並 在數據庫的第一行加入。這樣文本數據庫就會作為一個PHP文件,並且在第一行退出執行。也就是返回一個空頁面,從而達到保護文本數據庫的目的。    錯誤路徑洩露    1.漏洞原因:    PHP遇到錯誤時,就會給出出錯腳本的位置、行數和原因,例如:    Notice: Use of undefined constant test - assumed 'test' in D:interpubbigflytest.php on line 3   有很多人說,這並沒有什麼大不了。但洩露了實際路徑的後果是不堪設想的,對於某些入侵者,這個信息可是非常重要,而事實上現在有很多的服務器都存在這個問題。&nb
copyright © 萬盛學電腦網 all rights reserved