1. 程式人生 > 實用技巧 >DVWA 通關指南:File Inclusion(檔案包含)

DVWA 通關指南:File Inclusion(檔案包含)

目錄

File Inclusion(檔案包含)

Some web applications allow the user to specify input that is used directly into file streams or allows the user to upload files to the server. At a later time the web application accesses the user supplied input in the web applications context. By doing this, the web application is allowing the potential for malicious file execution.
有些 web 應用程式允許使用者指定直接檔案流的輸入,或允許使用者將檔案上載到伺服器。稍後 web 應用程式訪問 web 應用程式上下文中使用者提供的輸入。通過這樣做,web 應用程式允許惡意檔案執行。
If the file chosen to be included is local on the target machine, it is called "Local File Inclusion (LFI). But files may also be included on other machines, which then the attack is a "Remote File Inclusion (RFI).
如果選擇要包含的檔案是目標計算機上的本地檔案,則稱為“本地檔案包含(LFI)”。但是檔案也可能包含在其他機器上,這樣的攻擊就是“遠端檔案包含(RFI)”。
When RFI is not an option. using another vulnerability with LFI (such as file upload and directory traversal) can often achieve the same effect.Note, the term "file inclusion" is not the same as "arbitrary file access" or "file disclosure".
當 RFI 不是一個選項時。在 LFI 中使用另一個漏洞(例如檔案上傳和目錄遍歷)通常可以達到相同的效果。注意術語“檔案包含”與“任意檔案訪問”或“檔案洩漏”不同。
Read all five famous quotes from '../hackable/flags/fi.php' using only the file inclusion.
請在僅使用檔案包含的情況下,閱讀 “../hackable/flags/fi.php” 中的五句名言。

Low Level

This allows for direct input into one of many PHP functions that will include the content when executing.Depending on the web service configuration will depend if RFI is a possibility.
這允許直接輸入到許多PHP函式中的一個,這些函式將在執行時包含內容。RFI 是否可行取決於 web 的服務配置。

原始碼審計

原始碼很簡單,用 GET 方法接收檔案路徑,然後將其包含進來。伺服器包含檔案時,無論檔案是否是 PHP 檔案,都會嘗試當做 PHP 檔案來執行。如果檔案內容確實是 PHP 檔案,則會正常執行並返回結果,如果不是則會將檔案內容回顯到網頁中,所以檔案包含漏洞常常會導致任意檔案讀取與任意命令執行。

<?php

// The page we wish to display
$file = $_GET['page'];

?> 

例如靶場提供了 3 個檔案,單擊這些檔案就會顯示其執行內容,同時 url 也會用 GET 方法傳遞引數。

攻擊方式

page 引數指的是檔案路徑,因此我們先傳個不存在的檔名測試一下,看看有沒有報錯資訊。傳遞 page 引數為 “1.php”,靶場報錯並返回了檔案所在的路徑。

Warning: include(1.php): failed to open stream: No such file or directory in D:\DVWA-master\vulnerabilities\fi\index.php on line 36
Warning: include(): Failed opening '1.php' for inclusion (include_path='.;C:\php\pear;../../external/phpids/0.6/lib/') in D:\DVWA-master\vulnerabilities\fi\index.php on line 36

因此我們直接用相對路徑,訪問上兩級資料夾下的 “fi.php'” 檔案,構造出 payload。

?page=..\..\hackable\flags\fi.php

Medium Level

The developer has read up on some of the issues with LFI/RFI, and decided to filter the input. However, the patterns that are used, isn't enough.
開發人員已經閱讀了 LFI/RFI 的一些問題,並決定過濾輸入,然而他所使用的過濾還不夠。

原始碼審計

原始碼如下,程式碼增加了 str_replace 函式對 page 引數進行了過濾。將 “http://”、“https://”替換為空阻止遠端包含漏洞,將“../”、“..\” 替換為空阻止用相對路徑訪問檔案。

<?php

// The page we wish to display
$file = $_GET[ 'page' ];

// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );

?> 

攻擊方式

雖然程式碼將相對路徑的語法過濾了,但是絕對路徑不受影響,可以利用網頁的報錯資訊推匯出其他檔案的絕對路徑。當然也可以使用雙寫繞過,也就是讓 str_replace 函式替換後的 page 引數是檔案路徑即可。

?page=...\.\...\.\hackable\flags\fi.php

High Level

The developer has had enough. They decided to only allow certain files to be used. However as there are multiple files with the same basename, they use a wildcard to include them all.
開發者已經受夠了,他們決定只允許使用某些檔案。但是由於存在多個具有相同基名的檔案,因此它們使用萬用字元將它們全部包括在內。

原始碼審計

原始碼如下,使用 fnmatch 根據指定的模式來匹配檔名或字串。該函式將檢查 page 引數開頭必須是否是 file,若是伺服器才會去包含相應的檔案。

<?php

// The page we wish to display
$file = $_GET[ 'page' ];

// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit;
}

?>

攻擊方式

雖然是隻能包含 file 開頭的檔案,但是實在太巧合了,我們依然可以利用 file 偽協議讀取到檔案內容。

?page=file:///D:\DVWA-master\hackable\flags\fi.php

Impossible Level

The developer calls it quits and hardcodes only the allowed pages, with there exact filenames. By doing this, it removes all avenues of attack.
開發人員只對允許的頁面進行硬編碼,並提供精確的檔名,這樣做消除了所有的攻擊途徑。

<?php

// The page we wish to display
$file = $_GET[ 'page' ];

// Only allow include.php or file{1..3}.php
if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) {
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit;
}

?>

總結

為了更好地使用程式碼的重用性,可以使用檔案包含函式將檔案包含進來,直接使用檔案中的程式碼來提高重用性。但是這也產生了檔案包含漏洞,產生原因是在通過 PHP 的函式引入檔案時,為了靈活包含檔案會將被包含檔案設定為變數,通過動態變數來引入需要包含的檔案。此時使用者可以對變數的值可控,而伺服器端未對變數值進行合理地校驗或者校驗被繞過,就會導致檔案包含漏洞。常用的檔案包含函式有 include()、include_once()、require()、require_once()。
包含漏洞分為本地包含和原創包含 2 類,當包含的檔案在伺服器本地時,就形成了本地檔案包含。檔案包含可以包含任意檔案,被包含的檔案可以不是 PHP 程式碼,可以是文字或圖片等。只要檔案被包含就會被伺服器指令碼語言執行,如果包含的檔案內容不符合 php 語法,會直接將檔案內容輸出。例如下面這段簡易的程式碼:

<?php
    $file = $_GET['file'];
    include($file);
?>

當包含的檔案在遠端伺服器上時,就形成了遠端檔案包含。所包含遠端伺服器的檔案字尾不能與目標伺服器語言相同,遠端檔案包含需要在 php.ini 中設定:

allow_url_include = on(是否允許 include/require 遠端檔案)
allow_url_fopen = on(是否允許開啟遠端檔案)

參考資料

新手指南:DVWA-1.9全級別教程之File Inclusion
CTF-WEB:PHP 偽協議