__destruct()方法被调用时,日志文件被删除。
代码大致如下:
logfile.php
<?php
class LogClass {
public $logfilename = "";
public function logdata($text) {
echo "log data".$text."<br/>";
file_put_contents($this->logfilename,$text,FILE_APPEBD);
}
public function __destruct() {
echo 'deletes'.$this->logfilename;
unlink(dirname(__FILE__).'/'.$this->logfilename);
}
}
?>
在其他类中使用LogClass
logLogin.php
<?php
include "index.php";
$obj = new LogClass();
$obj->logfilename = "login.log";
$obj->logdata('记录日志');
?>
上面的这段代码就是一个正常的使用LogClass类来完成日志记录的功能。
下面显示的是存在对象注入漏洞的使用例子。
news.php
<?php
include "logfile.php";
// some codes the use the LogClass
class User {
public $age = 0;
public $name = '';
public function print_data() {
echo "User".$this->name."is".$this->age."years old.<br/>";
}
}
// 从用户接受输入发序列化为User对象
$usr = unserialize($_GET["user"]);
?>
上面显示的代码使用了LogClass对象同时还会从用户那里接受输入进行发序列化转化为一个User对象。
当我们提交如下的数据
news.php?user=O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John”;}
这样的语句是可以正常使用的,也是程序员希望使用的方法。
但是如果提交的数据为:
news.php?user=O:8:"LogClass":1:{s:11:"logfilename";s:9:".htaccess";}
那么最后就会输出delete .htaccess。
可以看到通过构造的数据,导致执行了LogClass中的__destruct()方法然后删除了网站中重要的配置文件。
从上面这个例子也可以看出来,如果没有严格控制用户的输入同时对用户的输入进行了反序列化的操作,那么就有可能会实现代码执行的漏洞。
注入点
PHP对象注入一般在处在程序的逻辑上面。例如一个User类定义了__toString()用来进行格式化输出,但是也存在File类定义了__toString()方法读取文件内容然后进行显示,那么攻击者就有可能通过User类的反序列化构造一个File类来读取网站的配置文件。
user.php
<?php
class FileClass {
public $filename = "error.log";
public function __toString() {
echo "filename发生了变化==>" . $this->filename ;
return @file_get_contents($this->filename);
}
}
class UserClass {
public $age = 0;
public $name = '';
public function __toString() {
return 'User '.$this->name." is ".$this->age.' years old. <br/>';
}
}
$obj = unserialize($_GET['usr']);
echo $obj; //调用obj的__toString()方法
?>







