php - PHP反序列化和重复的变量名
问题描述
最近,我偶然发现了对旧版本 CMS Contao 中 PHP 对象注入漏洞的描述(它是用德语编写的,但我将翻译关键部分)。
作者在那里说,他没有设法让 Null-Bytes 进入反序列化函数(它们被过滤掉了),因此他无法直接写入类的受保护或私有成员。
然后他说这不是问题,因为unserialize() 函数不会关心类的序列化版本是否具有在真实类中实际受保护的公共成员,因此他可以删除前导的 Null-Bytes 和星号并更正变量名称字符串的长度(只是在序列化版本中公开变量)以使攻击起作用(因此写入易受攻击类的受保护成员)。
然后我尝试编写自己的这种行为的 PoC,但失败了。首先,我创建了一个名为“Test”的小测试类,它具有受保护的成员“value”和一个打印该值的析构函数:
class Test {
protected $value = "Default";
public function __destruct() {
echo $this->value . "<br>";
}
}
现在我正在尝试更改受保护的“值”成员的值。使用 Null-Bytes 和 Star,一切正常:
$obj = unserialize("O:4:\"Test\":1:{s:8:\"\0*\0value\";s:8:\"Injected\";}");
echo serialize($obj);
给我:
O:4:"Test":1:{s:8:"*value";s:8:"Injected";}
注入
现在我尝试省略 Null-Bytes 和星号,所以我假装“值”将是一个公共变量:
$obj2 = unserialize("O:4:\"Test\":1:{s:5:\"value\";s:8:\"Injected\";}"); // I pretended that 'value' would be a public variable
echo serialize($obj2);
这给了我:
O:4:"Test":2:{s:8:"*value";s:7:"Default";s:5:"value";s:8:"Injected";}
默认
如果您查看该类的序列化版本,似乎 PHP-Object 有两个名称相同但可见性不同的成员。析构函数打印出受保护的成员,因此注入不起作用。
现在我想知道在这种情况下我是否遗漏了一些东西,或者为什么这似乎对文章的作者有用。我将非常感谢您的帮助!
解决方案
推荐阅读
- mongodb - Spring Boot MongoRepository 未正确映射聚合
- javascript - 如何在包含相同子项和类名的各个 div 上应用单击事件
- python - 使用数据转换器将 3D 体积显示为图像
- image - 将 png 图像从文件动态加载到 Tpanel 上的 Timage 中,然后调整大小/缩放/平移它的适当方法是什么?
- python - 使用 Python 套接字发送连接的固定长度值
- jquery - 使用ajax将它们作为json后如何循环遍历django表单错误
- javascript - 如何根据 Javascript 中的按钮单击向表格添加信息?
- python - 如何对齐两个 numpy 直方图,使它们共享相同的 bin/index,并将直方图频率转换为概率?
- javascript - Mapbox Leaflet 缩放无法从中心进行
- python - 当 Jupyter 内核突然死机时,我可以恢复 Python 对象吗?