ctf中的一道反序列化題
阿新 • • 發佈:2018-11-26
早就想寫了,今天剛好遇到一道反序列化的題就記錄一下
自己在本地搭的,原始碼如下:
index1.php
<?php error_reporting(E_ALL & ~E_NOTICE); $user = $_GET["user"]; $file = $_GET["file"]; $pass = $_GET["pass"]; if(isset($user)&&(file_get_contents($user,'r')==="admin")){ echo "hello admin!<br>"; if(preg_match("/f1a9/",$file)){ exit(); }else{ include($file); //class.php $pass = unserialize($pass); echo $pass; } }else{ echo "you are not admin ! "; } ?> <!-- $user = $_GET["user"]; $file = $_GET["file"]; $pass = $_GET["pass"]; if(isset($user)&&(file_get_contents($user,'r')==="admin")){ echo "hello admin!<br>"; include($file); //class.php }else{ echo "you are not admin ! "; } -->
class.php
<?php
error_reporting(E_ALL & ~E_NOTICE);
class Read{//f1a9.php
public $file;
public function __toString(){
if(isset($this->file)){
echo file_get_contents($this->file);
}
return "__toString was called!";
}
}
?>
f1a9.php
<?php
error_reporting(E_ALL & ~E_NOTICE);
//flag{hSh_ctf:[email protected]}
?>
本地測試
訪問首頁,檢視原始碼
根據以上原始碼洩露,是檔案包含漏洞,配合封裝協議讀取檔案原始碼
包含了class.php檔案,該怎麼讀它的原始碼內容呢
這裡得講到file_get_contents()函式
file_get_contents() 函式把整個檔案讀入一個字串中。
這裡的字串是$user引數接受的,利用它的檔案封裝協議來讀取$file引數include的檔案
當然這裡要使第一個條件成立。還需要講到一個檔案封裝協議
php://input 是個可以訪問請求的原始資料的只讀流
第一個條件:
if(isset($user)&&(file_get_contents($user,'r')==="admin"))
使$user的值等於admin,並且使$user接收讀入的檔案
可利用php://input繞過
成功繞過
現在利用php偽協議讀取class.php原始碼,格式為base64加密
解密後
可以直接讀取flag檔案嗎? 答案是不能
但是class.php把我們引入到另一個地方,就是利用反序列化來讀取flag檔案
於是我們構造反序列化的引數:
O:4:"Read":1:{s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=f1a9.php";}
這裡也是利用php://filter來讀取flag檔案
上面的就是f1a9.php的內容,格式base64加密,解密即可