<?php
class index {
private $test;
public function __construct()
{
$this->test = new normal();
}
public function __destruct()
{
$this->test->action();
}
}
class normal {
public function action(){
echo "please attack me";
}
}
class evil {
var $test2;
public function action(){
eval($this->test2);
}
}
unserialize($_GET['test']);
这段代码包含了一个 PHP 的反序列化漏洞,可能会导致代码执行漏洞。让我们逐步解析每部分代码,帮助你理解其中的关键概念和潜在风险。
代码结构解析
1. index
类
class index {
private $test;
public function __construct()
{
$this->test = new normal();
}
public function __destruct()
{
$this->test->action();
}
}
- 属性: 该类有一个私有属性
$test
,它会在构造函数中被初始化为normal
类的实例。 - 构造函数: 当
index
类的实例被创建时,$test
被设置为normal
类的对象。 - 析构函数: 当
index
类的实例被销毁时,$test->action()
被调用。由于$test
是normal
类的对象,所以会调用normal
类的action()
方法。
2. normal
类
class normal {
public function action(){
echo "please attack me";
}
}
- 这个类有一个
action()
方法,它只会输出字符串"please attack me"
。
3. evil
类
class evil {
var $test2;
public function action(){
eval($this->test2);
}
}
- 属性: 该类有一个公开的属性
$test2
,它可以存储任意数据。 - 方法:
action()
方法会调用eval()
函数。eval()
函数执行其参数作为 PHP 代码,因此如果$test2
包含 PHP 代码,它将被执行。
漏洞分析
unserialize($_GET['test']);
unserialize()
: 这个函数用于将序列化的字符串转换回 PHP 对象。它会根据序列化的数据重建对象及其属性。
潜在风险
由于 unserialize()
允许通过序列化数据创建对象,如果攻击者能够控制传递给 unserialize()
的数据,他们可以创建 evil
类的实例,并设置其属性 $test2
。然后,在反序列化过程中,如果创建了 index
类的实例并调用析构函数,会触发 evil
类的 action()
方法,执行 $test2
中的任意 PHP 代码。
攻击过程示例
-
构造恶意数据:
$evilPayload = serialize(array( 'test' => new evil() ));
在这个例子中,我们创建了一个
evil
类的实例,并将其放入序列化的数据中。 -
设置
$test2
:$evilObject = new evil(); $evilObject->test2 = 'echo "This is a test";'; // 可以是任何 PHP 代码 $evilPayload = serialize(array( 'test' => $evilObject ));
-
利用漏洞:
将evilPayload
传递给 URL 中的test
参数,例如:http://example.com/script.php?test=O:4:"evil":1:{s:4:"test2";s:22:"echo 'This is a test';";}
这会导致
unserialize()
创建一个evil
对象,并在index
对象的析构时执行echo 'This is a test';
。
解决方案
- 禁用
unserialize()
: 如果不需要反序列化,最好禁用该功能。 - 使用
allowed_classes
: PHP 5.6 及更高版本支持unserialize()
的allowed_classes
选项,可以限制反序列化的类。unserialize($_GET['test'], ['allowed_classes' => ['index']]);
- 安全库: 使用经过验证的库进行对象序列化和反序列化,避免直接使用
unserialize()
。
了解这些概念可以帮助你更好地理解 PHP 反序列化的风险,并采取相应的安全措施。
标签:test2,demo,unserialize,action,PHP,test,序列化 From: https://www.cnblogs.com/o-O-oO/p/18357284