今天要講的內容是一個在 PHP 中很重要的功能
因為不論是要存取檔案
還是遠端請求網頁的內容
都離不開這項元件
那就是 "協議流"
在官方的說明文件中
一共提供了以下幾種
今天會講幾個重要且常用的協議
也因為這些協議的使用不當
造成了 LFI (Local File Include), RFI(Remote File Include)
甚至最後有可能造成 RCE (Remote Code Excution) 導致整台主機淪陷
那在使用這些協議時有兩個重要的設定要注意
接下來介紹的協議都會與這兩項相關
這也是預設在讀取本地檔案時所用的協議
只是通常在函數中的實作會有些許不同
而在這個協議最原始的用法中
只能使用絕對路徑來存取
file://<path>
include($_GET['path']);
舉個例子來說path
這個變數沒有經過任何過濾就被放進讀取
這樣我們就可以存取任意一個你知道路徑的檔案
這是非常危險的一件事 稱為 LFI
因為一些本來應該只能夠看到網頁跟目錄底下的檔案
如今可以透過這個方式存取到其他位置
等於你的主機重要資訊會被看光光
而 linux 底下有個大家都可以看的檔案 /etc/passwd
但不存在網頁根目錄底下
這通常會被用來檢查是否存在 LFI
因此會寫成 ?path=file:///etc/passwd
要注意 file
後面有三個 /
其中前兩個是 file 協議本身的
第三個是絕對路徑的
allow_url_include
php://filter/read=/resource=/
其中 read 這個參數又有許多編碼方式可以選擇
這個協議通常被攻擊者利用在要取得 PHP 原始碼時會使用的
因為 PHP 語法會被 web server 解析至前端時隱藏起來
剛好這個協議的編碼特性
可以將讀取到的原始碼經過編碼後輸出從而繞過
例如有一份檔案 index.php
<?php
echo 'Hello';
?>
我們可以使用 php://read=convert.base64-encode/resource=index.php
而將原始碼輸出成 PD9waHAKZWNobyAnSGVsbG8nOwo/Pg==
只要將這串字串進行 base64 解碼後
我們就得到原始碼了