其原理就是注入一段用戶能控制的腳本或代碼,並讓服務端執行。文件包含漏洞可能出現在JSP、PHP、 ASP等語言中,原理都是一樣的,本文只介紹PHP文件包含漏洞。
要想成功利用文件包含漏洞進行攻擊,需要滿足以下兩個條件:
1. Web應用采用include()等文件包含函數通過動態變量的方式引入需要包含的文件 (文件包含函數還有 include_once()、require()、require_once())
2. 用戶能夠控制該動態變量
現在來看一段簡單的文件包含代碼:
<?php $filename = $_GET['filename']; include($filename);
通過上面的代碼可以看到,在得到變量$filename的值后沒有經過任何處理,直接帶入include()函數中。此處就存在一個文件包含漏洞,利用該漏洞我們可以查看系統中的任意文件。
下面我們來實際測試一下。首先將該PHP頁面上傳到Web服務器,先讓其包含一個正常的txt文件,運行結果如下圖2所示。
圖2
接着我們在該txt文本中插入php代碼,看結果如何?這里給其插入如下圖3所示代碼。
圖3
再次訪問,結果如下圖4所示。
圖4
通過上圖我們可以看到文本中的PHP代碼被成功執行了。
利用該漏洞,我們可以查看系統中的任意文件,比如經常用到的“/etc/passwd”文件,如圖5所示。
圖5
PHP文件包含漏洞分為
一、本地文件包含漏洞(LFI):能夠打開並包含本地文件的漏洞,被稱為本地文件包含漏洞。利用本地文件包含漏洞,可以查看系統任意文件內容,如果具備一些條件,也可以執行命令。在下面的漏洞利用技巧部分對這個有詳細介紹。
二、遠程文件包含漏洞(RFI):如 果php.ini的配置選項allow_url_fopen和allow_url_include為ON的話,則文件包含函數是可以加載遠程文件的,這種 漏洞被稱為遠程文件包含漏洞。利用遠程文件包含漏洞,可以直接執行任意命令。在實際滲透攻擊過程中,攻擊者可以在自己的Web服務器上放一個可執行的惡意 文件,通過目標網站存在的遠程文件包含漏洞來加載文件,從而實現執行任意命令的目的。
文件包含漏洞利用技巧
遠程文件包含漏洞之所以能夠執行命令,就是因為攻擊者可以自定義被包含的文件內容。因此,本地文件包含漏洞要想執行命令,也需要找一個攻擊者能夠控制內容的本地文件。
目前主要有幾下幾種常見的技巧:
包含用戶上傳的文件。這個很好理解,也是最簡單的一種辦法。如果用戶上傳的文件內容中包含PHP代碼,那么這些代碼被文件包含函數加載后將會被執行。但能否攻擊成功,取決於上傳功能的設計,比如需要知道上傳文件存放的物理路徑,還需要上傳的文件有執行權限。
包含data://或php://input等偽協議。這需要目標服務器支持,同時要求allow_url_fopen為設置為ON。在PHP5.2.0之后的版本中支持data:偽協議,可以很方便地執行代碼。
包含Session文件。這部分需要攻擊者能夠控制部分Session文件的內容,PHP默認生成的Session文件一般存放在/tmp目錄下。
包 含日志文件。比如Web服務器的訪問日志文件,這是一種通用的技巧。因為幾乎所有網站都會將用戶的訪問記錄到訪問日志中。因此,攻擊者可以向Web日志中 插入PHP代碼,通過文件包含漏洞來執行包含在Web日志中的PHP代碼,下面的案例中就是利用該技巧成功獲取到目標網站的WebShell的。但需要注 意的是,如果網站訪問量大的話,日志文件可能會非常大,這時如果包含一個這么大的文件時,PHP進程可能會卡死。一般網站通常會每天生成一個新的日志文 件,因此在凌晨時進行攻擊相對來說容易成功。
包含/proc/self/environ文件。這個也是一種通用的技巧,因為它根本不需要猜測被包含文件的路徑,同時用戶也能控制它的內容,常見的做法是向User-Agent中注入PHP代碼來完成攻擊。
PHP文件包含漏洞防范
本部分主要從代碼層和Web服務器安全配置兩個方面來講解PHP文件包含 漏洞的防范。首先來從代碼層來講,在開發過程中應該盡量避免動態的變量,尤其是用戶可以控制的變量。一種保險的做法是采用“白名單”的方式將允許包含的文 件列出來,只允許包含白名單中的文件,這樣就可以避免任意文件包含的風險,可參考下面圖10所示的代碼實現。
圖10
還有一種做法是將文件包含漏洞利用過程中的一些特殊字符定義在黑名單中,對傳入的參數進行過濾,但這樣有時會因為過濾不全,導致被有經驗的攻擊者繞過。
在 Web服務器安全配置方面可以通過設定php.ini中open_basedir的值將允許包含的文件限定在某一特定目錄內,這樣可以有效避免利用文件包 含漏洞進行的攻擊。需要注意的是,open_basedir的值是目錄的前綴,因此假設設置如下值:open_basedir=/var/www /test,那么實際上以下目錄都是在允許范圍內的。
/var/www/test
/var/www/test123
/var/www/testabc
如果要限定一個指定的目錄,需要在最后加上“/”,這一點需要特別注意。
open_basedir=/var/www/test/
如果有多個目錄,在Windows下目錄間用分號隔開,在Linux下面則用冒號隔開。
綜合來說,文件包含漏洞的防范方案有:
1. 在代碼層面
文件包含函數的文件名盡量避免動態變量,尤其是用戶可以控制的變量;最好使用文件名白名單
2. 服務器配置方面
a. php.ini中open_basedir的值將允許包含的文件限定在某一特定目錄內,這樣可以有效避免利用文件包 含漏洞進行的攻擊 {本地文件包含漏洞}
b. php.ini的配置選項allow_url_fopen和allow_url_include設置為Off (禁止打開遠程文件,禁止包含遠程文件) {遠程文件包含漏洞}
文章轉自:http://www.rising.com.cn/newsletter/news/2013-04-25/13587.html
